SDRAM——自动刷新

在这里插入图片描述
在这里插入图片描述
涉及到了仲裁信号
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

`timescale  1ns/1ns
module  sdram_a_ref
(
    input   wire            sys_clk     ,   //系统时钟,频率100MHz
    input   wire            sys_rst_n   ,   //复位信号,低电平有效
    input   wire            init_end    ,   //初始化结束信号
    input   wire            aref_en     ,   //自动刷新使能

    output  reg             aref_req    ,   //自动刷新请求
    output  reg     [3:0]   aref_cmd    ,   //自动刷新阶段写入sdram的指令,{cs_n,ras_n,cas_n,we_n}
    output  reg     [1:0]   aref_ba     ,   //自动刷新阶段Bank地址
    output  reg     [12:0]  aref_addr   ,   //地址数据,辅助预充电操作,A12-A0,13位地址
    output  wire            aref_end        //自动刷新结束标志
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//

//parameter     define
parameter   CNT_REF_MAX =   10'd749     ;   //自动刷新等待时钟数(7.5us)
parameter   TRP_CLK     =   3'd2        ,   //预充电等待周期
            TRC_CLK     =   3'd7        ;   //自动刷新等待周期
parameter   P_CHARGE    =   4'b0010     ,   //预充电指令
            A_REF       =   4'b0001     ,   //自动刷新指令
            NOP         =   4'b0111     ;   //空操作指令
parameter   AREF_IDLE   =   3'b000      ,   //初始状态,等待自动刷新使能
            AREF_PCHA   =   3'b001      ,   //预充电状态
            AREF_TRP    =   3'b011      ,   //预充电等待          tRP
            AUTO_REF    =   3'b010      ,   //自动刷新状态
            AREF_TRF    =   3'b100      ,   //自动刷新等待        tRC
            AREF_END    =   3'b101      ;   //自动刷新结束

//wire  define
wire            trp_end     ;   //预充电等待结束标志
wire            trc_end     ;   //自动刷新等待结束标志
wire            aref_ack    ;   //自动刷新应答信号

//reg   define
reg     [9:0]   cnt_aref        ;   //自动刷新计数器
reg     [2:0]   aref_state      ;   //SDRAM自动刷新状态
reg     [2:0]   cnt_clk         ;   //时钟周期计数,记录自刷新阶段各状态等待时间
reg             cnt_clk_rst     ;   //时钟周期计数复位标志
reg     [1:0]   cnt_aref_aref   ;   //自动刷新次数计数器

//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//

//cnt_ref:刷新计数器 反正是60~64ms要刷新一次
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_aref    <=  10'd0;
    else    if(cnt_aref >= CNT_REF_MAX)
        cnt_aref    <=  10'd0;
    else    if(init_end == 1'b1)
        cnt_aref    <=  cnt_aref + 1'b1;

//aref_req:自动刷新请求 被应答后才放手
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        aref_req    <=  1'b0;
    else    if(cnt_aref == (CNT_REF_MAX - 1'b1))
        aref_req    <=  1'b1;
    else    if(aref_ack == 1'b1)
        aref_req    <=  1'b0;

//aref_ack:自动刷新应答信号 如果进入了预充电则是被应答
assign  aref_ack = (aref_state == AREF_PCHA ) ? 1'b1 : 1'b0;

//aref_end:自动刷新结束标志
assign  aref_end = (aref_state == AREF_END  ) ? 1'b1 : 1'b0;

//cnt_clk:时钟周期计数,记录初始化各状态等待时间
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_clk <=  3'd0;
    else    if(cnt_clk_rst == 1'b1)
        cnt_clk <=  3'd0;
    else
        cnt_clk <=  cnt_clk + 1'b1;

//trp_end,trc_end,tmrd_end:等待结束标志
assign  trp_end = ((aref_state == AREF_TRP)
                    && (cnt_clk == TRP_CLK )) ? 1'b1 : 1'b0;
assign  trc_end = ((aref_state == AREF_TRF)
                    && (cnt_clk == TRC_CLK )) ? 1'b1 : 1'b0;

//cnt_aref_aref:初始化过程自动刷新次数计数器
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_aref_aref   <=  2'd0;
    else    if(aref_state == AREF_IDLE)
        cnt_aref_aref   <=  2'd0;
    else    if(aref_state == AUTO_REF)
        cnt_aref_aref   <=  cnt_aref_aref + 1'b1;
    else
        cnt_aref_aref   <=  cnt_aref_aref;

//SDRAM自动刷新状态机
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        aref_state  <=  AREF_IDLE;
    else
        case(aref_state)
            AREF_IDLE:	//被仲裁模式允许 才进入预充电状态
                if((aref_en == 1'b1) && (init_end == 1'b1))
                    aref_state  <=  AREF_PCHA;
                else
                    aref_state  <=  aref_state;
            AREF_PCHA:
                aref_state  <=  AREF_TRP;
            AREF_TRP:	
                if(trp_end == 1'b1)	//预充电等待2个周期
                    aref_state  <=  AUTO_REF;
                else
                    aref_state  <=  aref_state;
            AUTO_REF:
                aref_state  <=  AREF_TRF;
            AREF_TRF:
                if(trc_end == 1'b1)	//自动刷新等待7个周期
                    if(cnt_aref_aref == 2'd2)	//刷新两次
                        aref_state  <=  AREF_END;
                    else
                        aref_state  <=  AUTO_REF;
                else
                    aref_state  <=  aref_state;
            AREF_END:
                aref_state  <=  AREF_IDLE;
            default:
                aref_state  <=  AREF_IDLE;
        endcase

//cnt_clk_rst:时钟周期计数复位标志
always@(*)
    begin
        case (aref_state)
            AREF_IDLE:  cnt_clk_rst <=  1'b1;   //时钟周期计数器清零
            AREF_TRP:   cnt_clk_rst <=  (trp_end == 1'b1) ? 1'b1 : 1'b0;
                                                //等待结束标志有效,计数器清零
            AREF_TRF:   cnt_clk_rst <=  (trc_end == 1'b1) ? 1'b1 : 1'b0;
                                                //等待结束标志有效,计数器清零
            AREF_END:   cnt_clk_rst <=  1'b1;
            default:    cnt_clk_rst <=  1'b0;
        endcase
    end

//SDRAM操作指令控制	ba和addr全给1,不需要辅助设置
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            aref_cmd    <=  NOP;
            aref_ba     <=  2'b11;
            aref_addr   <=  13'h1fff;
        end
    else
        case(aref_state)
            AREF_IDLE,AREF_TRP,AREF_TRF:    //执行空操作指令
                begin
                    aref_cmd    <=  NOP;
                    aref_ba     <=  2'b11;
                    aref_addr   <=  13'h1fff;
                end
            AREF_PCHA:  //预充电指令
                begin
                    aref_cmd    <=  P_CHARGE;
                    aref_ba     <=  2'b11;
                    aref_addr   <=  13'h1fff;
                end 
            AUTO_REF:   //自动刷新指令
                begin
                    aref_cmd    <=  A_REF;
                    aref_ba     <=  2'b11;
                    aref_addr   <=  13'h1fff;
                end
            AREF_END:   //一次自动刷新完成
                begin
                    aref_cmd    <=  NOP;
                    aref_ba     <=  2'b11;
                    aref_addr   <=  13'h1fff;
                end    
            default:
                begin
                    aref_cmd    <=  NOP;
                    aref_ba     <=  2'b11;
                    aref_addr   <=  13'h1fff;
                end    
        endcase

endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值