为什么RAM在读操作时,需要在前一个时钟的上升沿先读出地址,然后在下一个时钟的上升沿才输出数据呢?(读延时)

RAM(随机访问存储器)读操作需要在两个时钟周期内完成,其中包括在第一个时钟周期内进行地址传递,而在第二个时钟周期内输出数据。这种设计是为了确保在数据线上稳定地输出正确的数据。

  1. 第一个时钟周期 - 地址传递: 在这个时钟周期内,存储器控制器将读取的地址传递给RAM。这通常发生在时钟信号的上升沿。这个过程需要时间,因为地址信号可能需要在存储器内部进行解码,以确定要读取的数据位置。

  2. 第二个时钟周期 - 数据输出: 在下一个时钟周期内,RAM将在时钟信号的上升沿输出所请求地址处的数据。这种设计确保了在数据线上传输的信号在时钟信号的边缘上是稳定的。数据输出需要一定的时间,因为RAM需要从所请求地址读取数据并将其放置在数据线上。

        采用这种分阶段的方式,可以避免时序问题,确保在读取数据时信号的稳定性。这样的设计允许存储器和控制器在时钟周期内进行更精细的同步,确保可靠的数据传输。

示例:

       (前提:地址0存储数据1,地址1存储数据2,地址2存储数据3)在第一个时钟周期末端,拉高读使能;在第二个时钟的上升沿开始触发(也就是在20000ps的位置进行触发),此时读到的地址是0(地址0存储的数据为1);又经过一个时钟周期,在该时钟周期的上升沿把地址0的数据输出,此时输出的是数据为1。以此类推,地址1对应的数据是2,地址2对应的数据是3,均可以由下图表示出来。

tb代码如下 :

`timescale 1ns/1ps
`define clkpd 20

module tb_1();
	reg 	   clk;
	reg 	   rden;
	reg 	   wren;
	reg  [9:0] address;
	wire [7:0] data_out;

RAM u_RAM(
	.address(address),
	.clock  (clk),
	.data   (),
	.rden   (rden),
	.wren   (wren),
	.q      (data_out)
);


initial clk = 1;
always#(`clkpd /2) clk = ~clk;

initial begin
	rden = 1'b0; 
	wren = 1'b0;
   address <= 10'b10;
	#18;
	rden = 1'b1;
	//#1000;
	//repeat(1000)begin		
   address <= 10'd0;
	#20;
   address <= 10'd1;
	#20;
   address <= 10'd2;
	#1000;
	$stop;
end
endmodule

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值