⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 control_interface.v

📁 SDRAM控制器Verilog员代码
💻 V
字号:
/******************************************************************************
*
*  LOGIC CORE:          Control Interface - Top level module			
*  MODULE NAME:         control_interface()
*  COMPANY:             Northwest Logic, Inc.
*                       www.nwlogic.com
*
*  REVISION HISTORY:  
*
*    Revision 1.0  05/11/2000     Description: Initial Release.
*             1.1  07/10/2000     Description: change precharge to terminate
*                                              for full page accesses.
*
*  FUNCTIONAL DESCRIPTION:
*
*  This module is the command interface module for the SDR SDRAM controller.
*
*  Copyright Northwest Logic, Inc., 2000.  All rights reserved.  
******************************************************************************/


/*The control interface module decodes and registers commands from the host, and passes the decoded NOP, WRITEA,
READA, REFRESH, PRECHARGE, and LOAD_MODE commands, and ADDR to the command module. The
LOAD_REG1 and LOAD_REG2 commands are decoded and used internally to load the REG1 and REG2 registers
with values from ADDR.The control interface module also contains a 16-bit down counter and control circuit that is used to generate periodic
refresh commands to the command module.*/


module control_interface(
        CLK,
        RESET_N,
        CMD,
        ADDR,
        REF_ACK,
        CM_ACK,
        NOP,
        READA,
        WRITEA,
        REFRESH,
        PRECHARGE,
        LOAD_MODE,
        SADDR,
        SC_CL,
        SC_RC,
        SC_RRD,
        SC_PM,
        SC_BL,
        REF_REQ,
        CMD_ACK
        );

`include        "params.v"

input                           CLK;                    // System Clock  模块的系统时钟
input                           RESET_N;                // System Reset  模块复位信号
input   [2:0]                   CMD;                    // Command input 命令输入
input   [`ASIZE-1:0]            ADDR;                   // Address       地址输入
input                           REF_ACK;                // Refresh request acknowledge  刷新请求确认信号输入,来自command module
input                           CM_ACK;                 // Command acknowledge      命令确认信号输入,来自command module
output                          NOP;                    // Decoded NOP command      解码后的NOP命令(输出给command module)
output                          READA;                  // Decoded READA command    解码后的READA命令(输出给command module)
output                          WRITEA;                 // Decoded WRITEA command   解码后的WRITEA命令(输出给command module)
output                          REFRESH;                // Decoded REFRESH command  解码后的REFRESH命令(输出给command module)
output                          PRECHARGE;              // Decoded PRECHARGE command解码后的PRECHARGE命令(输出给command module)
output                          LOAD_MODE;              // Decoded LOAD_MODE command解码后的LOAD_MODE命令(输出给command module)
output  [`ASIZE-1:0]            SADDR;                  // Registered version of ADDR     SADDR为ADDR经过寄存器寄存后的结果(输出给command module)
output  [1:0]                   SC_CL;                  // Programmed CAS latency   编程的CAS传输延迟(输出给command module)
output  [1:0]                   SC_RC;                  // Programmed RC delay      编程的RC延迟(输出给command module)
output  [3:0]                   SC_RRD;                 // Programmed RRD delay     编程的RRD延迟(输出给command module)
output                          SC_PM;                  // programmed Page Mode     编程的Page Mode(输出给command module) 
output  [3:0]                   SC_BL;                  // Programmed burst length  编程的burst length(输出给command module)
output                          REF_REQ;                // Hidden refresh request   隐藏的刷新请求信号(输出给command module),即用来使SDRAM定时自动刷新的请求信号,并非用户给出的刷新命令
output                          CMD_ACK;                // Command acknowledge      命令确认信号输出(输出给上层模块sdr_sdram)


            
reg                             NOP;
reg                             READA;
reg                             WRITEA;
reg                             REFRESH;
reg                             PRECHARGE;
reg                             LOAD_MODE;
reg     [`ASIZE-1:0]            SADDR;
reg     [1:0]                   SC_CL;
reg     [1:0]                   SC_RC;
reg     [3:0]                   SC_RRD;
reg     [3:0]                   SC_BL;
reg                             SC_PM;
reg                             REF_REQ;
reg                             CMD_ACK;

// Internal signals内部信号,这些信号仅用在本模块内部,用于在用户发出LOAD_REG1、LOAD_REG2命令的情况下,对其进行响应;而用户发出的其他命令NOP、READA、WRITEA、REFRESH、PRECHARGE、LOAD_MODE则需送command module进行处理。
reg                             LOAD_REG1;          //用于配置REG1
reg                             LOAD_REG2;          //用于配置REG2
reg     [15:0]                  REF_PER;            //刷新周期
reg     [15:0]                  timer;              //计数器,用于对两次刷新操作之间的时钟周期数进行计数
reg                             timer_zero;         //计数器下溢(计到0)标志



// Command decode and ADDR register命令解码和地址锁存(时钟信号CLK上升沿)
always @(posedge CLK or negedge RESET_N)
begin
        if (RESET_N == 0)                      //若复位信号有效,则将输出给command module的各个命令以及地址清0
        begin
                NOP             <= 0;
                READA           <= 0;
                WRITEA          <= 0;
                REFRESH         <= 0;
                PRECHARGE       <= 0;
                LOAD_MODE       <= 0;
                SADDR           <= 0;
        end
        
        else
        begin
        
                SADDR <= ADDR;                                  // register the address to keep proper
                                                                // alignment with the command          地址ADDR锁存到SADDR,使之与命令信号对齐
                                                              
                if (CMD == 3'b000)                              // NOP command    若命令输入码为3'b000,则NOP取1,说明用户发出NOP命令
                        NOP <= 1;
                else
                        NOP <= 0;                               //否则为0
                        
                if (CMD == 3'b001)                              // READA command  若命令输入码为3'b001,则READA取1,说明用户发出READA命令
                        READA <= 1;
                else
                        READA <= 0;                             //否则为0
                 
                if (CMD == 3'b010)                              // WRITEA command 若命令输入码为3'b010,则WRITEA取1,说明用户发出WRITEA命令
                        WRITEA <= 1;
                else
                        WRITEA <= 0;                            //否则为0
                        
                if (CMD == 3'b011)                              // REFRESH command若命令输入码为3'b011,则REFRESH取1,说明用户发出REFRESH命令
                        REFRESH <= 1;
                else
                        REFRESH <= 0;                           //否则为0
                        
                if (CMD == 3'b100)                              // PRECHARGE command若命令输入码为3'b100,则PRECHARGE取1,说明用户发出PRECHARGE命令
                        PRECHARGE <= 1;
                else
                        PRECHARGE <= 0;                         //否则为0
                        
                if (CMD == 3'b101)                              // LOAD_MODE command若命令输入码为3'b101,则PRECHARGE取1,说明用户发出LOAD_MODE命令
                        LOAD_MODE <= 1;
                else
                        LOAD_MODE <= 0;                         //否则为0
                        
                //以上命令需送command module进行处理                               
                
                if ((CMD == 3'b110) & (LOAD_REG1 == 0) & (CMD_ACK == 0))                              //LOAD_REG1 command若命令输入码为3'b110说明用户发出LOAD_REG1命令,若同时有LOAD_REG1等于0且输出给上层模块sdr_sdram的命令确认信号CMD_ACK无效,则LOAD_REG1取1
                        LOAD_REG1 <= 1;
                else   
                        LOAD_REG1 <= 0;                                                               //否则为0
                
                if ((CMD == 3'b111) & (LOAD_REG2 == 0) & (CMD_ACK == 0))                              //LOAD_REG2 command若命令输入码为3'b111说明用户发出LOAD_REG2命令,若同时有LOAD_REG2等于0且输出给上层模块sdr_sdram的命令确认信号CMD_ACK无效,则LOAD_REG2取1
                        LOAD_REG2 <= 1;
                else
                        LOAD_REG2 <= 0;                                                               //否则为0
                //上面两个命令在本模块内处理
                        
        end
end



// register configuration information if LOAD_REG1 or LOAD_REG2 is
// asserted.若LOAD_REG1 or LOAD_REG2有效,则将REG1、REG2配置信息锁存(时钟信号CLK上升沿)
always @(posedge CLK or negedge RESET_N)
begin

        if (RESET_N == 0)                              //若复位信号有效,则将寄存器配置信息全部清0
        begin
                SC_CL   <= 0;
                SC_RC   <= 0;
                SC_RRD  <= 0;
                SC_PM   <= 0;
                SC_BL   <= 0;
                REF_PER <= 0;
        end
        
        else                                           //否则
        begin
                if (LOAD_REG1 == 1)                              //若LOAD_REG1 == 1,即需要装载REG1(控制器配置寄存器)
                begin
                        SC_CL   <= SADDR[1:0];                   // CAS Latency  地址信号0、1位携带了编程的CAS传输延迟信息,赋给SC_CL 
                        SC_RC   <= SADDR[3:2];                   // RC delay  地址信号2、3位携带了编程的RC延迟信息,赋给SC_RC
                        SC_RRD  <= SADDR[7:4];                   // RRD delay  地址信号4、5、6、7位携带了编程的RRD延迟信息,赋给SC_RRD
                        SC_PM   <= SADDR[8];                     // Page Mode  地址信号第8位携带了编程的Page Mode信息,赋给SC_PM
                        SC_BL   <= SADDR[12:9];                  // Burst length地址信号9到12位携带了编程的Burst length信息,赋给SC_BL
                end
                
                if (LOAD_REG2 == 1)                              //若LOAD_REG2 == 1,即需要装载REG2(控制器刷新周期寄存器)
                        REF_PER <= SADDR[15:0];                  // REFRESH Period地址信号0到15位携带了SDRAM刷新周期信息,赋给REF_PER
                                                          
        end
end


//  Generate CMD_ACK产生命令确认信号CMD_ACK,输出给顶层模块(时钟信号CLK上升沿)
always @(posedge CLK or negedge RESET_N)
begin
        if (RESET_N == 0)                    //若复位信号有效,则CMD_ACK清0
                CMD_ACK <= 0;
        else                                 //否则若CMD_ACK==0即输出给上层模块sdr_sdram的命令确认信号无效,且来自command module的命令确认信号有效(CM_ACK == 1),或者LOAD_REG1 、LOAD_REG2(这两个命令仅在本模块内使用,并不传送给command module)有效 ,则CMD_ACK赋值为1即有效
                if (((CM_ACK == 1) | (LOAD_REG1 == 1) | (LOAD_REG2 == 1)) & (CMD_ACK == 0))
                        CMD_ACK <= 1;
                else
                        CMD_ACK <= 0;        //否则为0
end


 
// refresh timer刷新计数器(时钟信号CLK上升沿)


always @(posedge CLK or negedge RESET_N) begin
        if (RESET_N == 0) 
        begin                                //若复位信号有效,则清0计数器、计数器下溢标志、刷新请求信号
                timer           <= 0;
                timer_zero      <= 0;
                REF_REQ         <= 0;
        end
        
        else                                 //否则
        begin
                if (timer_zero == 1)         //若计数器下溢标志有效,则计数器赋初值REF_PER
                        timer <= REF_PER;
                else if (SC_BL != 0)         //否则若SC_BL != 0,则计数器减1计数
                        timer <= timer - 1;
                if ((timer==0) & (SC_BL != 0))//若计数器计到0且SC_BL != 0,则计数器溢出标志timer_zero有效且刷新请求有效
                begin
                        timer_zero <= 1;
                        REF_REQ    <= 1;
                end
                
                else                          //否则若来自command module的刷新请求确认输入信号REF_ACK == 1,则计数器溢出标志清除,刷新请求清除
                if (REF_ACK == 1)
                begin
                        timer_zero <= 0;
                        REF_REQ    <= 0;
                end
        end
end

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -