Inferring a single port RAM in Verilog

时间:2017-07-12 08:21:28

标签: verilog fpga intel-fpga

I am trying to make a 32x4 (32 words, 4-bit) single port RAM block. Here is my Verilog code:

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

Since I'm using Altera's Cyclone V chip on a DE-1-SoC, I based my code on their guide here: http://quartushelp.altera.com/14.1/mergedProjects/hdl/vlog/vlog_pro_ram_inferred.htm

Question: Whenever I write a value to an address in the block I have to wait an extra clock cycle for it to get written. Why so?

1 个答案:

答案 0 :(得分:1)

我猜你在写完后尝试读取一个时钟周期时会看到“额外的时钟周期”,但仍然会得到旧值。 这是因为您在写入mem,和驱动输出q 时使用非阻塞分配。 因此,需要一个时钟周期来写入mem和一个时钟周期来读取它。总共有两个周期。

如果要减少内存延迟,请使用并发语句并“分配”输出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个周期写入延迟)。 这是好的,不应该影响你的合成,因为它是一个非常小的数组。