📄 control_interface.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 + -