基于FPGA的双口RAM读写操作(连续读写)
最近在使用双口RAM作为数据流的缓存,拟采用连续写入,然后连续读出的方式,即每个数据占用1个clock时钟周期。
写入操作:wren,wraddr, datain可同时有效并赋值;
读出操作:1. 当rden使能有效后一个周期,数据才输出(注意点);
2. 读操作地址在rden使能有效后,需要不断自加递增;
读操作如果满足上述两点后,读出数据应该就是正确的;
读操作行为和数据后续输出行为可以分2段编写,也可以一段编写,本文采用一段式,同时对两个相同的DPRAM进行操作,代码参见下文。
always@(posedge clk_in)
if(rst) begin
rdstate <= 0;
rden_row <= 0;
rden_xrm <= 0;
addrb_row <= 0;
addrb_xrm <= 0;
rdover <= 0;
XrmRowEn <= 0;
RowInt <= 0;
RowFlo <= 0;
XrmInt <= 0;
XrmFlo <= 0;
rddatacnt <= 0;
end
else begin
case(rdstate)
4'd0: begin
rdover <= 0;
addrb_row <= 0;
addrb_xrm <= 0;
XrmRowEn <= 0;
RowInt <= 0;
RowFlo <= 0;
XrmInt <= 0;
XrmFlo <= 0;
rddatacnt <= 0;
if(wrfull_row && wrfull_xrm) begin
rden_row <= 1;
rden_xrm <= 1;
rdstate <= 1;
end
else begin
rden_row <= 0;
rden_xrm <= 0;
rdstate <= 0;
end
end
4'd1: begin
addrb_row <= addrb_row + 1;
addrb_xrm <= addrb_xrm + 1;
rdstate <= 2;
end
4'd2: begin
addrb_row <= addrb_row + 1;
addrb_xrm <= addrb_xrm + 1;
XrmRowEn <= 1;
RowInt <= dout_row[12:9];
RowFlo <= dout_row[ 8:0];
XrmInt <= dout_xrm[17:9];
XrmFlo <= dout_xrm[ 8:0];
if(rddatacnt == 511) begin
rdover <= 1;
rddatacnt <= 0;
rdstate <= 0;
end
else begin
rdover <= 0;
rddatacnt <= rddatacnt + 1;
rdstate <= 2;
end
end
default: begin
rdstate <= 0;
rden_row <= 0;
rden_xrm <= 0;
addrb_row <= 0;
addrb_xrm <= 0;
rdover <= 0;
XrmRowEn <= 0;
RowInt <= 0;
RowFlo <= 0;
XrmInt <= 0;
XrmFlo <= 0;
end
endcase
end
说明: 代码4'd1和4'd2两段是重点,对应上文写操作的两点描述。