zoukankan      html  css  js  c++  java
  • SDRAM读写一字(上)

    SDRAM读写一字

    系统设计

    SDRAM指令

    指令

    常量名

    CKE

    CSn

    RAS

    CASn

    WEn

    备注

    空操作

    NOP

    1

    0

    1

    1

    1

     

    行激活

    ACTIVE

    1

    0

    0

    1

    1

     

    读操作

    READ

    1

    0

    1

    0

    1

     

    写操作

    WRITE

    1

    0

    1

    0

    0

     

    预充电

    PR

    1

    0

    0

    1

    0

     

    自刷新

    AR

    1

    0

    0

    0

    1

     

    设置寄存器

    LMR

    1

    0

    0

    0

    0

     

    突发停止

    BURST_STOP

    1

    0

    1

    1

    0

    1

    SDRAM初始化

        SDRAM控制模块发送初始化使能信号,使能SDRAM初始化模块,然后进行初始化操作,初始化操作完成后,发出初始化完成信号到SDRAM控制模块,SDRAM控制模块进入下一步操作。

        Init_start用于启动SDRAM初始化模块进行初始化,done_init用于反馈SDRAM初始化模块初始化完成。在SDRAM初始化的过程中,根据初始化的每一个步骤,进行输出指令和SDRAM_address信号。

    初始化时序

    初始化操作流程图

    SDRAM初始化代码

    该工程的时钟频率为20MHz

    module sdram_init(

    clk,

    reset_n,

    init_start,

    init_done,

    sdram_command,

    sdram_address

    );

    //参数定义

    parameter T200US = 12'd3999; //上电延迟200us

     

    //端口定义

    input clk; //时钟信号20MHz

    input reset_n; //复位信号

    input init_start; //初始化开始信号,高电平有效

    output init_done; //初始化完成信号,输出,高电平有效

    output [4:0] sdram_command; //ckecs_nrascas_nwe_nSDRAM指令信号

    output [13:0] sdram_address; //[13:12]BA , [11:0]AddrSDRAM地址信号

    //常量定义

    parameter NOP = 5'b10111, //空操作

    ACTIVE = 5'b10011, //行激活

    READ = 5'b10101, //读操作

    WRITE = 5'b10100, //写操作

    PR = 5'b10010, //预充电

    AR = 5'b10001, //自刷新

    LMR = 5'b10000; //设置寄存器

    parameter SET_MODE_REG = {4'd0, 1'b0, 2'd0, 3'b010, 1'b0, 3'b011};

    //突发读写,潜伏期为2,顺序操作,突发长度为8

    //寄存器定义

    reg [11:0] time_cnt; //上电延迟计数寄存器

    reg [4:0] sdram_command_reg; //SDRAM指令寄存器

    reg [13:0] sdram_address_reg; //SDRAM地址信号寄存器,{bank,address}

    reg init_done_reg; //初始化完成信号寄存器

    reg [3:0] state_cnt; //状态机计数器,用于控制状态跳转

     

    //*****************************************************************************

    // 模块名称:SDRAM初始化模块

    // 功能描述:在初始化开始控制信号的控制下进行初始化操作,操作完成后发出初始化完成信号

    //*****************************************************************************

    always @(posedge clk or negedge reset_n)

    begin

    if(reset_n == 1'b0)

    begin

    time_cnt <= #1 12'd0; //上电延迟计数寄存器清零

    state_cnt <= #1 4'd0; //状态计数器初始化

    init_done_reg <= #1 1'b0; //初始化完成寄存器清零

    sdram_command_reg <= #1 NOP; //SDRAM指令寄存器初始化

    sdram_address_reg <= #1 14'h3fff; //SDRAM地址信号寄存器进行置高

    end

    else

    begin

    if(init_start == 1'b1)

    case (state_cnt)

    4'd0://上电延迟200us

    begin

    if(time_cnt == T200US) //判断200us延迟是否结束

    begin

    state_cnt <= #1 state_cnt + 1'b1;

    time_cnt <= #1 12'd0;

    end

    else

    time_cnt <= #1 time_cnt + 1'b1;

    end

    4'd1://预充电操作

    begin

    sdram_command_reg <= #1 PR;

    sdram_address_reg <= #1 14'h3fff;

    state_cnt <= #1 state_cnt + 1'b1;

    end

    4'd2://空操作

    begin

    sdram_command_reg <= #1 NOP;

    state_cnt <= #1 state_cnt + 1'b1;

    end

    4'd3://自动刷新

    begin

    sdram_command_reg <= #1 AR;

    state_cnt <= #1 state_cnt + 1'b1;

    end

    4'd4,4'd5://空操作

    begin

    sdram_command_reg <= #1 NOP;

    state_cnt <= #1 state_cnt + 1'b1;

    end

    4'd6://自动刷新

    begin

    sdram_command_reg <= #1 AR;

    state_cnt <= #1 state_cnt + 1'b1;

    end

    4'd7,4'd8://空操作

    begin

    sdram_command_reg <= #1 NOP;

    state_cnt <= #1 state_cnt + 1'b1;

    end

    4'd9://设置寄存器

    begin

    sdram_command_reg <= #1 LMR;

    state_cnt <= #1 state_cnt + 1'b1;

    sdram_address_reg <= #1 SET_MODE_REG;

    end

    4'd10,4'd11://空操作

    begin

    sdram_command_reg <= #1 NOP;

    state_cnt <= #1 state_cnt + 1'b1;

    end

    4'd12://设置初始化完成信号

    begin

    init_done_reg <= #1 1'b1;

    state_cnt <= #1 state_cnt + 1'b1;

    end

    4'd14://恢复初始化完成信号

    begin

    state_cnt <= #1 4'd0;

    end

    default://其他状态,恢复到初始状态

    begin

    state_cnt <= #1 4'd0;

    sdram_command_reg <= #1 NOP;

    end

    endcase

    end

    end

    //*****************************************************************************

    assign init_done = init_done_reg;

    assign sdram_command = sdram_command_reg;

    assign sdram_address = sdram_address_reg;

    endmodule

    SDRAM读写模块

    state_signal: 状态信号,用于控制对SDRAM进行读写和自刷新;

    sdram_bank_addr:SDRAM最小单元地址,[21:20]块地址+[19:8]行地址Row+[7:0]列地址Column;

    write_data: 写入SDRAM的数据;

    rw_done_signal: 读写完成信号;

    ar_done_signal: 自动刷新完成信号;

    read_data: 从SDRAM读出的数据;

    sdram_command:SDRAM指令,cke、cs_n、ras、cas_n、we_n,SDRAM指令信号;

    sdram_address: SDRAM读写地址;

    sdram_dqm: SDRAM数据掩码;

    sdram_data: SDRAM读写数据;

        state_signal有四种状态,分别为自刷新、读、写、空操作。Sdram读写控制模块根据state_signal的信号对SDRAM发出控制信息,同时接收数据和发送数据、地址。

        当处于自刷新状态时,向SDRAM发送自刷新命令,自刷新完成后ar_done_signal信号有效,表明自刷新操作完成。

        当处于读状态时,向SDRAM发送读数据命令、读取数据的地址sdram_bank_addr,读操作完成后rw_done_signal信号有效,表明读操作完成,这时可以从read_data读取从sdram读取的数据。

        当处于写状态时,向SDRAM发送写数据命令,同时将写入的数据送往write_data,写入的地址送往sdram_bank_addr,写操作完成后rw_done_signal信号有效,表明写操作完成。

        当处于空操作时向sdram发送NOP指令。

        sdram_dqmsdram的数据掩码信号,在对sdram进行读写操作时,其电平状态要与指令sdram_command相配合操作。

    自刷新操作

    存储体中电容的数据有效保存期上限是64ms,也就是说每一行刷新的循环周期是64ms。这样刷新速度就是:行数量/64ms 。我们在看内存规格时,经常会看到4096 Refresh Cycles/64ms 8192 Refresh Cycles/64ms的标识,这里的40968192就代表这个芯片中每个L-Bank的行数。刷新命令一次对一行有效,发送间隔也是随总行数而变化,4096行时为15.625 μs

    由此每隔15us需要自刷新一次。

    刷新操作采样简单的操作:

    1. 发送AutoRefresh命令,命SDRAM刷新内部逻辑的内容
    2. 相关操作需要消耗时间tRFC-63ns

      自刷新时序:

    自刷新代码:

    读操作

    读操作过程

    1. 发送Active命令、行(Row)和库(Bank)地址。
    2. 满足时间要求tRCD-20ns
    3. 发送Read命令、列(Column)和库(Bank)地址,DQM拉低,拉高A10一个时钟,表示读操作后自动释放资源库(With Auto Precharge)。
    4. 满足CAS Latency时间要求
    5. CAS Latency满足之后,接下来满足时间要求tAC-6nstRP-20ns,然后读取数据。

    读操作代码

    写操作

    操作过程

    1. 发送Active命令,发送库(Bank)和行(Row)地址信息。
    2. 满足tRCD时间要求,至少20ns
    3. 发送Write命令、库(Bank)和列(Column)地址;A10拉高代表With Auto Precharge
    4. 同时写入的一字数据。这时候DQM必须拉低。
    5. 满足tWRtDPL)时间要求,至少2个时钟。
    6. 满足tRP时间要求,至少20ns
    7. 经过时间tWRtDPL)以后,一字数据就成功被写入。随后SDRAM开始执行Auto Precharge的操作,释放当前相关的资源库。最后经过tRP以后(Auto Precharge的操作完成)

    时序图

    写操作代码

    大西瓜FPGA-->https://daxiguafpga.taobao.com

    博客资料、代码、图片、文字等属大西瓜FPGA所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!

    每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号“科乎”。

  • 相关阅读:
    vmware linux虚拟机连接ip设置
    java图片转byte转string
    javaScript传递参数,参数变化问题
    path和classpath的区别
    本地jar在打包时打入到项目中去
    使用集合来排序
    Unity 学习笔记2
    Unity 学习笔记
    unity3d 基础知识点
    Unity3D中的多线程及使用多线程
  • 原文地址:https://www.cnblogs.com/logic3/p/5239338.html
Copyright © 2011-2022 走看看