module mcb_soft_calibration_top  # (
  parameter       C_MEM_TZQINIT_MAXCNT  = 10'h512,  // DDR3 Minimum delay between resets
  parameter       C_MC_CALIBRATION_MODE = "CALIBRATION", // if set to CALIBRATION will reset DQS IDELAY to DQS_NUMERATOR/DQS_DENOMINATOR local_param values, and does dynamic recal,
                                                         // if set to NOCALIBRATION then defaults to hard cal blocks setting of C_MC_CALBRATION_DELAY *and* no dynamic recal will be done 
  parameter       SKIP_IN_TERM_CAL  = 1'b0,     // provides option to skip the input termination calibration
  parameter       SKIP_DYNAMIC_CAL  = 1'b0,     // provides option to skip the dynamic delay calibration
  parameter       SKIP_DYN_IN_TERM  = 1'b0,     // provides option to skip the input termination calibration
  parameter       C_SIMULATION      = "FALSE",  // Tells us whether the design is being simulated or implemented
  parameter       C_MEM_TYPE        = "DDR"	// provides the memory device used for the design
  )
  (
  input   wire        UI_CLK,                 // Input - global clock to be used for input_term_tuner and IODRP clock
  input   wire        RST,                    // Input - reset for input_term_tuner - synchronous for input_term_tuner state machine, asynch for IODRP (sub)controller
  input   wire        IOCLK,                  // Input - IOCLK input to the IODRP's
  output  wire        DONE_SOFTANDHARD_CAL,   // active high flag signals soft calibration of input delays is complete and MCB_UODONECAL is high (MCB hard calib complete)
  input   wire        PLL_LOCK,               // Lock signal from PLL
  input   wire        SELFREFRESH_REQ,     
  input   wire        SELFREFRESH_MCB_MODE,
  output  wire         SELFREFRESH_MCB_REQ ,
  output  wire         SELFREFRESH_MODE,    
  
  
  
  
  output  wire        MCB_UIADD,              // to MCB's UIADD port
  output  wire        MCB_UISDI,              // to MCB's UISDI port
  input   wire        MCB_UOSDO,
  input   wire        MCB_UODONECAL,
  input   wire        MCB_UOREFRSHFLAG,
  output  wire        MCB_UICS,
  output  wire        MCB_UIDRPUPDATE,
  output  wire        MCB_UIBROADCAST,
  output  wire  [4:0] MCB_UIADDR,
  output  wire        MCB_UICMDEN,
  output  wire        MCB_UIDONECAL,
  output  wire        MCB_UIDQLOWERDEC,
  output  wire        MCB_UIDQLOWERINC,
  output  wire        MCB_UIDQUPPERDEC,
  output  wire        MCB_UIDQUPPERINC,
  output  wire        MCB_UILDQSDEC,
  output  wire        MCB_UILDQSINC,
  output  wire        MCB_UIREAD,
  output  wire        MCB_UIUDQSDEC,
  output  wire        MCB_UIUDQSINC,
  output  wire        MCB_RECAL,
  output  wire        MCB_SYSRST,
  output  wire        MCB_UICMD,
  output  wire        MCB_UICMDIN,
  output  wire  [3:0] MCB_UIDQCOUNT,
  input   wire  [7:0] MCB_UODATA,
  input   wire        MCB_UODATAVALID,
  input   wire        MCB_UOCMDREADY,
  input   wire        MCB_UO_CAL_START,
  
  inout   wire        RZQ_Pin,
  inout   wire        ZIO_Pin,
  output  wire            CKE_Train
  
  );

  wire IODRP_ADD;
  wire IODRP_SDI;
  wire RZQ_IODRP_SDO;
  wire RZQ_IODRP_CS;
  wire ZIO_IODRP_SDO;
  wire ZIO_IODRP_CS;
  wire IODRP_SDO;
  wire IODRP_CS;
  wire IODRP_BKST;
  wire RZQ_ZIO_ODATAIN;
  wire RZQ_ZIO_TRISTATE;
  wire RZQ_TOUT;
  wire ZIO_TOUT;
  wire [7:0] Max_Value;
  wire ZIO_IN;
  wire RZQ_IN;
  reg     ZIO_IN_R1, ZIO_IN_R2;
  reg     RZQ_IN_R1, RZQ_IN_R2;
  assign RZQ_ZIO_ODATAIN  = ~RST;
  assign RZQ_ZIO_TRISTATE = ~RST;
  assign IODRP_BKST       = 1'b0;  //future hook for possible BKST to ZIO and RZQ


mcb_soft_calibration #(
  .C_MEM_TZQINIT_MAXCNT (C_MEM_TZQINIT_MAXCNT),
  .C_MC_CALIBRATION_MODE(C_MC_CALIBRATION_MODE),
  .SKIP_IN_TERM_CAL     (SKIP_IN_TERM_CAL),
  .SKIP_DYNAMIC_CAL     (SKIP_DYNAMIC_CAL),
  .SKIP_DYN_IN_TERM     (SKIP_DYN_IN_TERM),
  .C_SIMULATION         (C_SIMULATION),
  .C_MEM_TYPE           (C_MEM_TYPE)
  ) 
mcb_soft_calibration_inst (
  .UI_CLK               (UI_CLK),  // main clock input for logic and IODRP CLK pins.  At top level, this should also connect to IODRP2_MCB CLK pins
  .RST                  (RST),             // main system reset for both this Soft Calibration block - also will act as a passthrough to MCB's SYSRST
  .PLL_LOCK             (PLL_LOCK), //lock signal from PLL
  .SELFREFRESH_REQ      (SELFREFRESH_REQ),    
  .SELFREFRESH_MCB_MODE  (SELFREFRESH_MCB_MODE),
  .SELFREFRESH_MCB_REQ   (SELFREFRESH_MCB_REQ ),
  .SELFREFRESH_MODE     (SELFREFRESH_MODE),   
  
  .DONE_SOFTANDHARD_CAL (DONE_SOFTANDHARD_CAL),// active high flag signals soft calibration of input delays is complete and MCB_UODONECAL is high (MCB hard calib complete)        .IODRP_ADD(IODRP_ADD),       // RZQ and ZIO IODRP ADD port, and MCB's UIADD port
  .IODRP_ADD            (IODRP_ADD),       // RZQ and ZIO IODRP ADD port
  .IODRP_SDI            (IODRP_SDI),       // RZQ and ZIO IODRP SDI port, and MCB's UISDI port
  .RZQ_IN               (RZQ_IN_R2),         // RZQ pin from board - expected to have a 2*R resistor to ground
  .RZQ_IODRP_SDO        (RZQ_IODRP_SDO),   // RZQ IODRP's SDO port
  .RZQ_IODRP_CS         (RZQ_IODRP_CS),   // RZQ IODRP's CS port
  .ZIO_IN               (ZIO_IN_R2),         // Z-stated IO pin - garanteed not to be driven externally
  .ZIO_IODRP_SDO        (ZIO_IODRP_SDO),   // ZIO IODRP's SDO port
  .ZIO_IODRP_CS         (ZIO_IODRP_CS),   // ZIO IODRP's CS port
  .MCB_UIADD            (MCB_UIADD),      // to MCB's UIADD port
  .MCB_UISDI            (MCB_UISDI),      // to MCB's UISDI port
  .MCB_UOSDO            (MCB_UOSDO),      // from MCB's UOSDO port (User output SDO)
  .MCB_UODONECAL        (MCB_UODONECAL), // indicates when MCB hard calibration process is complete
  .MCB_UOREFRSHFLAG     (MCB_UOREFRSHFLAG), //high during refresh cycle and time when MCB is innactive
  .MCB_UICS             (MCB_UICS),         // to MCB's UICS port (User Input CS)
  .MCB_UIDRPUPDATE      (MCB_UIDRPUPDATE),  // MCB's UIDRPUPDATE port (gets passed to IODRP2_MCB's MEMUPDATE port: this controls shadow latch used during IODRP2_MCB writes).  Currently just trasnparent
  .MCB_UIBROADCAST      (MCB_UIBROADCAST),  // to MCB's UIBROADCAST port (User Input BROADCAST - gets passed to IODRP2_MCB's BKST port)
  .MCB_UIADDR           (MCB_UIADDR),        //to MCB's UIADDR port (gets passed to IODRP2_MCB's AUXADDR port
  .MCB_UICMDEN          (MCB_UICMDEN),       //set to take control of UI interface - removes control from internal calib block
  .MCB_UIDONECAL        (MCB_UIDONECAL),
  .MCB_UIDQLOWERDEC     (MCB_UIDQLOWERDEC),
  .MCB_UIDQLOWERINC     (MCB_UIDQLOWERINC),
  .MCB_UIDQUPPERDEC     (MCB_UIDQUPPERDEC),
  .MCB_UIDQUPPERINC     (MCB_UIDQUPPERINC),
  .MCB_UILDQSDEC        (MCB_UILDQSDEC),
  .MCB_UILDQSINC        (MCB_UILDQSINC),
  .MCB_UIREAD           (MCB_UIREAD),        //enables read w/o writing by turning on a SDO->SDI loopback inside the IODRP2_MCBs (doesn't exist in regular IODRP2).  IODRPCTRLR_R_WB becomes don't-care.
  .MCB_UIUDQSDEC        (MCB_UIUDQSDEC),
  .MCB_UIUDQSINC        (MCB_UIUDQSINC),
  .MCB_RECAL            (MCB_RECAL),         //when high initiates a hard re-calibration sequence
  .MCB_UICMD            (MCB_UICMD        ),
  .MCB_UICMDIN          (MCB_UICMDIN      ),
  .MCB_UIDQCOUNT        (MCB_UIDQCOUNT    ),
  .MCB_UODATA           (MCB_UODATA       ),
  .MCB_UODATAVALID      (MCB_UODATAVALID  ),
  .MCB_UOCMDREADY       (MCB_UOCMDREADY   ),
  .MCB_UO_CAL_START     (MCB_UO_CAL_START),
  .MCB_SYSRST           (MCB_SYSRST       ), //drives the MCB's SYSRST pin - the main reset for MCB
  .Max_Value            (Max_Value        ),  // Maximum Tap Value from calibrated IOI
  .CKE_Train            (CKE_Train)
);



always@(posedge UI_CLK,posedge RST)
if (RST)        
   begin
        ZIO_IN_R1 <= 1'b0; 
        ZIO_IN_R2 <= 1'b0;

        RZQ_IN_R1 <= 1'b0; 
        RZQ_IN_R2 <= 1'b0;         
   end
else
   begin

        ZIO_IN_R1 <= ZIO_IN;
        ZIO_IN_R2 <= ZIO_IN_R1;
        RZQ_IN_R1 <= RZQ_IN;
        RZQ_IN_R2 <= RZQ_IN_R1;
   end

IOBUF IOBUF_RZQ (
    .O  (RZQ_IN),
    .IO (RZQ_Pin),
    .I  (RZQ_OUT),
    .T  (RZQ_TOUT)
    );

IODRP2 IODRP2_RZQ       (
      .DATAOUT(),
      .DATAOUT2(),
      .DOUT(RZQ_OUT),
      .SDO(RZQ_IODRP_SDO),
      .TOUT(RZQ_TOUT),
      .ADD(IODRP_ADD),
      .BKST(IODRP_BKST),
      .CLK(UI_CLK),
      .CS(RZQ_IODRP_CS),
      .IDATAIN(RZQ_IN),
      .IOCLK0(IOCLK),
      .IOCLK1(1'b1),
      .ODATAIN(RZQ_ZIO_ODATAIN),
      .SDI(IODRP_SDI),
      .T(RZQ_ZIO_TRISTATE)
      );


generate 
if ((C_MEM_TYPE == "DDR" || C_MEM_TYPE == "DDR2" || C_MEM_TYPE == "DDR3") &&
     (SKIP_IN_TERM_CAL == 1'b0)
     ) begin : gen_zio

IOBUF IOBUF_ZIO (
    .O  (ZIO_IN),
    .IO (ZIO_Pin),
    .I  (ZIO_OUT),
    .T  (ZIO_TOUT)
    );


IODRP2 IODRP2_ZIO       (
      .DATAOUT(),
      .DATAOUT2(),
      .DOUT(ZIO_OUT),
      .SDO(ZIO_IODRP_SDO),
      .TOUT(ZIO_TOUT),
      .ADD(IODRP_ADD),
      .BKST(IODRP_BKST),
      .CLK(UI_CLK),
      .CS(ZIO_IODRP_CS),
      .IDATAIN(ZIO_IN),
      .IOCLK0(IOCLK),
      .IOCLK1(1'b1),
      .ODATAIN(RZQ_ZIO_ODATAIN),
      .SDI(IODRP_SDI),
      .T(RZQ_ZIO_TRISTATE)
      );


end 
endgenerate
      

endmodule