// Copyright (c) 2003 - Lattice Semiconductor
//                    - November 2003.
//
// This program is controlled by a written license agreement.
// Unauthorized Reproduction or Use is Expressly Prohibited.
// ********************************************************************
//
//
//  Name   : fcram_top
//
//  Parent : 
//
//  Children : fcram_core
//           : ddr_io
//
//  Overview: Top level of FCRAM controller including fcram core, 
//            ddr I/O, control I/O, and user appliation placeholder.
//
//  Log:
//
//  Revision 1.0 11/05/03 Mike Hammer
//                        Nav Gupta
//
//  Initial revision
//  Modified :  
//
// *********************************************************************

`timescale 1 ns/100 ps

`include "fcram_params.v"

module fcram_top (

   sys_resetn,      // system reset (active low)
   pll_clk,
   sys_clk,

   ddr_clk,
   ddr_clkn,
   ddr_pdn,
   ddr_csn,

   ddr_fn,
   ddr_addr,
   ddr_ba,

   ddr_dq,

`ifdef FCRAM1
   ddr_dqs,
`endif

`ifdef FCRAM2
   ddr_qs,
   ddr_ds,
`endif

   usr_reset,
   usr_addri,
   usr_cmdi,
   usr_datai,
   usr_datao,
   usr_num_xfersi,
   usr_acko,
   usr_dreqo,
   usr_dvalo,
   usr_read_delay,
   init_bt,
   init_te,
   init_de,
   init_dic,
   ref_burst,
   ref_interval,
   cntrl_ref_eni

`ifdef TECH_EC
`ifdef DQ_WIDTH8
) /* synthesis PGROUP="fcram_top_group" */ /* synthesis PLOC="R2C23" */ /* synthesis PBBOX="17,17" */ ;
`else
) /* synthesis PGROUP="fcram_top_group" */ /* synthesis PLOC="R2C22" */ /* synthesis PBBOX="17,17" */ ;
`endif
`endif
  
`ifdef TECH_SLAYER
) ;
`endif
  

// -----------------------
// USER DEFINED PARAMETERS
// -----------------------

parameter dq_width = `DQ_WIDTH;    // width of FCRAM data bus (8, 16, 32 bits)
parameter dq_groups = `DQ_GROUPS;  // number of data bus groups (groups of 8)

input          sys_resetn;         // system reset (active low)
output         pll_clk;
input          sys_clk;

output         ddr_clk;
output         ddr_clkn;
output         ddr_pdn;
output         ddr_csn;
output         ddr_fn;
output [14:0]  ddr_addr;
output [1:0]   ddr_ba;

inout [dq_width-1:0]  ddr_dq;

`ifdef TECH_EC
inout [dq_groups-1:0] ddr_dqs;
`endif

`ifdef TECH_SLAYER
input [dq_groups-1:0] ddr_qs;
output [dq_groups-1:0] ddr_ds;
`endif


input         usr_reset;
input [26:0]  usr_addri;
input [2:0]   usr_cmdi;
input [(dq_width*2)-1:0]  usr_datai;
output [(dq_width*2)-1:0] usr_datao;
input [3:0]   usr_num_xfersi;
output        usr_acko;
output        usr_dreqo;
output        usr_dvalo;
input [1:0]   usr_read_delay;
input         init_bt;
input         init_te;
input         init_de;
input [1:0]   init_dic;
input [3:0]   ref_burst;
input [15:0]  ref_interval;
input         cntrl_ref_eni;

//wire          sys_clk_buf;
wire          sys_clk_0;
wire          sys_clkp_90;
wire          sys_reset;
 
wire          pdn;    
wire          csn;
wire          fn;
wire [1:0]    ba;
wire [14:0]   addr;

wire          usr_reset_int;
wire [26:0]   usr_addri_int;
wire [2:0]    usr_cmdi_int;
wire [(dq_width*2)-1:0] usr_datai_int;
wire [(dq_width*2)-1:0] usr_datao_int;
wire [3:0]    usr_num_xfersi_int;
wire          usr_acko_int;
wire          usr_dreqo_int;
wire          usr_dvalo_int;
wire          init_bt_int;
wire          init_te_int;
wire          init_de_int;
wire [1:0]    init_dic_int;
wire [3:0]    ref_burst_int;
wire [15:0]   ref_interval_int;
wire          ctrl_ref_eni_int;

wire [dq_width-1:0]  dout0;
wire [dq_width-1:0]  dout1;
wire          dout_val;
wire [dq_width-1:0]  din0;
wire [dq_width-1:0]  din1;
wire          dqs_en;
wire          dqs_low;

wire          pll_lock;
wire          dcntl_enbl;
wire [dq_groups-1:0] data_valid;
wire [dq_groups-1:0] ddrclkpol;
wire          dqsbuf_read;


// -------------
// reset and GSR
// -------------

INV INV_sys_reset (.A(sys_resetn), .Z(sys_reset));

// instantiate the GSR block for synthesis
GSR GSR_INST (.GSR(~sys_reset));
PUR PUR_INST (.PUR(~sys_reset));

//TSALL TSALL_INST (1'b1);

// --------------------------------
// instantiate the System clock PLL
// --------------------------------

// This will generate a clock in phase with the system clock (DQ output clock) 
// and a clock out of phase by 90 degrees (main FPGA clock and DQS output clock)

`ifdef TECH_EC

//IBM IBM_sys_clk (.I(sys_clk), .O(sys_clk_buf)) /* synthesis LEVELMODE="LVTTL" */;

fcram_ehxpllb sys_clk_pll(

     .pll_rst          (sys_reset),
//     .clk_in           (sys_clk_buf),
     .clk_in           (sys_clk),
     .pll_fbk          (sys_clkp_90),
     .clkop            (sys_clkp_90),
     .clkos            (sys_clk_0),
     .pll_lock         (pll_lock),
     .clkok            ()
);

assign pll_clk = sys_clkp_90;

`endif


`ifdef TECH_SLAYER

IB IB_sys_clk (.I(sys_clk), .O(sys_clk_buf)) /* synthesis LEVELMODE="LVTTL" */;

fcram_ehxplla sys_clk_pll(

     .clk              (sys_clk_buf),
     .resetn           (sys_resetn),
     .clkop            (sys_clkp_90),
     .clkos            (sys_clk_0),
     .lock             (pll_lock)
);

assign pll_clk = sys_clkp_90;

`endif

ddr_io ddr_io_u(

    .sys_reset        (sys_reset),

    .sys_clk_0        (sys_clk_0),
    .sys_clkp_90      (sys_clkp_90),

    .ddr_clk          (ddr_clk),
    .ddr_clkn         (ddr_clkn),

    .ddr_dq           (ddr_dq),

`ifdef TECH_EC
    .ddr_dqs          (ddr_dqs),
    .dcntl_enbl       (dcntl_enbl),
    .data_valid       (data_valid),
    .ddrclkpol        (ddrclkpol),
`endif

`ifdef TECH_SLAYER
    .ddr_qs_in        (ddr_qs),
    .ddr_ds_out       (ddr_ds),
`endif

    .dout0            (dout0),
    .dout1            (dout1),
    .dout_val         (dout_val),

    .din0             (din0),
    .din1             (din1),

    .dqs_en           (dqs_en),
    .dqs_low          (dqs_low),

    .dqsbuf_read      (dqsbuf_read)
);

fpga_io fpga_io_u(

    .sys_reset        (sys_reset),
    .sys_clkp_90      (sys_clkp_90),

    .pdn              (pdn),
    .csn              (csn),
    .fn               (fn),
    .ba               (ba),
    .addr             (addr),

    .ddr_pdn          (ddr_pdn),
    .ddr_csn          (ddr_csn),
    .ddr_fn           (ddr_fn),
    .ddr_ba           (ddr_ba),
    .ddr_addr         (ddr_addr)
);

fcram_one_e2_1_001 fcram_core_u(

    .sys_reset        (sys_reset),
    .sys_clkp_90      (sys_clkp_90),
    .sys_clk_0        (sys_clk_0),

    .usr_reset        (usr_reset_int),
    .usr_addri        (usr_addri_int),
    .usr_cmdi         (usr_cmdi_int),
    .usr_datai        (usr_datai_int),
    .usr_datao        (usr_datao_int),
    .usr_num_xfersi   (usr_num_xfersi_int),
    .usr_acko         (usr_acko_int),
    .usr_dreqo        (usr_dreqo_int),
    .usr_dvalo        (usr_dvalo_int),
    .usr_read_delay   (usr_read_delay),
    .bt               (init_bt_int),
    .te               (init_te_int),
    .de               (init_de_int),
    .dic              (init_dic_int),
    .ref_burst        (ref_burst_int),
    .ref_interval     (ref_interval_int),
    .cntrl_ref_eni    (cntrl_ref_eni_int),

    .pdn              (pdn),
    .csn              (csn),
    .fn               (fn),
    .ba               (ba),
    .addr             (addr),
    .dout0            (dout0),
    .dout1            (dout1),
    .dout_val         (dout_val),
    .din0             (din0),
    .din1             (din1),
    .dqs_en           (dqs_en),
    .dqs_low          (dqs_low),

    .pll_lock         (pll_lock),

`ifdef TECH_EC
    .dcntl_enbl       (dcntl_enbl),
    .data_valid       (data_valid),
    .ddrclkpol        (ddrclkpol),
`endif
    .dqsbuf_read      (dqsbuf_read)
);

fcram_app_drv fcram_app_drv_u(

    .sys_resetn	        (sys_resetn),
    .usr_reset	        (usr_reset), 
    .usr_clk	        (sys_clkp_90),  
    .usr_addri	        (usr_addri),  
    .usr_cmdi	        (usr_cmdi),    
    .usr_datai	        (usr_datai),   
    .usr_datao	        (usr_datao),    
    .usr_num_xfersi	(usr_num_xfersi), 
    .usr_acko	        (usr_acko),        
    .usr_dreqo	        (usr_dreqo),    
    .usr_dvalo	        (usr_dvalo),     
    .init_bt	        (init_bt), 
    .init_te	        (init_te),
    .init_de	        (init_de),
    .init_dic	        (init_dic),   
    .ref_burst	        (ref_burst), 
    .ref_interval	(ref_interval),
    .ctrl_ref_eni	(cntrl_ref_eni),       

    .usr_reset_int	(usr_reset_int),
    .usr_addri_int	(usr_addri_int), 
    .usr_cmdi_int	(usr_cmdi_int),   
    .usr_datai_int	(usr_datai_int),  
    .usr_datao_int	(usr_datao_int),   
    .usr_num_xfersi_int	(usr_num_xfersi_int),
    .usr_acko_int	(usr_acko_int),    
    .usr_dreqo_int	(usr_dreqo_int),
    .usr_dvalo_int	(usr_dvalo_int),
    .init_bt_int	(init_bt_int),
    .init_te_int	(init_te_int),
    .init_de_int	(init_de_int),
    .init_dic_int	(init_dic_int),   
    .ref_burst_int	(ref_burst_int), 
    .ref_interval_int	(ref_interval_int),
    .ctrl_ref_eni_int   (cntrl_ref_eni_int)
);

endmodule
