其他分享
首页 > 其他分享> > 调用RAM IP核完成乒乓操作1

调用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