仿真测试文件如下,可以直接使用
`timescale 1ns / 1ps
module pingpang();
parameter data_depth=4096;//fft的点数
parameter buffer_size=12;
parameter data_width=12;//fft的输出数据位宽,实际数据的宽度为27
reg clk;
reg rst_n;
reg signed [data_width-1:0] data_in;
reg signed [buffer_size-1:0] data_out;
reg [buffer_size-1:0] buffer1[data_depth-1:0];//缓存地址1
reg [buffer_size-1:0] buffer2[data_depth-1:0];//缓存地址2
reg wr_flag;//写标志, wr_flag = 0,写buffer1,wr_flag = 1,写buffer2
reg rd_flag;//读标志, rd_flag = 0,读buffer1,rd_flag = 1,读buffer2
reg[data_width-1:0] wr1_cnt;
reg[data_width-1:0] rd1_cnt;
reg[data_width-1:0] wr2_cnt;
reg[data_width-1:0] rd2_cnt;
initial begin
clk=1;
rst_n=1;
data_in=0;
#5 rst_n=0;
#5 rst_n=1;
end
always#5 clk=~clk;
always#10 data_in<=$random%4095;
//写指令
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
wr_flag<=1'b0;
end
else if(wr1_cnt==12'd4095)begin
wr_flag<=1'b1;
end
else if(wr2_cnt==12'd4095)begin
wr_flag<=1'b0;
end
else begin
wr_flag<=wr_flag;
end
end
//写计数
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
wr1_cnt<=24'd0;
wr2_cnt<=24'd0;
end
else if(!wr_flag)begin
wr1_cnt<=wr1_cnt+24'd1;
wr2_cnt<=24'd0;
end
else begin
wr2_cnt<=wr2_cnt+24'd1;
wr1_cnt<=24'd0;
end
end
//读指令
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
rd_flag<=1'bz;
end
else if(wr1_cnt==12'd2047)begin
rd_flag<=1'b0;
end
else if(wr2_cnt==12'd2047)begin
rd_flag<=1'b1;
end
else begin
rd_flag<=rd_flag;
end
end
//读计数
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
rd1_cnt<=24'd0;
rd2_cnt<=24'd0;
end
else if(!rd_flag)begin
rd1_cnt<=rd1_cnt+24'd1;
rd2_cnt<=24'd0;
end
else begin
rd2_cnt<=rd2_cnt+24'd1;
rd1_cnt<=24'd0;
end
end
integer i=0;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
for(i=0;i<12'd4095;i=i+1)begin
buffer1[i]<=12'd0;
buffer2[i]<=12'd0;
end
end
else begin
case(wr_flag)
1'b0:buffer1[wr1_cnt]<=data_in; //wr_flag = 0 ,写buffer1
1'b1:buffer2[wr2_cnt]<=data_in; //wr_flag = 1 ,写buffer2
default:begin
buffer1[wr1_cnt]<=buffer1[wr1_cnt];
buffer1[wr2_cnt]<=buffer1[wr2_cnt];
end
endcase
end
end
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_out<=12'd0;
end
else begin
case(rd_flag)
1'b0:data_out<=buffer1[rd1_cnt]; //rd_flag = 0,读buffer1
1'b1:data_out<=buffer2[rd2_cnt]; //rd_flag = 1,读buffer2
default:data_out<=12'd0;
endcase
end
end
endmodule
测试效果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/3a344aec43f7051da6472c284012ba06.png)