前言
在数据处理的一个周期内,为了避免同时对RAM读和写,因此利用乒乓操作将读写分开,在一个周期内仅对一片RAM读,对另一片RAM写,下个周期后再换回来。因此,实际上一片RAM的操作周期是两个数据处理周期。
代码释义
scyc :数据处理周期
exsig :ram切换信号
wsig :ram写信号
rsig : ram读信号
addr1 :ram1读写地址
addr2 :ram2读写地址
dat_i : ram写数据
dat_o :模块输出数据
时序图如下所示,在每个wsig和rsig信号来时,在exsig为高电平时写RAM1、读RAM2,当exsig为低电平时,写RAM2.读RAM1,由此避免了在一个scyc周期内对一片RAM进行读写。
具体实现代码如下:
always@(posedge clk,negedge rst_n)
if(!rst_n) begin
w1clk<=1'b0;
w2clk<=1'b0;
r1clk<=1'b0;
r2clk<=1'b0;
end
else if(exsig==1'b1)
if(wsig)
w1clk<=1'b1;
else if(rsig)
r2clk<=1'b1;
else begin
w1clk<=1'b0;
r2clk<=1'b0;
end
else if(exsig==1'b0)
if(wsig)
w2clk<=1'b1;
else if(rsig)
r1clk<=1'b1;
else begin
w2clk<=1'b0;
r1clk<=1'b0;
end
else begin
w1clk<=1'b0;
w2clk<=1'b0;
r1clk<=1'b0;
r2clk<=1'b0;
end
RAM的读写地址是在每次读信号后发生变化
always@(posedge clk,negedge rst_n)
if(!rst_n) begin
addr1<=5'd0;
addr2<=5'd0;
end
else if(r1clk)
addr1<=addr1+1'b1;
else if(r2clk)
addr2<=addr2+1'b1;
最终结果如下
稍后我会把链接放上来,是quartus 18.1工程文件,包括testbench,也可以把verilog文件添加到自己的工程中去。代码下载地址:
https://download.csdn.net/download/changshengxiao/11785262