其他分享
首页 > 其他分享> > RAM的交替读写

RAM的交替读写

作者:互联网


一、认识RAM
RAM的分类比较多,单口RAM,双口RAM等等,详细的不再介绍。这里使用的是simple dual port RAM。本次实验的内容是RAM的交替读写,RAM的读写位宽和深度都设置为256x8来完成这部分的内容。

二、 调用RAM ip并按照上述要求进行设置
设置过程如下几个图:





在summary界面中划红线部分可得知,RAM读端口读出的数据会延迟一个时钟周期,相比于地地址而言。

三、设计思路
内部产生一个写使能信号,当写使能信号为高时向RAM中写入数据,写端口的地址开始叠加,当写完数据之后把写使能信号拉低,此时开启RAM的读端口,读地址开始叠加,当读完数据后在写使能信号拉高,开始写入数据,如此往复循环。

绘制波形如下:

四、rtl代码的完成
如下:内部添加的wr_en其实就是RAM的wea信号,wr_addr和rd_addr是对RAM读写端口地址的控制,RAM输出的数据最终连接到端口信号po_data。

代码
`timescale 1ns / 1ps

module ctrl_ram(

input 		wire 			clk,
input 		wire 			rst_n,
input 		wire 	[7:0]	pi_data,
output 		wire 	[7:0]	po_data
    );

reg 				wr_en;
reg 		[7:0]	wr_addr;
reg 		[7:0]	rd_addr;

always @(posedge clk or negedge rst_n)begin
	if (rst_n == 1'b0) begin
		wr_en <= 1'b1;
	end
	else if (wr_addr == 'd255) begin
		wr_en <= 1'b0;
	end
	else if (rd_addr == 'd255) begin
		wr_en <= 1'b1;
	end
end      			

always @(posedge clk or negedge rst_n)begin
	if (rst_n == 1'b0) begin
		wr_addr <= 'd0;
	end
	else if (wr_en == 1'b1 && wr_addr == 'd255) begin
		wr_addr <= 'd0;
	end
	else if (wr_en == 1'b1) begin
		wr_addr <= wr_addr + 1'b1;
	end
end   

always @(posedge clk or negedge rst_n)begin
	if (rst_n == 1'b0) begin
		rd_addr <= 'd0;
	end
	else if (wr_en == 1'b0 && rd_addr == 'd255) begin
		rd_addr <= 'd0;
	end
	else if (wr_en == 1'b0) begin
		rd_addr <= rd_addr + 1'b1;
	end
end  

ram256x8 inst_ram256x8 (
  .clka(clk),    // input wire clka
  .wea(wr_en),      // input wire [0 : 0] wea
  .addra(wr_addr),  // input wire [7 : 0] addra
  .dina(pi_data),    // input wire [7 : 0] dina
  .clkb(clk),    // input wire clkb
  .addrb(rd_addr),  // input wire [7 : 0] addrb
  .doutb(po_data)  // output wire [7 : 0] doutb
);

endmodule

5.写tb并完成仿真 tb如下:这里gen_data仅产生了一次数据256x8的数据,所以仿真的时候读写数据仅完成一次交替。如果想多次交替,可以在写一个for循环,让产生数据的task循环执行即可。 <summarytb代码< summary="">
`timescale 1ns / 1ns

module tb_ctrl_ram();

reg 		clk;
reg 		rst_n;
reg  [7:0]	data;
wire [7:0]	po_data;

initial begin
	rst_n = 0;
	clk   = 0;
	data  = 'd0;
	#55;
	rst_n = 1;
end

always #10 clk = ~clk;

initial begin
	gen_data();
end

task gen_data;
	integer i;
	begin
		@(posedge rst_n);
//		repeat (50)@(posedge clk);
		for(i=0;i<256;i=i+1)begin
			data = i;
			@(posedge clk);
		end
		data = 0;
	end
endtask

ctrl_ram inst_ctrl_ram (
	.clk(clk),
	.rst_n(rst_n), 
	.pi_data(data),
	.po_data(po_data));

endmodule

5.2仿真结果
​​

放大后对比一下写入的数据和读出的数据是否一致即可,这里就不在贴图了。

读端口的波形

你会发现读出的数据相对读端口的地址而言,延迟了一个时钟周期。

标签:clk,数据,读写,RAM,交替,rst,data,reg
来源: https://www.cnblogs.com/xiaoyongstudy/p/16351138.html