📄 ddr_ctrl.v
字号:
// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Copyright (c) 2001 by Lattice Semiconductor Corporation
// --------------------------------------------------------------------
//
// Permission:
//
// Lattice Semiconductor grants permission to use this code for use
// in synthesis for any Lattice programmable logic product. Other
// use of this code, including the selling or duplication of any
// portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL or Verilog source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Lattice Semiconductor provides no warranty
// regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
// Lattice Semiconductor Corporation
// 5555 NE Moore Court
// Hillsboro, OR 97214
// U.S.A
//
// TEL: 1-800-Lattice (USA and Canada)
// 408-826-6000 (other locations)
//
// web: http://www.latticesemi.com/
// email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
// This is the main control module of the SDR SDRAM controller
// reference design.
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
// Ver :| Author :| Mod. Date :| Changes Made:
// V0.1 :| Nagaraj Chekka :| 07/23/03 :| Pre-Release
// --------------------------------------------------------------------
`timescale 1ns / 1ps
module ddr_ctrl(
clk,
reset_n,
sys_r_wn,
sys_add,
sys_adsn,
sys_dly_200us,
sys_init_done,
istate,
cstate,
wren,
addr
);
`include "ddr_par.v"
//---------------------------------------------------------------------
// inputs
//
input clk;
input reset_n;
input sys_r_wn;
input sys_adsn;
input sys_dly_200us;
input [RA_MSB:CA_LSB] sys_add;
//---------------------------------------------------------------------
// outputs
//
output sys_init_done;
output [3:0] istate;
output [3:0] cstate;
output wren;
output [RA_MSB:CA_LSB] addr;
//---------------------------------------------------------------------
// registers
//
reg sys_init_done; // indicates sdr initialization is done
reg [3:0] istate; // INIT_FSM state variables
reg [3:0] cstate; // CMD_FSM state variables
reg [3:0] cs_clkcnt;
reg [3:0] i_clkcnt;
reg i_syncResetClkCNT; // reset i_clkcnt to 0
reg cs_syncResetClkCNT; // reset cs_clkcnt to 0
reg load_mrs_done; // Load mode register done during intilaization
reg load_mrs_af;
reg rd_wr_req_during_ref_req;
reg [RA_MSB:CA_LSB] addr;
reg wren;
reg [10:0] q;
reg ref_req_c;
reg ref_req;
reg latch_ref_req;
reg ref_ack;
reg sys_adsn_r;
reg [RA_MSB:CA_LSB] sys_add_r ;
reg sys_r_wn_r;
//---------------------------------------------------------------------
// local definitions
//
`define endOf_tRP_i i_clkcnt == NUM_CLK_tRP
`define endOf_tRFC_i i_clkcnt == NUM_CLK_tRFC
`define endOf_tMRD_i i_clkcnt == NUM_CLK_tMRD
`define endOf_tRP cs_clkcnt == NUM_CLK_tRP
`define endOf_tRFC cs_clkcnt == NUM_CLK_tRFC
`define endOf_tMRD cs_clkcnt == NUM_CLK_tMRD
`define endOf_tRCD cs_clkcnt == NUM_CLK_tRCD
`define endOf_Cas_Latency cs_clkcnt == NUM_CLK_CL
`define endOf_Read_Burst cs_clkcnt == NUM_CLK_READ - 1
`define endOf_Write_Burst cs_clkcnt == NUM_CLK_WRITE - 1
`define endOf_tDAL cs_clkcnt == NUM_CLK_WAIT
//=======================================================================
// INIT_FSM state machine
//=======================================================================
always @(posedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
istate <= i_IDLE;
load_mrs_done <= 1'b0;
load_mrs_af <= 1'b0;
end else
case (istate)
i_IDLE: begin // wait for 200 us delay by checking sys_dly_200us
if (sys_dly_200us) istate <= i_NOP;
end
i_NOP: begin // After 200us delay apply NOP and then do precharge all
istate <= i_PRE;
end
i_PRE: begin // precharge all
istate <= (NUM_CLK_tRP == 0) ? (load_mrs_done ? i_AR1 : i_EMRS): i_tRP;
end
i_tRP: begin // wait until tRP satisfied
if (`endOf_tRP_i)
istate <= load_mrs_done ? i_AR1 : i_EMRS;
end
i_EMRS: begin //Enable DLL in Extended Mode Reg
istate <= (NUM_CLK_tMRD == 0) ? i_MRS : i_tMRD;
end
i_tMRD: begin // wait until tMRD satisfied
if (`endOf_tMRD_i)
istate <= load_mrs_done ? (load_mrs_af ? i_ready : i_PRE) : i_MRS;
end
i_MRS: begin //Reset DLL in load Mode Reg
load_mrs_done <= 1'b1;
istate <= (NUM_CLK_tMRD == 0) ? (load_mrs_af ? i_ready : i_PRE) : i_tMRD;
end
i_AR1: begin // auto referesh
istate <= (NUM_CLK_tRFC == 0) ? i_AR2 : i_tRFC1;
end
i_tRFC1: begin // wait until tRFC satisfied
if (`endOf_tRFC_i) istate <= i_AR2;
end
i_AR2: begin // auto referesh
istate <= (NUM_CLK_tRFC == 0) ? i_MRS : i_tRFC2;
end
i_tRFC2: begin // wait until tRFC satisfied
load_mrs_af <= 1'b1; // Load mode register after refresh
if (`endOf_tRFC_i) istate <= i_MRS;
end
i_ready: begin // stay at this state for normal operation
istate <= i_ready;
end
default: begin
istate <= i_NOP;
end
endcase
end
//=======================================================================
// sys_init_done generation
//=======================================================================
always @(posedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
sys_init_done <= 0;
end else begin
case (istate)
i_ready: sys_init_done <= 1;
default: sys_init_done <= 0;
endcase
end
end
//=======================================================================
// Latching the address and looking at
// READ or Write request during Refresh and address latching
//=======================================================================
always @(posedge clk or negedge reset_n) begin
if (reset_n == 1'b0) begin
rd_wr_req_during_ref_req <= 1'b0;
addr <= {RA_MSB {1'b0}};
sys_adsn_r <= 1'b0;
sys_add_r <= {RA_MSB {1'b0}};
sys_r_wn_r <= 1'b0;
end else begin
sys_adsn_r <= sys_adsn;
sys_add_r <= sys_add;
sys_r_wn_r <= sys_r_wn;
// Store the address whenever there is address strobe
if (!sys_adsn_r && sys_init_done)
addr <= sys_add_r;
// New (rd or wr) during refresh command getting serviced
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -