首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Xilinx: BRAM读物

Xilinx: BRAM读物
EN

Stack Overflow用户
提问于 2016-04-06 16:34:15
回答 1查看 7.1K关注 0票数 0

我打算在下面写一个最小的、完整的和可验证的例子。

我想将10个值写入BRAM (单端口块RAM)的前10个地址,然后读取这些值。在检查结果后,我发现

  • 在完成写操作时,前10个地址没有变化。
  • 读取时,输出在3个时钟周期后发生变化,并在“地址”信号停止变化时保持不变。

您能解释一下这种行为以及如何获得所需的结果(在10个地址中写10个值)吗?我更感兴趣的是解决第二个问题(阅读前10个地址的值)。

下面是我的verilog测试平台和波导的快照。

代码语言:javascript
复制
module BRAM_tb;
    // Inputs
    reg clk;
    reg [3:0] wea;                  // write enable signal
    reg [31:0] addra;               // address
    reg signed [31:0] dina;     // data in

    // Outputs
    wire [31:0] douta;          // data out

    // Instantiate the Unit Under Test (UUT)
    BLOCK_MEM uut (
        .clka(clk), 
        .wea(wea), 
        .addra(addra), 
        .dina(dina), 
        .douta(douta)
    );

    always begin
        #15 clk =~clk;
    end

    task writeStuff;    //write to address
        begin
            addra <= addra + 1;
            dina <= dina+1;
        end
    endtask

    task readStuff; // read the at address
        begin
            addra <= addra + 1;
        end
    endtask

    reg [1:0] writing;
    integer counter;
    initial begin
        // Initialize Inputs
        clk = 0;
        addra = 0;
        dina = 16;
        counter = 0;
        writing = 2'b10; //idle state
        // Wait 100 ns for global reset to finish
        #100;
        wea <= 1;
        writing <=1;
    end

    always @(posedge clk)begin
        case(writing)
            1: if(counter<10) begin
                    writeStuff;
                    counter <=counter+1;
                end else begin
                    writing <=0;    // change state to reading
                    counter <=0;
                    addra <= 0;
                    wea <=0;    // stop writing
                end
            0:  if(counter<10) begin
                    readStuff;
                    counter <=counter+1;
                end else begin // change addra to zero and do nothing
                    addra <= 0;
                    writing <=2'b10; //goto idle state
                end
            2: if(1) begin
                    //do nothing
                end
        endcase
    end

  • 灰色线是写操作开始的地方。蓝线是开始读取操作的地方。

内存是由Xilinx生成的IP核.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-07 14:48:11

我将猜测一下您是如何配置BRAM的(我使用Vivado 2015.4和3/pg058 058-blk-mem-gen.pdf作为参考)。看来您已经选择了始终启用(因为ENA信号不存在)、32位数据和32位地址接口。请注意,如果使用32位地址接口,WEA将从1位信号更改为4位信号。这是为了允许字节可寻址写入。

考虑到这一点,我们知道对于wea of 0b0001,只有最不重要的字节会被写入。此外,从上述指南第46页的时序图中,我们知道我们可以期望在douta上写完之后可以获得书面数据。我们可以在第一个映像上验证这一点--例如,在200 was的douta = 0xfff75c13上,0x13字节来自位于前一个时钟边缘的dina (其他字节是以前内存中的字节)。因此,这证实了写操作与预期的相同。

至于图像2中的读取,如果再次计数,您将看到douta改变了每个4时钟周期。同样,请记住内存是按字节寻址的,但是要返回4个字节,因此忽略了地址中最低的两位(address 0x07 == 0x06 == 0x05 == 0x04)。

简而言之,BRAM正在按预期工作,这可能不是您所期望的方式。要移动到内存中的下一个32位/4字节字,您需要将地址增加4,而不是1。要写入整个单词,(而不仅仅是最低字节)设置wea='b1111

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36457120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档