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

📄 ddr2_32mx32_controller_0.v

📁 Xilinx DDR2存储器接口调试代码
💻 V
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2005-2007 Xilinx, Inc.
// This design is confidential and proprietary of Xilinx, All Rights Reserved.
///////////////////////////////////////////////////////////////////////////////
//   ____  ____
//  /   /\/   /
// /___/  \  /   Vendor			: Xilinx
// \   \   \/    Version		: $Name: i+IP+131489 $
//  \   \        Application		: MIG
//  /   /        Filename		: ddr2_32Mx32_controller_0.v
// /___/   /\    Date Last Modified	: $Date: 2007/09/21 15:23:17 $
// \   \  /  \   Date Created		: Mon May 2 2005
//  \___\/\___\
// Device	: Spartan-3/3A/3A-DSP
// Design Name	: DDR2 SDRAM
// Purpose	: This is main controller block. This includes the following
//                features:
//                - The controller state machine that controls the
//                initialization process upon power up, as well as the
//                read, write, and refresh commands.
//                - Accepts and decodes the user commands.
//                - Generates the address and Bank address and control signals
//                   to the memory    
//                - Generates control signals for other modules.
///////////////////////////////////////////////////////////////////////////////
`timescale 1ns/100ps
`include "../rtl/ddr2_32Mx32_parameters_0.v"

module ddr2_32Mx32_controller_0
  (
   input                           clk/* synthesis syn_keep=1 */,
   input                           rst0,
   input                           rst180,
   input [((`ROW_ADDRESS 
	    + `COL_AP_WIDTH)-1):0] address,
   input [`BANK_ADDRESS-1:0]       bank_address,
   input [2:0]                     command_register,
   input                           burst_done,
   output                          ddr_rasb_cntrl,
   output                          ddr_casb_cntrl,
   output [`BANK_ADDRESS-1:0]      ddr_ba_cntrl,
   output [`ROW_ADDRESS-1:0]       ddr_address_cntrl,
   output                          ddr_csb_cntrl,
   output                          dqs_enable,
   output                          dqs_reset /* synthesis syn_keep=1 */,
   output                          rst_dqs_div_int,
   output                          cmd_ack,
   output                          init,
   output			   ddr_web_cntrl,
   output                          ddr_cke_cntrl,
   output reg                      write_enable,
   output reg                      rst_calib,
   output reg                      ddr_odt_cntrl,
   output reg                      ar_done,
   input                           wait_200us,
   output                          auto_ref_req
   );

   localparam IDLE		      = 4'b0000;
   localparam PRECHARGE		      = 4'b0001;
   localparam AUTO_REFRESH	      = 4'b0010;
   localparam ACTIVE		      = 4'b0011;
   localparam FIRST_WRITE	      = 4'b0100;
   localparam WRITE_WAIT	      = 4'b0101;
   localparam BURST_WRITE	      = 4'b0110;
   localparam PRECHARGE_AFTER_WRITE   = 4'b0111;
   localparam PRECHARGE_AFTER_WRITE_2 = 4'b1000;
   localparam READ_WAIT		      = 4'b1001;
   localparam BURST_READ	      = 4'b1010;
   localparam ACTIVE_WAIT	      = 4'b1011;

   localparam INIT_IDLE	         = 2'b00;
   localparam INIT_PRECHARGE	 = 2'b01;
   localparam INIT_LOAD_MODE_REG = 2'b10;
   localparam INIT_AUTO_REFRESH  = 2'b11;


					
   localparam [5:0]              CNTNEXT = 6'd40;
   reg [3:0]                     current_state;
   reg [3:0]                     next_state;
   reg [1:0]                     init_current_state;
   reg [1:0]                     init_next_state;


   reg [((`ROW_ADDRESS           
	  + `COL_AP_WIDTH)-1):0] address_reg;
   reg                           auto_ref;
   reg                           auto_ref1;
   reg                           autoref_value;
   reg                           auto_ref_detect1;
   reg [(`MAX_REF_WIDTH-1):0]    autoref_count;
   reg                           auto_ref_issued;
   reg [`BANK_ADDRESS-1:0]       ba_address_reg1;
   reg [`BANK_ADDRESS-1:0]       ba_address_reg2;
   reg [2:0]                     burst_length;
   reg [2:0]                     cas_count;

   reg [`ROW_ADDRESS-1:0]        column_address_reg;
   reg [`ROW_ADDRESS-1:0]        column_address_reg1;
   reg [2:0]                     wr;
   reg                           ddr_rasb2;
   reg                           ddr_casb2;
   reg                           ddr_web2;
   reg [`BANK_ADDRESS-1:0]       ddr_ba1;
   reg [`ROW_ADDRESS-1:0]        ddr_address1;
   reg [3:0]                     init_count;
   reg                           init_done;
   reg                           init_done_r1;
   reg                           init_memory;
   reg                           init_mem;
   reg [6:0]                     init_pre_count;
   reg [7:0]                     dll_rst_count;
   reg [(`MAX_REF_WIDTH-1):0]    ref_freq_cnt;
   reg                           read_cmd1;
   reg                           read_cmd2;
   reg                           read_cmd3;
   reg [2:0]                     rcdr_count;
   reg [2:0]                     rcdw_count;
   reg [5:0]                     rfc_counter_value;
   reg                           rfc_count_reg;
   reg                           ar_done_reg;
   reg                           rdburst_end_1;
   reg                           rdburst_end_2;
   reg [2:0]                     rp_count;
   reg [5:0]                     rfc_count;
   reg [`ROW_ADDRESS-1:0]        row_address_reg;
   reg                           rst_dqs_div_r;
   reg                           rst_dqs_div_r1; //For Reg Dimm
   reg [2:0]                     wrburst_end_cnt;
   reg                           wrburst_end_1;
   reg                           wrburst_end_2;
   reg                           wrburst_end_3;
   reg [2:0]                     wr_count;
   reg                           write_cmd1;
   reg                           write_cmd2;
   reg                           write_cmd3;
   reg [2:0]                     dqs_div_cascount;
   reg [2:0]                     dqs_div_rdburstcount;
   reg                           dqs_enable1;
   reg                           dqs_enable2;
   reg                           dqs_enable3;
   reg                           dqs_reset1_clk0;
   reg                           dqs_reset2_clk0;
   reg                           dqs_reset3_clk0;
   reg                           dqs_enable_int;
   reg                           dqs_reset_int;
   reg                           rst180_r;
   reg                           rst0_r;
   reg                           ddr_odt2;
   reg                           go_to_active;
   reg                           accept_cmd_in;
   reg  			 odt_deassert;
   reg                           rpcnt0 ;
   reg                           auto_ref_wait;
   reg                           auto_ref_wait1;
   reg                           auto_ref_wait2;
   reg [5:0]                     count6;


   wire [`ROW_ADDRESS - 1:0]     lmr;
   wire [`ROW_ADDRESS - 1:0]     emr;
   wire [`ROW_ADDRESS - 1:0]     lmr_dll_rst;
   wire [`ROW_ADDRESS - 1:0]     lmr_dll_set;
   wire [`ROW_ADDRESS-1:0]       column_address;

   wire                          write_cmd_in;
   wire                          wrburst_end;
   wire [`ROW_ADDRESS-1:0]       row_address;
   wire                          rdburst_end;
   wire [2:0]                    rp_cnt_value;
   wire                          init_done_value;
   wire                          initialize_memory;
   wire                          read_cmd;
   wire                          ddr_rasb1;
   wire                          ddr_casb1;
   wire                          ddr_web1;
   wire                          ack_reg;
   wire                          ack_o;
   wire                          auto_ref_issued_p;
   wire                          ar_done_p;
   wire                          go_to_active_value;
   wire                          ddr_odt1;
   wire                          rst_dqs_div_int1;
   wire [2:0]                    burst_cnt_max;


   // Input : COMMAND REGISTER FORMAT
   //          000  - NOP
   //          010  - Initialize memory
   //          100  - Write Request
   //          110  - Read request

   // Input : Address format
   //   row address  = address((`ROW_ADDRESS+ `COL_AP_WIDTH) -1 : `COL_AP_WIDTH)
   //   column addres = address( `COL_AP_WIDTH-1 : 0)

   assign    ddr_csb_cntrl       = 1'b0;
   assign    row_address         = address_reg[((`ROW_ADDRESS +
                                                 `COL_AP_WIDTH)-1):
                                               `COL_AP_WIDTH];
   assign    column_address      = {address_reg[`ROW_ADDRESS - 1:11],
				    1'b0,address_reg[9:0]};
   assign    init                = init_done;
   assign    ddr_rasb_cntrl      = ddr_rasb2;
   assign    ddr_casb_cntrl      = ddr_casb2;
   assign    ddr_web_cntrl       = ddr_web2;
   assign    ddr_address_cntrl   = ddr_address1;
   assign    ddr_ba_cntrl        = ddr_ba1;
   assign    rst_dqs_div_int     = rst_dqs_div_int1;
   assign    emr                 = `EXT_LOAD_MODE_REGISTER;
   assign    lmr                 = `LOAD_MODE_REGISTER;
   assign    lmr_dll_rst         = {lmr[`ROW_ADDRESS - 1 : 9],1'b1,lmr[7:0]};
   assign    lmr_dll_set         = {lmr[`ROW_ADDRESS - 1 : 9],1'b0,lmr[7:0]};
   assign    ddr_cke_cntrl       = ~wait_200us;

   always @ (negedge clk)
     rst180_r <= rst180;

   always @ (posedge clk)
     rst0_r <= rst0;

//******************************************************************************
// Register user address 
//******************************************************************************

   always @ (negedge clk) begin
      row_address_reg    <= row_address;
      column_address_reg <= column_address;
      ba_address_reg1    <= bank_address;
      ba_address_reg2    <= ba_address_reg1;
      address_reg        <= address;
   end

   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         burst_length <= 3'b000;
         wr           <= 3'd0;
      end
      else begin
         burst_length  <= lmr[2:0];
         wr            <= `TWR_COUNT_VALUE;
      end
   end

   always @( negedge clk ) begin
      if ( rst180_r )
        accept_cmd_in <= 1'b0;
      else if ( current_state == IDLE && ((rpcnt0 && rfc_count_reg &&
                                           !auto_ref_wait && !auto_ref_issued)))
        accept_cmd_in <= 1'b1;
      else
        accept_cmd_in <= 1'b0;
   end


//******************************************************************************
// Commands from user.
//******************************************************************************
   assign initialize_memory = (command_register == 3'b010);
   assign write_cmd_in      = (command_register == 3'b100 &&
                               accept_cmd_in == 1'b1) ;
   assign read_cmd          = (command_register == 3'b110 &&
                               accept_cmd_in == 1'b1) ;

//******************************************************************************
// write_cmd1 is asserted when user issued write command and the controller s/m 
// is in idle state and AUTO_REF is not asserted.
//******************************************************************************

   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         write_cmd1  <= 1'b0;
         write_cmd2  <= 1'b0;
         write_cmd3  <= 1'b0;
      end
      else begin
         if (accept_cmd_in)
           write_cmd1 <= write_cmd_in;
         write_cmd2 <= write_cmd1;
         write_cmd3 <= write_cmd2;
      end
   end
   
//******************************************************************************
// read_cmd1 is asserted when user issued read command and the controller s/m 
// is in idle state and AUTO_REF is not asserted.
//******************************************************************************
  
   always @ (negedge clk) begin
      if (rst180_r == 1'b1) begin
         read_cmd1      <= 1'b0;
         read_cmd2      <= 1'b0;
         read_cmd3      <= 1'b0;
      end
      else begin
         if (accept_cmd_in)
           read_cmd1       <= read_cmd;
         read_cmd2       <= read_cmd1;
         read_cmd3       <= read_cmd2;
      end
   end
  
//******************************************************************************
// rfc_count
// An executable command can be issued only after Trfc period after a AUTOREFRESH 
// command is issued. rfc_count_value is set in the parameter file depending on 
// the memory device speed grade and the selected frequency.For example for 5B 
// speed grade, trfc= 75 at 133Mhz, rfc_counter_value = 6'b001010. 
// ( Trfc/clk_period= 75/7.5= 10)
//******************************************************************************

   always @( negedge clk ) begin
      if (rst180_r == 1'b1)
        rfc_count <= 6'd0;
      else if(current_state == AUTO_REFRESH)
	rfc_count <= rfc_counter_value;
      else if(rfc_count != 6'b000000)
	rfc_count <= rfc_count - 1'b1;
   end
   
//******************************************************************************
// rp_count
// An executable command can be issued only after Trp period after a PRECHARGE 
// command is issued. rp_count value is fixed to support all memory speed grades. 
//******************************************************************************

   assign rp_cnt_value = (current_state == PRECHARGE) ? 3'b100 :
                         (rpcnt0 != 1'b1) ? (rp_count - 1'b1) :
                         3'b000;
   
//******************************************************************************
// ACTIVE to READ/WRITE counter
//
// rcdr_count
// ACTIVE to READ delay - Minimum interval between ACTIVE and READ command. 
// rcdr_count value is fixed to support all memory speed grades. 
//
// rcdw_count
// ACTIVE to WRITE delay - Minimum interval between ACTIVE and WRITE command.
// rcdw_count value is fixed to support all memory speed grades. 
//
//******************************************************************************

   always @( negedge clk ) begin
      if ( rst180_r )
        rcdr_count <= 3'b000;
      else if ( current_state == ACTIVE )
        rcdr_count <= 3'b001; 
      else if ( rcdr_count != 3'b000 )
        rcdr_count <= rcdr_count - 1'b1;
   end

   always @( negedge clk ) begin
      if ( rst180_r )
        rcdw_count <= 3'b000;
      else if ( current_state == ACTIVE)
        rcdw_count <= 3'b001; 
      else if ( rcdw_count != 3'b000 )
        rcdw_count <= rcdw_count - 1'b1;
   end

//******************************************************************************
// WR Counter a PRECHARGE command can be applied only after 3 cycles after a 
// WRITE command has finished executing
//******************************************************************************

   always @(negedge clk) begin
      if (rst180_r)
        wr_count <= 3'b000;
      else
        if (dqs_enable_int)
          wr_count <=  wr ;
        else if (wr_count != 3'b000)
          wr_count <= wr_count - 3'b001;

⌨️ 快捷键说明

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