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?
答案 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个周期写入延迟)。 这是好的,不应该影响你的合成,因为它是一个非常小的数组。