在 Verilog 中推断单端口 RAM

Inferring a single port RAM in Verilog

我正在尝试制作一个 32x4(32 字,4 位)单端口 RAM 块。这是我的 Verilog 代码:

module RAM_array (input clk, wren, input [4:0] address,
                        input [3:0] data, output reg [3:0] q);

    reg [3:0] mem [31:0]; // a 4 bit wide 32 word RAM block.

    always @(posedge clk) begin
            if (wren)
                mem[address] <= data;
            q <= mem[address];
    end
endmodule

因为我在 DE-1-SoC 上使用 Altera 的 Cyclone V 芯片,所以我的代码基于他们的指南:http://quartushelp.altera.com/14.1/mergedProjects/hdl/vlog/vlog_pro_ram_inferred.htm

问题:每当我将值写入块中的地址时,我都必须等待一个额外的时钟周期才能将其写入。为什么会这样?

我猜你在写入后尝试读取一个时钟周期时看到了 "extra clock cycle",但仍然得到旧值。 发生这种情况是因为您在写入内存 和驱动输出 q 时使用了非阻塞分配。 因此,写入内存需要一个时钟周期,读取内存需要一个时钟周期。总共是两个周期。

如果要减少内存延迟,请使用并发语句和 "assign" 输出 q。 这将实现从 mem 到输出 q:

的简单连线
module RAM_array (input clk, wren, input [4:0] address,
                    input [3:0] data, output [3:0] q);

    reg [3:0] mem [31:0]; // a 4 bit wide 32 word RAM block.

    always @(posedge clk) 
            if (wren)
                mem[address] <= data;

    assign q = mem[address];

endmodule

合成器应选择使用 FF 而不是 SRAM 块来实现此代码(这正是 FF 的行为 --> 零周期读取延迟,1 周期写入延迟)。 这没关系,应该不会影响您的合成,因为它是一个非常小的阵列。