一.理论知识
1.读命令(Read),控制命令为{CS_N,RAS_N,CAS_N,WE_N} = 4’b0101,用来实现对已激活的特定 L-Bank 的特定行的数据突发读取操作, BA[1:0]指定需要读取数据的特定 LBank,地址总线 A0-A9 指定需要读取存储单元的起始列地址, A10 的电平变化控制突发读操作完成后是否立即执行自动预充电操作,若 A10 为高电平,突发读操作完成后,立即执行自动预充电操作,关闭当前行;若 A10 为低电平,突发读操作完成后,当前行依然处于激活状态,以便对当前行执行新的读/写操作,想要关闭当前激活行,需写入预充电指令。读数据有多种模式,这里我们使用不带自动预充电的页突发读模式,激活一次以后,可以连续读取一整页的数据,不过也可以读取小于一整页的数据,当不需要读数据的时候,只需要发送突发中止指令即可。
2.首先是激活特定 L-Bank 的特定行,该操作下13位地址线被用来发送行地址信号,Ba[1:0]表示要激活的Bank。
3.经过tRCD的延迟之后,需要向sdram芯片发送读数据命令。此时13位地址线用来发送列地址信号,但是13位只用到了低9位,高4位全部赋值为0。
4.读数据命令后,要等待2~3个周期的潜伏期,才能接受到sdram输出的数据。这里的潜伏期到底是2个周期还是3个周期,取决于前面初始化阶段的设置。
5.如果要读取N个字节的数据,发送完读数据命令之后的N个周期后发送突发中止指令。突发中止指令不像读数据那样,不需要等待2~3个周期的潜伏期。
6.读数据结束之后,要给芯片发送预充电命令,关闭激活的L-Bank和行。
二.芯片时序分析


三.设计verilog时序图

四.verilog代码
module sdram_read
(
input wire sys_clk,
input wire sys_rst_n,
input wire init_end,
input wire rd_en,
input wire [23:0] rd_addr,
input wire [15:0] rd_data,
input wire [9:0] rd_burst_len,
output reg rd_ack,
output reg rd_end,
output reg [3:0] rd_sdram_cmd,
output reg [1:0] rd_sdram_ba,
output reg [12:0] rd_sdram_addr,
output wire [15:0] rd_sdram_data
);
// 状态
parameter ST_IDLE = 0,
ST_ACTIVE = 1,
ST_ACT_WAIT = 2,
ST_READ = 3,
ST_CAS_WAIT = 4,
ST_RD_DATA = 5,
ST_PRE = 6,
ST_PRE_WAIT = 7,
ST_RD_END = 8;
// 延迟计数器的值
parameter CNT_ACT_WAIT = 2,
CNT_CAS_WAIT = 3,
CNT_PRE_WAIT = 2;
// 命令
parameter CMD_NOP = 4'b0111,
CMD_ACTIVE = 4'b0011,
CMD_PRE = 4'b0010,
CMD_READ = 4'b0101,
CMD_BURST

本文详细讲解了如何通过Verilog设计实现SDRAM的读取过程,包括命令解读、行/列地址控制、数据突发读取、预充电操作,以及关键时序逻辑的控制。从理论知识到实际代码实现,适合理解SDRAM工作原理与Verilog设计的读者。
最低0.47元/天 解锁文章
761

被折叠的 条评论
为什么被折叠?



