// This module splits the bidirectional dqs line into seperate
// input and output signals.

module ddr_dqs32_io (

    rst,
    dqs_clk,
    core_clk,

    // Input signal from the core
    pio_read,
    tri_en,

    // Input signal from the Master DLL
    dqsdel,

    // output signals to the PIO
    dqsout_pio,

    // output signals to the core
    dqsout_core,
    prmbdet,
    ddrclkpol,
    ddr_dqs_out,
    dqsi,

    // bi-directional DQS signal at the memory
    bidi
);

input                         rst;
input                         dqs_clk;
input                         core_clk;

input   [3:0]                 pio_read;
input                         tri_en;
input                         dqsdel;
input   [1:0]                 ddr_dqs_out;

output  [3:0]                 dqsout_pio;
output  [3:0]                 dqsout_core;
output  [3:0]                 prmbdet;
output  [3:0]                 ddrclkpol;
output  [3:0]                 dqsi;

inout   [3:0]                 bidi;

// Internal wires
wire   [3:0]                  dqsi;
wire   [3:0]                  dqsi_tmp;
wire   [3:0]                  out_to_bb;
wire   [3:0]                  tri_en_reg;



ODDRXB U1_ODDRXB (.DA(ddr_dqs_out[0]), .DB(ddr_dqs_out[1]), .LSR(rst), 
                  .CLK(dqs_clk), .Q(out_to_bb[0]));

ODDRXB U2_ODDRXB (.DA(ddr_dqs_out[0]), .DB(ddr_dqs_out[1]), .LSR(rst), 
                  .CLK(dqs_clk), .Q(out_to_bb[1]));

ODDRXB U3_ODDRXB (.DA(ddr_dqs_out[0]), .DB(ddr_dqs_out[1]), .LSR(rst), 
                  .CLK(dqs_clk), .Q(out_to_bb[2]));

ODDRXB U4_ODDRXB (.DA(ddr_dqs_out[0]), .DB(ddr_dqs_out[1]), .LSR(rst), 
                  .CLK(dqs_clk), .Q(out_to_bb[3]));


ODDRXB U1_TODDRXB (.DA(tri_en), .DB(tri_en), .LSR(rst),
                  .CLK(dqs_clk), .Q(tri_en_reg[0]));
ODDRXB U2_TODDRXB (.DA(tri_en), .DB(tri_en), .LSR(rst),
                  .CLK(dqs_clk), .Q(tri_en_reg[1]));
ODDRXB U3_TODDRXB (.DA(tri_en), .DB(tri_en), .LSR(rst),
                  .CLK(dqs_clk), .Q(tri_en_reg[2]));
ODDRXB U4_TODDRXB (.DA(tri_en), .DB(tri_en), .LSR(rst),
                  .CLK(dqs_clk), .Q(tri_en_reg[3]));

// Instantiate the DQSBUF modules
DQSBUFB U1_DQSBUFB (.DQSI(dqsi[0]), .CLK(core_clk), .READ(pio_read[0]),
                    .DQSDEL(dqsdel), .DQSO(dqsout_pio[0]),
                    .DDRCLKPOL(ddrclkpol[0]), .DQSC(dqsout_core[0]),
                    .PRMBDET(prmbdet[0]));

DQSBUFB U2_DQSBUFB (.DQSI(dqsi[1]), .CLK(core_clk), .READ(pio_read[1]),
                    .DQSDEL(dqsdel), .DQSO(dqsout_pio[1]),
                    .DDRCLKPOL(ddrclkpol[1]), .DQSC(dqsout_core[1]),
                    .PRMBDET(prmbdet[1]));

DQSBUFB U3_DQSBUFB (.DQSI(dqsi[2]), .CLK(core_clk), .READ(pio_read[2]),
                    .DQSDEL(dqsdel), .DQSO(dqsout_pio[2]),
                    .DDRCLKPOL(ddrclkpol[2]), .DQSC(dqsout_core[2]),
                    .PRMBDET(prmbdet[2]));

DQSBUFB U4_DQSBUFB (.DQSI(dqsi[3]), .CLK(core_clk), .READ(pio_read[3]),
                    .DQSDEL(dqsdel), .DQSO(dqsout_pio[3]),
                    .DDRCLKPOL(ddrclkpol[3]), .DQSC(dqsout_core[3]),
                    .PRMBDET(prmbdet[3]));

/////////////////// Parameters for the DQS delay /////////////////////
parameter DQS_DLY_1 = 0 ;
parameter DQS_DLY_2 = 0 ;
parameter DQS_DLY_3 = 0 ;
parameter DQS_DLY_4 = 0 ;

assign #DQS_DLY_1 dqsi[0] = dqsi_tmp[0];
assign #DQS_DLY_2 dqsi[1] = dqsi_tmp[1];
assign #DQS_DLY_3 dqsi[2] = dqsi_tmp[2];
assign #DQS_DLY_4 dqsi[3] = dqsi_tmp[3];


// Instantiate the BB modules

BB U1_BB (.I(out_to_bb[0]), .T(tri_en_reg[0]), .O(dqsi_tmp[0]), .B(bidi[0]));
BB U2_BB (.I(out_to_bb[1]), .T(tri_en_reg[1]), .O(dqsi_tmp[1]), .B(bidi[1]));
BB U3_BB (.I(out_to_bb[2]), .T(tri_en_reg[2]), .O(dqsi_tmp[2]), .B(bidi[2]));
BB U4_BB (.I(out_to_bb[3]), .T(tri_en_reg[3]), .O(dqsi_tmp[3]), .B(bidi[3]));

//TSALL TSALL_INST (.TSALL(1'b1));

endmodule


