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

📄 ctrl.v

📁 DDR2源代码 DDR2源代码 DDR2源代码
💻 V
📖 第 1 页 / 共 3 页
字号:
//*****************************************************************************// DISCLAIMER OF LIABILITY// // This text/file contains proprietary, confidential// information of Xilinx, Inc., is distributed under license// from Xilinx, Inc., and may be used, copied and/or// disclosed only pursuant to the terms of a valid license// agreement with Xilinx, Inc. Xilinx hereby grants you a // license to use this text/file solely for design, simulation, // implementation and creation of design files limited // to Xilinx devices or technologies. Use with non-Xilinx // devices or technologies is expressly prohibited and // immediately terminates your license unless covered by// a separate agreement.//// Xilinx is providing this design, code, or information // "as-is" solely for use in developing programs and // solutions for Xilinx devices, with no obligation on the // part of Xilinx to provide support. By providing this design, // code, or information as one possible implementation of // this feature, application or standard, Xilinx is making no // representation that this implementation is free from any // claims of infringement. You are responsible for // obtaining any rights you may require for your implementation. // Xilinx expressly disclaims any warranty whatsoever with // respect to the adequacy of the implementation, including // but not limited to any warranties or representations that this// implementation is free from claims of infringement, implied // warranties of merchantability or fitness for a particular // purpose.//// Xilinx products are not intended for use in life support// appliances, devices, or systems. Use in such applications is// expressly prohibited.//// Any modifications that are made to the Source Code are // done at the user抯 sole risk and will be unsupported.//// Copyright (c) 2006-2007 Xilinx, Inc. All rights reserved.//// This copyright and support notice must be retained as part // of this text at all times. //*****************************************************************************//   ____  ____//  /   /\/   /// /___/  \  /    Vendor: Xilinx// \   \   \/     Version: 2.1//  \   \         Application: MIG//  /   /         Filename: ctrl.v// /___/   /\     Date Last Modified: $Date: 2008/01/09 15:43:36 $// \   \  /  \    Date Created: Wed Aug 30 2006//  \___\/\___\//////Device: Virtex-5//Design Name: DDR/DDR2//Purpose://   This module is the main control logic of the memory interface. All//   commands are issued from here according to the burst, CAS Latency and the//   user commands.//Reference://Revision History:// Rev1.2 - Fixed auto refresh to activate bug. KP 11-19-2007//*****************************************************************************`timescale 1ns/1psmodule ctrl #  (   // Following parameters are for 72-bit RDIMM design (for ML561 Reference    // board design). Actual values may be different. Actual parameters values    // are passed from design top module ddr2_sdram module. Please refer to   // the ddr2_sdram module for actual values.   parameter BANK_WIDTH    = 2,   parameter COL_WIDTH     = 10,   parameter CS_BITS       = 0,   parameter CS_NUM        = 1,   parameter ROW_WIDTH     = 14,   parameter ADDITIVE_LAT  = 0,   parameter BURST_LEN     = 4,   parameter CAS_LAT       = 5,   parameter ECC_ENABLE    = 0,   parameter REG_ENABLE    = 1,   parameter TREFI_NS      = 7800,   parameter TRAS          = 40000,   parameter TRCD          = 15000,   parameter TRRD          = 10000,   parameter TRFC          = 105000,   parameter TRP           = 15000,   parameter TRTP          = 7500,   parameter TWR           = 15000,   parameter TWTR          = 10000,   parameter CLK_PERIOD    = 3000,   parameter MULTI_BANK_EN = 1,   parameter TWO_T_TIME_EN = 0,   parameter DDR_TYPE      = 1   )  (   input                   clk,   input                   rst,   input [2:0]             af_cmd,   input [30:0]            af_addr,   input                   af_empty,   input                   phy_init_done,   output                  ctrl_ref_flag,   output                  ctrl_af_rden,   output reg              ctrl_wren,   output reg              ctrl_rden,   output [ROW_WIDTH-1:0]  ctrl_addr,   output [BANK_WIDTH-1:0] ctrl_ba,   output                  ctrl_ras_n,   output                  ctrl_cas_n,   output                  ctrl_we_n,   output [CS_NUM-1:0]     ctrl_cs_n   );  // input address split into various ranges  localparam ROW_RANGE_START     = COL_WIDTH;  localparam ROW_RANGE_END       = ROW_WIDTH + ROW_RANGE_START - 1;  localparam BANK_RANGE_START    = ROW_RANGE_END + 1;  localparam BANK_RANGE_END      = BANK_WIDTH + BANK_RANGE_START - 1;  localparam CS_RANGE_START      = BANK_RANGE_START + BANK_WIDTH;  localparam CS_RANGE_END        = CS_NUM + CS_RANGE_START - 1;  // compare address (for determining bank/row hits) split into various ranges  // (compare address doesn't include column bits)  localparam CMP_WIDTH            = CS_NUM + BANK_WIDTH + ROW_WIDTH;  localparam CMP_ROW_RANGE_START  = 0;  localparam CMP_ROW_RANGE_END    = ROW_WIDTH + CMP_ROW_RANGE_START - 1;  localparam CMP_BANK_RANGE_START = CMP_ROW_RANGE_END + 1;  localparam CMP_BANK_RANGE_END   = BANK_WIDTH + CMP_BANK_RANGE_START - 1;  localparam CMP_CS_RANGE_START   = CMP_BANK_RANGE_END + 1;  localparam CMP_CS_RANGE_END     = CS_BITS + CMP_CS_RANGE_START;  localparam BURST_LEN_DIV2      = BURST_LEN / 2;  localparam OPEN_BANK_NUM       = 4;  localparam CS_BITS_FIX         = (CS_BITS == 0) ? 1 : CS_BITS;  // calculation counters based on clock cycle and memory parameters  // TRAS: ACTIVE->PRECHARGE interval - 2  localparam integer TRAS_CYC = (TRAS + CLK_PERIOD)/CLK_PERIOD;  // TRCD: ACTIVE->READ/WRITE interval - 3 (for DDR2 factor in ADD_LAT)  localparam integer TRRD_CYC = (TRRD + CLK_PERIOD)/CLK_PERIOD;  localparam integer TRCD_CYC = (((TRCD + CLK_PERIOD)/CLK_PERIOD) >                                 ADDITIVE_LAT )?             ((TRCD+CLK_PERIOD)/ CLK_PERIOD) - ADDITIVE_LAT : 0;  // TRFC: REFRESH->REFRESH, REFRESH->ACTIVE interval - 2  localparam integer TRFC_CYC = (TRFC + CLK_PERIOD)/CLK_PERIOD;  // TRP: PRECHARGE->COMMAND interval - 2   // for precharge all add 1 extra clock cycle  localparam integer TRP_CYC =  ((TRP + CLK_PERIOD)/CLK_PERIOD) +1;  // TRTP: READ->PRECHARGE interval - 2 (Al + BL/2 + (max (TRTP, 2tck))-2  localparam integer TRTP_TMP_MIN = (((TRTP + CLK_PERIOD)/CLK_PERIOD) >= 2)?                                     ((TRTP + CLK_PERIOD)/CLK_PERIOD) : 2;  localparam integer TRTP_CYC = TRTP_TMP_MIN + ADDITIVE_LAT                                + BURST_LEN_DIV2 - 2;  // TWR: WRITE->PRECHARGE interval - 2  localparam integer WR_LAT = (DDR_TYPE > 0) ? CAS_LAT + ADDITIVE_LAT - 1 : 1;  localparam integer TWR_CYC = ((TWR + CLK_PERIOD)/CLK_PERIOD) +             WR_LAT + BURST_LEN_DIV2 ;  // TWTR: WRITE->READ interval - 3 (for DDR1, TWTR = 2 clks)  // DDR2 = CL-1 + BL/2 +TWTR  localparam integer TWTR_TMP_MIN = (TWTR + CLK_PERIOD)/CLK_PERIOD;  localparam integer TWTR_CYC = (DDR_TYPE > 0) ? (TWTR_TMP_MIN + (CAS_LAT -1)                                 + BURST_LEN_DIV2 ): 2;  //  TRTW: READ->WRITE interval - 3  //  DDR1: CL + (BL/2)  //  DDR2: (BL/2) + 2. Two more clocks are added to  //  the DDR2 counter to account for the delay in  //  arrival of the DQS during reads (pcb trace + buffer  //  delays + memory parameters).  localparam TRTW_CYC = (DDR_TYPE > 0) ? BURST_LEN_DIV2 + 4 :             (CAS_LAT == 25) ? 2 + BURST_LEN_DIV2 : CAS_LAT + BURST_LEN_DIV2;  localparam integer CAS_LAT_RD = (CAS_LAT == 25) ? 2 : CAS_LAT;  // Make sure all values >= 0 (some may be = 0)  localparam TRAS_COUNT = (TRAS_CYC > 0) ? TRAS_CYC : 0;  localparam TRCD_COUNT = (TRCD_CYC > 0) ? TRCD_CYC : 0;  localparam TRRD_COUNT = (TRRD_CYC > 0) ? TRRD_CYC : 0;  localparam TRFC_COUNT = (TRFC_CYC > 0) ? TRFC_CYC : 0;  localparam TRP_COUNT  = (TRP_CYC > 0)  ? TRP_CYC  : 0;  localparam TRTP_COUNT = (TRTP_CYC > 0) ? TRTP_CYC : 0;  localparam TWR_COUNT  = (TWR_CYC > 0)  ? TWR_CYC  : 0;  localparam TWTR_COUNT = (TWTR_CYC > 0) ? TWTR_CYC : 0;  localparam TRTW_COUNT = (TRTW_CYC > 0) ? TRTW_CYC : 0;  // Auto refresh interval  localparam TREFI_COUNT = ((TREFI_NS * 1000)/CLK_PERIOD) - 1;  // memory controller states  localparam   CTRL_IDLE                =     5'h00;  localparam   CTRL_PRECHARGE           =     5'h01;  localparam   CTRL_PRECHARGE_WAIT      =     5'h02;  localparam   CTRL_AUTO_REFRESH        =     5'h03;  localparam   CTRL_AUTO_REFRESH_WAIT   =     5'h04;  localparam   CTRL_ACTIVE              =     5'h05;  localparam   CTRL_ACTIVE_WAIT         =     5'h06;  localparam   CTRL_BURST_READ          =     5'h07;  localparam   CTRL_READ_WAIT           =     5'h08;  localparam   CTRL_BURST_WRITE         =     5'h09;  localparam   CTRL_WRITE_WAIT          =     5'h0A;  localparam   CTRL_PRECHARGE_WAIT1     =     5'h0B;  reg [CMP_WIDTH-1:0]                      act_addr_r;  wire [30:0]                              af_addr_r;  reg [30:0]                               af_addr_r1;  reg [30:0]                               af_addr_r2;  reg [30:0]                               af_addr_r3;  wire [2:0]                               af_cmd_r;  reg [2:0]                                af_cmd_r1;  reg [2:0]                                af_cmd_r2;  reg                                      af_valid_r;  reg                                      af_valid_r1;  reg                                      af_valid_r2;  reg [CS_BITS_FIX :0]                     auto_cnt_r;  reg                                      auto_ref_r;  reg [(OPEN_BANK_NUM*CMP_WIDTH)-1:0]      bank_cmp_addr_r;  reg [OPEN_BANK_NUM-1:0]                  bank_hit;  reg [OPEN_BANK_NUM-1:0]                  bank_hit_r;  reg [OPEN_BANK_NUM-1:0]                  bank_hit_r1;  reg [OPEN_BANK_NUM-1:0]                  bank_valid_r;  reg                                      bank_conflict_r;  reg                                      conflict_resolved_r;  reg                                      ctrl_af_rden_r;  reg                                      conflict_detect_r;  wire                                     conflict_detect;  reg [ROW_WIDTH-1:0]                      ddr_addr_r;  wire [ROW_WIDTH-1:0]                     ddr_addr_col;  wire [ROW_WIDTH-1:0]                     ddr_addr_row;  reg [BANK_WIDTH-1:0]                     ddr_ba_r;  reg                                      ddr_cas_n_r;  reg [CS_NUM-1:0]                         ddr_cs_n_r;  reg                                      ddr_ras_n_r;  reg                                      ddr_we_n_r;  reg [4:0]                                next_state;  reg                                      no_precharge_wait_r;  reg                                      no_precharge_r;  reg                                      no_precharge_r1;  reg                                      phy_init_done_r;  reg [4:0]                                precharge_ok_cnt_r;  reg                                      precharge_ok_r;  reg [4:0]                                ras_cnt_r;  reg [3:0]                                rcd_cnt_r;  reg                                      rcd_cnt_ok_r;  reg [2:0]                                rdburst_cnt_r;  reg                                      rdburst_ok_r;  reg                                      rdburst_rden_ok_r;  reg                                      rd_af_flag_r;  wire                                     rd_flag;  reg                                      rd_flag_r;  reg [4:0]                                rd_to_wr_cnt_r;  reg                                      rd_to_wr_ok_r;  reg                                      ref_flag_r;  reg [11:0]                               refi_cnt_r;  reg                                      refi_cnt_ok_r;  reg                                      rst_r                                           /* synthesis syn_preserve = 1 */;  reg                                      rst_r1                                           /* synthesis syn_maxfan = 10 */;  reg [7:0]                                rfc_cnt_r;  reg                                      rfc_ok_r;  reg [3:0]                                row_miss;  reg [3:0]                                row_conflict_r;  reg [3:0]                                rp_cnt_r;  reg                                      rp_cnt_ok_r;  reg [CMP_WIDTH-1:0]                      sb_open_add_r;  reg [4:0]                                state_r;  reg [4:0]                                state_r1;  wire                                     sm_rden;  reg                                      sm_rden_r;  reg [2:0]                                trrd_cnt_r;  reg                                      trrd_cnt_ok_r;  reg [2:0]                                two_t_enable_r;  reg [CS_NUM-1:0]                         two_t_enable_r1;  reg [2:0]                                wrburst_cnt_r;  reg                                      wrburst_ok_r;  reg                                      wrburst_wren_ok_r;  wire                                     wr_flag;  reg                                      wr_flag_r;  reg [4:0]                                wr_to_rd_cnt_r;  reg                                      wr_to_rd_ok_r;  // XST attributes for local reset "tree"  // synthesis attribute shreg_extract of rst_r is "no";  // synthesis attribute shreg_extract of rst_r1 is "no";  // synthesis attribute equivalent_register_removal of rst_r is "no"  //***************************************************************************  // sm_rden is used to assert read enable to the address FIFO  assign sm_rden = ((state_r == CTRL_BURST_WRITE) ||                    (state_r == CTRL_BURST_READ)) ;  // assert read flag to the adress FIFO  assign ctrl_af_rden = sm_rden || rd_af_flag_r;  // local reset "tree" for controller logic only. Create this to ease timing  // on reset path. Prohibit equivalent register removal on RST_R to prevent  // "sharing" with other local reset trees (caution: make sure global fanout  // limit is set to large enough value, otherwise SLICES may be used for  // fanout control on RST_R.  always @(posedge clk) begin    rst_r  <= rst;    rst_r1 <= rst_r;  end  //*****************************************************************  // interpret commands from Command/Address FIFO  //*****************************************************************  assign wr_flag = (af_valid_r2) ? ((af_cmd_r2 == 3'b000) ? 1'b1 : 1'b0): 1'b0;  assign rd_flag = (af_valid_r2) ? ((af_cmd_r2 == 3'b001) ? 1'b1 : 1'b0): 1'b0;  always @(posedge clk) begin    rd_flag_r <= rd_flag;    wr_flag_r <= wr_flag;  end  //////////////////////////////////////////////////  // The data from the address FIFO is fetched and  // stored in two register stages. The data will be  // pulled out of the second register stage whenever  // the state machine can handle new data from the  // address FIFO.  // This flag is asserted when there is no  // cmd & address in the pipe. When there is  // valid cmd & addr from the address FIFO the  // af_valid signals will be asserted. This flag will  // be set the cycle af_valid_r is de-asserted.  always @(posedge clk) begin    // for simulation purposes - to force CTRL_AF_RDEN low during reset    if (rst_r1)      rd_af_flag_r <= 1'd0;    else if((ctrl_af_rden_r) ||            (rd_af_flag_r && (af_valid_r || af_valid_r1)))         rd_af_flag_r <= 1'd0;    else if (~af_valid_r1 || ~af_valid_r)         rd_af_flag_r <= 1'd1;  end  // First register stage for the cmd & add from the FIFO.  // The af_valid_r signal gives the status of the data  // in this stage. The af_valid_r will be asserted when there  // is valid data. This register stage will be updated  // 1. read to the FIFO and the FIFO not empty  // 2. After write and read states  // 3. The valid signal is not asserted in the last stage.  always @(posedge clk) begin    if (rst_r1)begin      af_valid_r <= 1'd0;    end else begin      if (ctrl_af_rden_r || sm_rden_r || ~af_valid_r1          || ~af_valid_r2)begin        af_valid_r <= ctrl_af_rden_r;      end    end  end  // The output register in the FIFO is used. The addr  // and command are already registered in the FIFO.  assign af_addr_r = af_addr;  assign af_cmd_r = af_cmd;  // Second register stage for the cmd & add from the FIFO.  // The af_valid_r1 signal gives the status of the data  // in this stage. The af_valid_r will be asserted when there  // is valid data. This register stage will be updated  // 1. read to the FIFO and the FIFO not empty and there  // is no valid data on this stage  // 2. After write and read states  // 3. The valid signal is not asserted in the last stage.  always@(posedge clk) begin    if (rst_r1)begin      af_valid_r1 <= 1'd0;      af_addr_r1 <= {31{1'bx}};      af_cmd_r1 <= {3{1'bx}};    end else if (~af_valid_r1 || sm_rden_r ||                  ~af_valid_r2) begin      af_valid_r1 <= af_valid_r;      af_addr_r1 <= af_addr_r;      af_cmd_r1 <= af_cmd_r;    end  end  // The state machine uses the address and command in this

⌨️ 快捷键说明

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