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循环执行即可。

`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仿真结果

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

读端口的波形:

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

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小勇study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值