调用RAM IP核完成乒乓操作1
作者:互联网
一、 乒乓操作
两个RAM交替读写,简称为RAM的乒乓操作。
二、乒乓操作练习
1、两个异步双口RAMA和RAMB,读写位宽皆为8bit,时钟皆为50mhz,深度皆为1024;
2、当 RAMA 被写入 1024 字节时,给读时序提供一个启动信号读取 RAMA 的数据,读取完 RAMA 的 1024 字节数据时,切换读 RAMB 以此类推。
3、写入 RAMA 和 B 的数据是 0~255 递增的数据。
三、画波形
四、根据波形写代码
module ctrl_ram(
input wire clk,
input wire rst_n,
input wire [7:0] pi_data,
output wire [7:0] po_data
);
reg wra_en;
reg [9:0] wra_addr;
reg [9:0] rda_addr;
wire [7:0] rda_data;
reg wrb_en;
reg [9:0] wrb_addr;
reg [9:0] rdb_addr;
wire [7:0] rdb_data;
reg wra_en_r;
//RAMA的读写端口
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
wra_en <= 1'b1;
end
else if (wra_addr == 'd1023) begin
wra_en <= 1'b0;
end
else if(rda_addr == 'd1023) begin
wra_en <= 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
wra_addr <= 'd0;
end
else if (wra_en == 1'b1 && wra_addr == 'd1023) begin
wra_addr <= 'd0;
end
else if (wra_en == 1'b1) begin
wra_addr <= wra_addr + 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
rda_addr <= 'd0;
end
else if (wra_en == 1'b0 && rda_addr == 'd1023) begin
rda_addr <= 'd0;
end
else if (wra_en == 1'b0) begin
rda_addr <= rda_addr + 1'b1;
end
end
//RAMB的读写端口
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
wrb_en <= 1'b0;
end
else if (wrb_addr == 'd1023) begin
wrb_en <= 1'b0;
end
else if(rdb_addr == 'd1023) begin
wrb_en <= 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
wrb_addr <= 'd0;
end
else if (wrb_en == 1'b1 && wrb_addr == 'd1023) begin
wrb_addr <= 'd0;
end
else if (wrb_en == 1'b1) begin
wrb_addr <= wrb_addr + 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
rdb_addr <= 'd0;
end
else if (wrb_en == 1'b0 && rdb_addr == 'd1023) begin
rdb_addr <= 'd0;
end
else if (wrb_en == 1'b0) begin
rdb_addr <= rdb_addr + 1'b1;
end
end
always @(posedge clk) begin
wra_en_r <= wra_en;
end
//rama
ram256x8 ram256x8a_inst (
.clka(clk), // input clka
.wea(wra_en), // input [0 : 0] wea
.addra(wra_addr), // input [9 : 0] addra
.dina(pi_data), // input [7 : 0] dina
.clkb(clk), // input clkb
.addrb(rda_addr), // input [9 : 0] addrb
.doutb(rda_data) // output [7 : 0] doutb
);
//ramb
ram256x8 ram256x8b_inst (
.clka(clk), // input clka
.wea(wrb_en), // input [0 : 0] wea
.addra(wrb_addr), // input [9 : 0] addra
.dina(pi_data), // input [7 : 0] dina
.clkb(clk), // input clkb
.addrb(rdb_addr), // input [9 : 0] addrb
.doutb(rdb_data) // output [7 : 0] doutb
);
assign po_data = (wra_en_r==1'b0)?rda_data:rdb_data;
endmodule
tb中通过task来产生写入的数据,如下;
task gen_data;
integer i;
begin
for(i=0;i<8192;i=i+1)begin
@(posedge clk);
pi_data = i[7:0];
end
end
endtask
四、modelsim仿真
仿真结果如下:
第一张仿真结果图可以看到RAMB中写端口:地址0写入的数据是255,地址1中写入的数据是0,地址2中的数据是1
第二种仿真图中可以观察到,地址012读出的数据和写入的是相同的。
注意:RAM读端口读出的数据相对于读地址而言会延迟一个时钟
参考V3学院
标签:wire,乒乓,IP,RAM,写入,reg,wra,data,RAMA 来源: https://www.cnblogs.com/xiaoyongstudy/p/16351071.html