欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SDRAM控制器设计(6)不带自动预充电的读操作时序

程序员文章站 2022-04-01 22:57:30
...

1.时序解读

不带自动预充电读操作时序,从时序中可以看出,主要包含**命名,读命令和预充电命令,与写操作类似,不同的是,读操作不需要给待写入的数据,有数据的读出,时序很明确,这里同样采用线性序列机方法实现读操作任务,步骤基本与写操作差不多
SDRAM控制器设计(6)不带自动预充电的读操作时序
在选定列地址后,就已经确定了具体的存储单元,剩下的事情就是数据通过数据I/O通道输出到内存总线上了。但是在CAS发出之后,仍要经过一定的时间才能有数据输出,从CAS与读命令发出到第一笔数据输出的这段时间,被定义为CL(CAS Latency,CAS潜伏期)。由于CL只在读取时出现,所以CL又被称为读潜伏期。CL的单位与tRCD一样,为时钟周期数,具体耗时有时钟频率决定。

不过,CAS并不是在经过CL周期之后才送达存储单元。实际上CAS和RAS一样是瞬间到达的,但CAS的响应时间要更快一些。为什么呢?假设芯片的位宽为n个bit,列数为c,那么一个行地址要选通n*c个存储体,而一个列地址只需选通n个存储体。但存储体中晶体管的反映时间仍会造成数据不可能与CAS在同一上升沿触发,肯定要延后至少一个时钟周期

由于芯片体积的原因,存储单元中的电容容量很小,所以信号要经过放大来保证其有效的识别性,这个放大/驱动工作由S-AMP负责,一个存储体对应一个S-AMP通道。但它要有一个准备时间才能保证信号的发送强度,因此从数据I/O总线上有数据输出之前的一个时钟上升沿开始,数据即已传向S-AMP,也就是说此时数据已经被触发,经过一定的驱动时间最终传向数据I/O总线进行输出,这段时间我们称之为tAC(Access Time from CLK,时钟触发后的访问时间)。tAC的单位是ns,对于不同的频率各有不同的明确规定,但必须要小于一个时钟周期,否则会因访问时间过长而使效率降低。需要强调的是,每个数据在读取时都有tAC,包括在连续读取中,只是在进行第一个数据传输的同时就开始了第二个数据的tAC。如图

CL的数值不能超过芯片的设计规范,否则会导致内存的不稳定,设置无法开机,而且它也不能在数据读取前临时更改。CL周期在开机初始化过长中的MRS阶段进行设置。

2.参数设置

//一次突发读操作任务,线性序列机方法
localparam  rd_ACT_TIME = 1'b1,
			rd_READ_TIME = SC_RCD+1,
			rd_PRE_TIME = SC_RCD+SC_CL+SC_BL+1,
			rd_END_TIME = SC_RCD+SC_CL+SC_BL;

3.计数器

//一次突发读操作过程时间计数器
aaa@qq.com(posedge Clk or negedge Rst_n)
begin
if(!Rst_n)
rd_cnt <= 16'd0;
else if(rd_cnt == rd_END_TIME)
rd_cnt <= 16'd0;
else if(rd_req ||rd_cnt>1'b0)
rd_cnt <= rd_cnt + 16'd1;
else
rd_cnt <= 16'd0;
end

4. 线性序列机

//一次突发读操作任务,类似线性序列机方法
task read_data;
begin
case(rd_cnt)
rd_ACT_TIME:begin //**命令
Command <= C_ACT;
Sa <= raddr_r;
Ba <= baddr_r;
end
rd_READ_TIME:begin //读命令
Command <= C_RD;
Sa <= {1'b0,caddr_r[8:0]};
Ba <= baddr_r;
end
rd_PRE_TIME:begin
Command <= C_PRE; //预充电
Sa[10] <= 1'b1;
end
rd_END_TIME:begin
FF <= 1'b1;
Command <= C_NOP;
end
default:
Command <= C_NOP;
endcase
end
endtask

5. 各种标志位生成

//一次突发读操作过程完成标志位
aaa@qq.com(posedge Clk or negedge Rst_n)
begin
if(!Rst_n)
rd_opt_done <= 1'b0;
else if(rd_cnt == rd_END_TIME)
rd_opt_done <= 1'b1;
else
rd_opt_done <= 1'b0;
end
//一次突发读操作过程状态标识信号
reg rd_opt;
aaa@qq.com(posedge Clk or negedge Rst_n)
begin
if(!Rst_n)
rd_opt <= 1'b0;
else if(rd_req == 1'b1)
rd_opt <= 1'b1;
else if(rd_opt_done == 1'b1)
rd_opt <= 1'b0;
else
rd_opt <= rd_opt;
end
//一次突发读操作过程中数据读完标志位
assign Rdata_done = (rd_cnt == rd_END_TIME)?1'b1:1'b0;
//读数据操作,数据有效区
aaa@qq.com(posedge Clk or negedge Rst_n)
begin
if(!Rst_n)
Rd_data_vaild <= 1'b0;
else if((rd_cnt > SC_RCD+SC_CL)
&&(rd_cnt <= SC_RCD+SC_CL+SC_BL))
Rd_data_vaild <= 1'b1;
else
Rd_data_vaild <= 1'b0;
end
//读数据
assign Rd_data = Dq;