Following shows a single-port RAM in write-first mode.
module raminfr (clk, we, en, addr, di, do);
input clk;
input we;
input en;
input [4:0] addr;
input [3:0] di;
output [3:0] do;
reg [3:0] RAM [31:0];
reg [4:0] read_addr;
always @(posedge clk)
begin
if (en) begin
if (we)
RAM[addr] <= di;
read_addr <= addr;
end
end
assign do = RAM[read_addr];
endmodule
Here, how can we assure that output do
is changed after RAM[addr] <= di;
is executed?
If the logic does write-first mode, data has to be written first and then read has to happen. But, as we know, RAM[addr] <= di;
and read_addr <= addr;
are executed concurrently. However, it seems that we cannot guarantee that output do
is changed after writing.
Why this code works?
Following are my exepctation:
assumption: addr[10] = 5, addr[20] = 15;
previous addr: 10, current addr:10, en: 1, we: 0 => do
= 5
previous addr: 10, current addr:20, en: 1, we: 1, di: 12 =>
do
will be changed because of RAM[read_addr] will be changed as 15. But, how can we assure that do
will be 12 instead of 15 (write-first mode)?
Also, is the reg read_addr
necessary? If it is, why?