// Copyright (c) 2003 - Lattice Semiconductor
//                    - November 2003.
//
// This program is controlled by a written license agreement.
// Unauthorized Reproduction or Use is Expressly Prohibited.
// ********************************************************************
//
//
//  Name   : ddr_io
//
//  Parent : fcram_top
//
//  Children : 
//
//  Overview: DDR I/O components for EC.
//
//  Log:
//
//  Revision 1.0 11/05/03 Mike Hammer
//                        Nav Gupta
//
//  Initial revision
//  Modified :  
//
// *********************************************************************

`timescale 1 ns/100 ps

`include "fcram_params.v"

module ddr_io (

   sys_reset,      // system reset (active high)

   sys_clk_0,
   sys_clkp_90,

   ddr_clk,
   ddr_clkn,

   ddr_dq,
   ddr_dqs,

   `ifdef TECH_EC
   dcntl_enbl,
   data_valid,
   ddrclkpol,
   `endif

   dout0,
   dout1,
   dout_val,
   din0,
   din1,
   dqs_en,
   dqs_low,
   dqsbuf_read
)  ;
  

// -----------------------
// 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_reset;          // system reset (active high)

input          sys_clk_0;
input          sys_clkp_90;

output         ddr_clk;
output         ddr_clkn;

input          dout_val;

input          dqs_en;
input          dqs_low;

input [dq_width-1:0]   dout0;
input [dq_width-1:0]   dout1;

output [dq_width-1:0]  din0;
output [dq_width-1:0]  din1;

wire [dq_width-1:0]    ddr_dq_buf_in;
// wire [dq_width-1:0]    ddr_dq_buf_in_temp;
// wire [dq_width-1:0]    ddr_dq_buf_in_temp2;
// wire [dq_width-1:0]    ddr_dq_buf_in_temp3;

wire [dq_width-1:0]    ddr_dq_buf_out;
inout [dq_width-1:0]   ddr_dq;
inout [dq_groups-1:0]  ddr_dqs;

`ifdef TECH_EC
input                  dcntl_enbl;
output [dq_groups-1:0] data_valid;
output [dq_groups-1:0] ddrclkpol;
`endif

input                  dqsbuf_read;

wire [dq_groups-1:0]   prmbdet;
// wire [dq_groups-1:0]   ddr_dqs_buf_in;
wire                      ddr_dqs_buf_in_0;
wire                      ddr_dqs_buf_in_1;
// wire [dq_groups-1:0]   ddr_dqs_buf_in_temp;
// wire [dq_groups-1:0]   ddr_dqs_buf_in_temp2;
// wire [dq_groups-1:0]   ddr_dqs_buf_in_temp3;

wire [dq_groups-1:0]   ddr_dqs_buf_out;

wire [dq_groups-1:0]   ddr_dqs_bus;

wire                   dll_dqsdel;
wire [dq_groups-1:0]   ddrclkpol;
wire [dq_groups-1:0]   pio_data_valid;

reg [dq_groups-1:0]    data_valid;

wire                   ddr_clk_single;
wire                   ddr_clk_single_n;

wire [dq_width-1:0]    din0_dqs;
wire [dq_width-1:0]    din1_dqs;


// --------------------
// DDR data bus outputs
// --------------------


ODDRXB oddrxb_ddr_dq0 (.DA(dout0[0]),.DB(dout1[0]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[0]));
ODDRXB oddrxb_ddr_dq1 (.DA(dout0[1]),.DB(dout1[1]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[1]));
ODDRXB oddrxb_ddr_dq2 (.DA(dout0[2]),.DB(dout1[2]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[2]));
ODDRXB oddrxb_ddr_dq3 (.DA(dout0[3]),.DB(dout1[3]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[3]));
ODDRXB oddrxb_ddr_dq4 (.DA(dout0[4]),.DB(dout1[4]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[4]));
ODDRXB oddrxb_ddr_dq5 (.DA(dout0[5]),.DB(dout1[5]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[5]));
ODDRXB oddrxb_ddr_dq6 (.DA(dout0[6]),.DB(dout1[6]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[6]));
ODDRXB oddrxb_ddr_dq7 (.DA(dout0[7]),.DB(dout1[7]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[7]));

wire [dq_width-1:0] ddr_dout_val;

ODDRXB oddrxb_ddr_dout_val0 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[0]));
ODDRXB oddrxb_ddr_dout_val1 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[1]));
ODDRXB oddrxb_ddr_dout_val2 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[2]));
ODDRXB oddrxb_ddr_dout_val3 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[3]));
ODDRXB oddrxb_ddr_dout_val4 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[4]));
ODDRXB oddrxb_ddr_dout_val5 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[5]));
ODDRXB oddrxb_ddr_dout_val6 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[6]));
ODDRXB oddrxb_ddr_dout_val7 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[7]));

BB outbuf_ddr_dq0 (.I(ddr_dq_buf_out[0]),.T(ddr_dout_val[0]),.O(ddr_dq_buf_in[0]),.B(ddr_dq[0])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq1 (.I(ddr_dq_buf_out[1]),.T(ddr_dout_val[1]),.O(ddr_dq_buf_in[1]),.B(ddr_dq[1])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq2 (.I(ddr_dq_buf_out[2]),.T(ddr_dout_val[2]),.O(ddr_dq_buf_in[2]),.B(ddr_dq[2])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq3 (.I(ddr_dq_buf_out[3]),.T(ddr_dout_val[3]),.O(ddr_dq_buf_in[3]),.B(ddr_dq[3])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq4 (.I(ddr_dq_buf_out[4]),.T(ddr_dout_val[4]),.O(ddr_dq_buf_in[4]),.B(ddr_dq[4])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq5 (.I(ddr_dq_buf_out[5]),.T(ddr_dout_val[5]),.O(ddr_dq_buf_in[5]),.B(ddr_dq[5])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq6 (.I(ddr_dq_buf_out[6]),.T(ddr_dout_val[6]),.O(ddr_dq_buf_in[6]),.B(ddr_dq[6])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq7 (.I(ddr_dq_buf_out[7]),.T(ddr_dout_val[7]),.O(ddr_dq_buf_in[7]),.B(ddr_dq[7])) /* synthesis IO_TYPE="SSTL25_II" */ ;


// TEMPORARY DELAYS INSERTED FOR SIMULATION ONLY
// THESE DELAYS REPRESENT BOARD DELAY SEEN BETWEEN FCRAM AND FPGA
// FOR DATA RETURNED FROM FCRAM IN RESPONSE TO A READ ORDER
// THESE DELAYS ARE IGNORED DURING SYNTHESIS
//
// assign ddr_dq_buf_in   = ddr_dq_buf_in_temp;
// assign ddr_dqs_buf_in  = ddr_dqs_buf_in_temp;

// assign #3.0 ddr_dq_buf_in_temp2  = ddr_dq_buf_in_temp;
// assign #3.0 ddr_dqs_buf_in_temp2  = ddr_dqs_buf_in_temp;

// assign #3.0 ddr_dq_buf_in_temp3  = ddr_dq_buf_in_temp2;
// assign #3.0 ddr_dqs_buf_in_temp3  = ddr_dqs_buf_in_temp2;

// assign #3.0 ddr_dq_buf_in  = ddr_dq_buf_in_temp3;
// assign #3.0 ddr_dqs_buf_in  = ddr_dqs_buf_in_temp3;



`ifdef DQ_WIDTH16

ODDRXB oddrxb_ddr_dq8 (.DA(dout0[8]),.DB(dout1[8]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[8]));
ODDRXB oddrxb_ddr_dq9 (.DA(dout0[9]),.DB(dout1[9]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[9]));
ODDRXB oddrxb_ddr_dq10 (.DA(dout0[10]),.DB(dout1[10]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[10]));
ODDRXB oddrxb_ddr_dq11 (.DA(dout0[11]),.DB(dout1[11]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[11]));
ODDRXB oddrxb_ddr_dq12 (.DA(dout0[12]),.DB(dout1[12]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[12]));
ODDRXB oddrxb_ddr_dq13 (.DA(dout0[13]),.DB(dout1[13]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[13]));
ODDRXB oddrxb_ddr_dq14 (.DA(dout0[14]),.DB(dout1[14]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[14]));
ODDRXB oddrxb_ddr_dq15 (.DA(dout0[15]),.DB(dout1[15]),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dq_buf_out[15]));

ODDRXB oddrxb_ddr_dout_val8 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[8]));
ODDRXB oddrxb_ddr_dout_val9 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[9]));
ODDRXB oddrxb_ddr_dout_val10 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[10]));
ODDRXB oddrxb_ddr_dout_val11 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[11]));
ODDRXB oddrxb_ddr_dout_val12 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[12]));
ODDRXB oddrxb_ddr_dout_val13 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[13]));
ODDRXB oddrxb_ddr_dout_val14 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[14]));
ODDRXB oddrxb_ddr_dout_val15 (.DA(dout_val),.DB(dout_val),.LSR(sys_reset),.CLK(sys_clk_0),.Q(ddr_dout_val[15]));

BB outbuf_ddr_dq8 (.I(ddr_dq_buf_out[8]),.T(ddr_dout_val[8]),.O(ddr_dq_buf_in[8]),.B(ddr_dq[8])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq9 (.I(ddr_dq_buf_out[9]),.T(ddr_dout_val[9]),.O(ddr_dq_buf_in[9]),.B(ddr_dq[9])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq10 (.I(ddr_dq_buf_out[10]),.T(ddr_dout_val[10]),.O(ddr_dq_buf_in[10]),.B(ddr_dq[10])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq11 (.I(ddr_dq_buf_out[11]),.T(ddr_dout_val[11]),.O(ddr_dq_buf_in[11]),.B(ddr_dq[11])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq12 (.I(ddr_dq_buf_out[12]),.T(ddr_dout_val[12]),.O(ddr_dq_buf_in[12]),.B(ddr_dq[12])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq13 (.I(ddr_dq_buf_out[13]),.T(ddr_dout_val[13]),.O(ddr_dq_buf_in[13]),.B(ddr_dq[13])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq14 (.I(ddr_dq_buf_out[14]),.T(ddr_dout_val[14]),.O(ddr_dq_buf_in[14]),.B(ddr_dq[14])) /* synthesis IO_TYPE="SSTL25_II" */ ;
BB outbuf_ddr_dq15 (.I(ddr_dq_buf_out[15]),.T(ddr_dout_val[15]),.O(ddr_dq_buf_in[15]),.B(ddr_dq[15])) /* synthesis IO_TYPE="SSTL25_II" */ ;
`endif



// ------------------
// DDR DQ data inputs
// ------------------

IDDRXB iddrxb_ddr_dq0 (.D(ddr_dq_buf_in[0]),.ECLK(ddr_dqs_bus[0]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[0]),.QA(din0_dqs[0]),.QB(din1_dqs[0]));
IDDRXB iddrxb_ddr_dq1 (.D(ddr_dq_buf_in[1]),.ECLK(ddr_dqs_bus[0]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[0]),.QA(din0_dqs[1]),.QB(din1_dqs[1]));
IDDRXB iddrxb_ddr_dq2 (.D(ddr_dq_buf_in[2]),.ECLK(ddr_dqs_bus[0]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[0]),.QA(din0_dqs[2]),.QB(din1_dqs[2]));
IDDRXB iddrxb_ddr_dq3 (.D(ddr_dq_buf_in[3]),.ECLK(ddr_dqs_bus[0]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[0]),.QA(din0_dqs[3]),.QB(din1_dqs[3]));
IDDRXB iddrxb_ddr_dq4 (.D(ddr_dq_buf_in[4]),.ECLK(ddr_dqs_bus[0]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[0]),.QA(din0_dqs[4]),.QB(din1_dqs[4]));
IDDRXB iddrxb_ddr_dq5 (.D(ddr_dq_buf_in[5]),.ECLK(ddr_dqs_bus[0]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[0]),.QA(din0_dqs[5]),.QB(din1_dqs[5]));
IDDRXB iddrxb_ddr_dq6 (.D(ddr_dq_buf_in[6]),.ECLK(ddr_dqs_bus[0]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[0]),.QA(din0_dqs[6]),.QB(din1_dqs[6]));
IDDRXB iddrxb_ddr_dq7 (.D(ddr_dq_buf_in[7]),.ECLK(ddr_dqs_bus[0]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[0]),.QA(din0_dqs[7]),.QB(din1_dqs[7]));


`ifdef DQ_WIDTH16

IDDRXB iddrxb_ddr_dq8 (.D(ddr_dq_buf_in[8]),.ECLK(ddr_dqs_bus[1]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[1]),.QA(din0_dqs[8]),.QB(din1_dqs[8]));
IDDRXB iddrxb_ddr_dq9 (.D(ddr_dq_buf_in[9]),.ECLK(ddr_dqs_bus[1]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[1]),.QA(din0_dqs[9]),.QB(din1_dqs[9]));
IDDRXB iddrxb_ddr_dq10 (.D(ddr_dq_buf_in[10]),.ECLK(ddr_dqs_bus[1]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[1]),.QA(din0_dqs[10]),.QB(din1_dqs[10]));
IDDRXB iddrxb_ddr_dq11 (.D(ddr_dq_buf_in[11]),.ECLK(ddr_dqs_bus[1]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[1]),.QA(din0_dqs[11]),.QB(din1_dqs[11]));
IDDRXB iddrxb_ddr_dq12 (.D(ddr_dq_buf_in[12]),.ECLK(ddr_dqs_bus[1]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[1]),.QA(din0_dqs[12]),.QB(din1_dqs[12]));
IDDRXB iddrxb_ddr_dq13 (.D(ddr_dq_buf_in[13]),.ECLK(ddr_dqs_bus[1]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[1]),.QA(din0_dqs[13]),.QB(din1_dqs[13]));
IDDRXB iddrxb_ddr_dq14 (.D(ddr_dq_buf_in[14]),.ECLK(ddr_dqs_bus[1]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[1]),.QA(din0_dqs[14]),.QB(din1_dqs[14]));
IDDRXB iddrxb_ddr_dq15 (.D(ddr_dq_buf_in[15]),.ECLK(ddr_dqs_bus[1]),.SCLK(sys_clk_0),.CE(1'b1),.LSR(sys_reset),.DDRCLKPOL(ddrclkpol[1]),.QA(din0_dqs[15]),.QB(din1_dqs[15]));

`endif

// ---------------------------------------------------------------------
// Reclock read data from the DQS clock to the falling edge of sys_clk_0
// ---------------------------------------------------------------------

FD1S3AX fd1s3ax_din0_0 (.D(din0_dqs[0]),.CK(~sys_clk_0),.Q(din0[0]));
FD1S3AX fd1s3ax_din0_1 (.D(din0_dqs[1]),.CK(~sys_clk_0),.Q(din0[1]));
FD1S3AX fd1s3ax_din0_2 (.D(din0_dqs[2]),.CK(~sys_clk_0),.Q(din0[2]));
FD1S3AX fd1s3ax_din0_3 (.D(din0_dqs[3]),.CK(~sys_clk_0),.Q(din0[3]));
FD1S3AX fd1s3ax_din0_4 (.D(din0_dqs[4]),.CK(~sys_clk_0),.Q(din0[4]));
FD1S3AX fd1s3ax_din0_5 (.D(din0_dqs[5]),.CK(~sys_clk_0),.Q(din0[5]));
FD1S3AX fd1s3ax_din0_6 (.D(din0_dqs[6]),.CK(~sys_clk_0),.Q(din0[6]));
FD1S3AX fd1s3ax_din0_7 (.D(din0_dqs[7]),.CK(~sys_clk_0),.Q(din0[7]));

FD1S3AX fd1s3ax_din1_0 (.D(din1_dqs[0]),.CK(~sys_clk_0),.Q(din1[0]));
FD1S3AX fd1s3ax_din1_1 (.D(din1_dqs[1]),.CK(~sys_clk_0),.Q(din1[1]));
FD1S3AX fd1s3ax_din1_2 (.D(din1_dqs[2]),.CK(~sys_clk_0),.Q(din1[2]));
FD1S3AX fd1s3ax_din1_3 (.D(din1_dqs[3]),.CK(~sys_clk_0),.Q(din1[3]));
FD1S3AX fd1s3ax_din1_4 (.D(din1_dqs[4]),.CK(~sys_clk_0),.Q(din1[4]));
FD1S3AX fd1s3ax_din1_5 (.D(din1_dqs[5]),.CK(~sys_clk_0),.Q(din1[5]));
FD1S3AX fd1s3ax_din1_6 (.D(din1_dqs[6]),.CK(~sys_clk_0),.Q(din1[6]));
FD1S3AX fd1s3ax_din1_7 (.D(din1_dqs[7]),.CK(~sys_clk_0),.Q(din1[7]));

`ifdef DQ_WIDTH16

FD1S3AX fd1s3ax_din0_8 (.D(din0_dqs[8]),.CK(~sys_clk_0),.Q(din0[8]));
FD1S3AX fd1s3ax_din0_9 (.D(din0_dqs[9]),.CK(~sys_clk_0),.Q(din0[9]));
FD1S3AX fd1s3ax_din0_10 (.D(din0_dqs[10]),.CK(~sys_clk_0),.Q(din0[10]));
FD1S3AX fd1s3ax_din0_11 (.D(din0_dqs[11]),.CK(~sys_clk_0),.Q(din0[11]));
FD1S3AX fd1s3ax_din0_12 (.D(din0_dqs[12]),.CK(~sys_clk_0),.Q(din0[12]));
FD1S3AX fd1s3ax_din0_13 (.D(din0_dqs[13]),.CK(~sys_clk_0),.Q(din0[13]));
FD1S3AX fd1s3ax_din0_14 (.D(din0_dqs[14]),.CK(~sys_clk_0),.Q(din0[14]));
FD1S3AX fd1s3ax_din0_15 (.D(din0_dqs[15]),.CK(~sys_clk_0),.Q(din0[15]));

FD1S3AX fd1s3ax_din1_8 (.D(din1_dqs[8]),.CK(~sys_clk_0),.Q(din1[8]));
FD1S3AX fd1s3ax_din1_9 (.D(din1_dqs[9]),.CK(~sys_clk_0),.Q(din1[9]));
FD1S3AX fd1s3ax_din1_10 (.D(din1_dqs[10]),.CK(~sys_clk_0),.Q(din1[10]));
FD1S3AX fd1s3ax_din1_11 (.D(din1_dqs[11]),.CK(~sys_clk_0),.Q(din1[11]));
FD1S3AX fd1s3ax_din1_12 (.D(din1_dqs[12]),.CK(~sys_clk_0),.Q(din1[12]));
FD1S3AX fd1s3ax_din1_13 (.D(din1_dqs[13]),.CK(~sys_clk_0),.Q(din1[13]));
FD1S3AX fd1s3ax_din1_14 (.D(din1_dqs[14]),.CK(~sys_clk_0),.Q(din1[14]));
FD1S3AX fd1s3ax_din1_15 (.D(din1_dqs[15]),.CK(~sys_clk_0),.Q(din1[15]));

`endif

// --------------------------------------------------------
// DLL for DDR inputs - generates an accurate 90 deg offset
// --------------------------------------------------------

DQSDLL dqsdll_0 (.CLK(sys_clkp_90),.RST(sys_reset),.UDDCNTL(dcntl_enbl),.DQSDEL(dll_dqsdel),.LOCK());

// --------------
// DDR DQS inputs
// --------------

DQSBUFB dqsbufb_ddr_dq0 (.DQSI(ddr_dqs_buf_in_0),.CLK(sys_clkp_90),.READ(dqsbuf_read),.DQSDEL(dll_dqsdel),.DQSO(ddr_dqs_bus[0]),.DDRCLKPOL(ddrclkpol[0]),.DQSC(),.PRMBDET(prmbdet[0]));

`ifdef DQ_WIDTH16
DQSBUFB dqsbufb_ddr_dq1 (.DQSI(ddr_dqs_buf_in_1),.CLK(sys_clkp_90),.READ(dqsbuf_read),.DQSDEL(dll_dqsdel),.DQSO(ddr_dqs_bus[1]),.DDRCLKPOL(ddrclkpol[1]),.DQSC(),.PRMBDET(prmbdet[1]));
`endif

// ---------------
// DDR DQS outputs
// ---------------

ODDRXB oddrxb_ddr_dqs0    (.DA(dqs_low),.DB(1'b0),.LSR(sys_reset),.CLK(sys_clkp_90),.Q(ddr_dqs_buf_out[0]));

`ifdef DQ_WIDTH16
ODDRXB oddrxb_ddr_dqs1    (.DA(dqs_low),.DB(1'b0),.LSR(sys_reset),.CLK(sys_clkp_90),.Q(ddr_dqs_buf_out[1]));
`endif

// --------------------------------------
// DDR DQS bidirectional tri-state buffer
// --------------------------------------

wire ddr_dqs_en_0;
ODDRXB oddrxb_ddr_dqs_en0    (.DA(dqs_en),.DB(dqs_en),.LSR(sys_reset),.CLK(sys_clkp_90),.Q(ddr_dqs_en_0));
BB outbuf_dqs_buf0 (.I(ddr_dqs_buf_out[0]),.T(ddr_dqs_en_0),.O(ddr_dqs_buf_in_0),.B(ddr_dqs[0])) /* synthesis IO_TYPE="SSTL25_II" */ ;

`ifdef DQ_WIDTH16
wire ddr_dqs_en_1;
ODDRXB oddrxb_ddr_dqs_en1    (.DA(dqs_en),.DB(dqs_en),.LSR(sys_reset),.CLK(sys_clkp_90),.Q(ddr_dqs_en_1));
BB outbuf_dqs_buf1 (.I(ddr_dqs_buf_out[1]),.T(ddr_dqs_en_1),.O(ddr_dqs_buf_in_1),.B(ddr_dqs[1])) /* synthesis IO_TYPE="SSTL25_II" */ ;
`endif

// -------------
// DDR CLK output
// --------------

// generate the free running balanced clock output to the FCRAM
ODDRXB oddrxb_ddr_clk  (.DA(1'b1),.DB(1'b0),.LSR(sys_reset),.CLK(sys_clkp_90),.Q(ddr_clk_single));
ODDRXB oddrxb_ddr_clkn (.DA(1'b0),.DB(1'b1),.LSR(sys_reset),.CLK(sys_clkp_90),.Q(ddr_clk_single_n));

OB ob_ddr_clk  (.I(ddr_clk_single),  .O(ddr_clk)) /* synthesis IO_TYPE="SSTL25_II" */ ;
OB ob_ddr_clkn (.I(ddr_clk_single_n),.O(ddr_clkn)) /* synthesis IO_TYPE="SSTL25_II" */ ;

pio_dvalid_gen pio_dvalid_gen_0 (

    .clk            (sys_clk_0),
    .rst_n          (~sys_reset),
    .pio_read       (dqsbuf_read),
    .prmbdet        (prmbdet[0]),
    .dqsi           (ddr_dqs_buf_in_0),
    .ddrclkpol      (ddrclkpol[0]),
    .pio_data_valid (pio_data_valid[0])
);

`ifdef DQ_WIDTH16

pio_dvalid_gen pio_dvalid_gen_1 (

    .clk            (sys_clk_0),
    .rst_n          (~sys_reset),
    .pio_read       (dqsbuf_read),
    .prmbdet        (prmbdet[1]),
    .dqsi           (ddr_dqs_buf_in_1),
    .ddrclkpol      (ddrclkpol[1]),
    .pio_data_valid (pio_data_valid[1])
);

`endif

// reclock the data valid signals
always @ (posedge sys_clkp_90 or posedge sys_reset) begin

    if (sys_reset) begin

        data_valid <= 'd0;
    end
    else begin

        data_valid <= pio_data_valid;
    end
end

endmodule
