Commit d0cdb654 authored by Andrey Filippov's avatar Andrey Filippov

Modifications for Icarus Verilog

parent 2d6f9609
--- /unisims/OSERDESE1.v 1969-12-31 17:00:00.000000000 -0700
+++ ../../vdt-projects/eddr3/unisims/OSERDESE1.v 2014-05-21 09:38:37.691045918 -0600
@@ -0,0 +1,3293 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 1995/2005 Xilinx, Inc.
+// All Right Reserved.
+///////////////////////////////////////////////////////////////////////////////
+// ____ ____
+// / /\/ /
+// /___/ \ / Vendor : Xilinx
+// \ \ \/ Version : 10.1
+// \ \ Description : Xilinx Timing Simulation Library Component
+// / / Source Synchronous Output Serializer
+// /___/ /\ Filename : OSERDESE1.v
+// \ \ / \ Timestamp : Tue Sep 16 15:30:44 PDT 2008
+// \___\/\___\
+//
+// Revision:
+// 09/16/08 - Initial version.
+// 12/05/08 - IR 495397.
+// 01/13/09 - IR 503429.
+// 01/15/09 - IR 503783 CLKPERF is not inverted for OFB/ofb_out.
+// 02/06/09 - CR 507373 Removed IOCLKGLITCH and CLKB
+// 02/26/09 - CR 510489 fixed SHIFTIN2_in
+// 03/16/09 - CR 512140 and 512139 -- sdf load errors
+// 01/27/10 - CR 546419 Updated specify block
+// 12/13/11 - Added `celldefine and `endcelldefine (CR 524859).
+// 09/04/12 - 676501 CLK -> OFB specify path missing
+// End Revision
+
+`timescale 1 ps / 1 ps
+`celldefine
+
+module OSERDESE1 (OCBEXTEND, OFB, OQ, SHIFTOUT1, SHIFTOUT2, TFB, TQ,
+ CLK, CLKDIV, CLKPERF, CLKPERFDELAY, D1, D2, D3, D4, D5, D6, OCE, ODV, RST, SHIFTIN1, SHIFTIN2, T1, T2, T3, T4, TCE, WC);
+
+
+ parameter DATA_RATE_OQ = "DDR";
+ parameter DATA_RATE_TQ = "DDR";
+ parameter integer DATA_WIDTH = 4;
+ parameter integer DDR3_DATA = 1;
+ parameter [0:0] INIT_OQ = 1'b0;
+ parameter [0:0] INIT_TQ = 1'b0;
+ parameter INTERFACE_TYPE = "DEFAULT";
+ parameter integer ODELAY_USED = 0;
+ parameter SERDES_MODE = "MASTER";
+ parameter [0:0] SRVAL_OQ = 1'b0;
+ parameter [0:0] SRVAL_TQ = 1'b0;
+ parameter integer TRISTATE_WIDTH = 4;
+
+
+ `ifdef XIL_TIMING
+ parameter LOC = "UNPLACED";
+ `endif
+
+//-------------------------------------------------------------
+// Outputs:
+//-------------------------------------------------------------
+// OQ: Data output
+// TQ: Output of tristate mux
+// SHIFTOUT1: Carry out data 1 for slave
+// SHIFTOUT2: Carry out data 2 for slave
+// OFB: O Feedback output
+
+//
+//-------------------------------------------------------------
+// Inputs:
+//-------------------------------------------------------------
+//
+// Inputs:
+// CLK: High speed clock from DCM
+// CLKB: Inverted High speed clock from DCM
+// CLKDIV: Low speed divided clock from DCM
+// CLKPERF: Performance Path clock
+// CLKPERFDELAY: delayed Performance Path clock
+// D1, D2, D3, D4, D5, D6 : Data inputs
+// OCE: Clock enable for output data flops
+// ODV: ODELAY value > 140 degrees
+// RST: Reset control
+// T1, T2, T3, T4: tristate inputs
+// SHIFTIN1: Carry in data 1 for master from slave
+// SHIFTIN2: Carry in data 2 for master from slave
+// TCE: Tristate clock enable
+// WC: Write command given by memory controller
+
+ output OCBEXTEND;
+ output OFB;
+ output OQ;
+ output SHIFTOUT1;
+ output SHIFTOUT2;
+ output TFB;
+ output TQ;
+
+ input CLK;
+ input CLKDIV;
+ input CLKPERF;
+ input CLKPERFDELAY;
+ input D1;
+ input D2;
+ input D3;
+ input D4;
+ input D5;
+ input D6;
+ input OCE;
+ input ODV;
+ input RST;
+ input SHIFTIN1;
+ input SHIFTIN2;
+ input T1;
+ input T2;
+ input T3;
+ input T4;
+ input TCE;
+ input WC;
+
+
+//
+ wire SERDES, DDR_CLK_EDGE;
+ wire [5:0] SRTYPE;
+ wire WC_DELAY;
+ wire [4:0] SELFHEAL;
+
+
+ wire load;
+ wire qmux1, qmux, tmux1, tmux2;
+ wire data1, data2, triin1, triin2;
+ wire d2rnk2;
+ wire CLKD;
+ wire CLKDIVD;
+ wire iodelay_state;
+
+// attribute
+ reg data_rate_int;
+ reg [3:0] data_width_int;
+ reg [1:0] tristate_width_int;
+ reg data_rate_oq_int;
+ reg [1:0] data_rate_tq_int;
+ reg ddr3_data_int;
+ reg interface_type_int;
+ reg odelay_used_int;
+ reg serdes_mode_int;
+
+// Output signals
+ wire ioclkglitch_out, ocbextend_out, ofb_out, oq_out, tq_out, shiftout1_out, shiftout2_out;
+
+// Other signals
+ tri0 GSR = glbl.GSR;
+
+ reg notifier;
+
+ wire CLK_in;
+ wire CLKDIV_in;
+ wire CLKPERF_in;
+ wire CLKPERFDELAY_in;
+ wire D1_in;
+ wire D2_in;
+ wire D3_in;
+ wire D4_in;
+ wire D5_in;
+ wire D6_in;
+ wire OCE_in;
+ wire ODV_in;
+ wire RST_in;
+ wire SHIFTIN1_in;
+ wire SHIFTIN2_in;
+ wire T1_in;
+ wire T2_in;
+ wire T3_in;
+ wire T4_in;
+ wire TCE_in;
+ wire WC_in;
+
+`ifndef XIL_TIMING
+
+ assign CLK_in = CLK;
+ assign CLKDIV_in = CLKDIV;
+ assign D1_in = D1;
+ assign D2_in = D2;
+ assign D3_in = D3;
+ assign D4_in = D4;
+ assign D5_in = D5;
+ assign D6_in = D6;
+ assign OCE_in = OCE;
+ assign T1_in = T1;
+ assign T2_in = T2;
+ assign T3_in = T3;
+ assign T4_in = T4;
+ assign TCE_in = TCE;
+ assign WC_in = WC;
+
+`endif // `ifndef XIL_TIMING
+
+
+ assign CLKPERF_in = CLKPERF;
+// assign CLKPERFDELAY_in = CLKPERFDELAY;
+// IR 495397 & IR 499954
+// assign CLKPERFDELAY_in = (CLKPERFDELAY === 1'bx)? 1'b0 : CLKPERFDELAY;
+ generate
+ case (ODELAY_USED)
+ 0: assign CLKPERFDELAY_in = CLKPERF;
+ 1: assign CLKPERFDELAY_in = (CLKPERFDELAY === 1'bx)? 1'b0 : CLKPERFDELAY;
+ endcase
+ endgenerate
+
+ assign SHIFTIN1_in = SHIFTIN1;
+ assign SHIFTIN2_in = SHIFTIN2;
+ assign ODV_in = ODV;
+ assign RST_in = RST;
+
+ buf b_ocbextend (OCBEXTEND, ocbextend_out);
+ buf b_ofb (OFB, ofb_out);
+ buf b_oq (OQ, oq_out);
+ buf b_shiftout1 (SHIFTOUT1, shiftout1_out);
+ buf b_shiftout2 (SHIFTOUT2, shiftout2_out);
+ buf b_tfb (TFB, tfb_out);
+ buf b_tq (TQ, tq_out);
+
+
+ initial begin
+
+//-------------------------------------------------
+//----- DATA_RATE_OQ check
+//-------------------------------------------------
+ case (DATA_RATE_OQ)
+ "SDR" : data_rate_oq_int <= 1'b1;
+ "DDR" : data_rate_oq_int <= 1'b0;
+ default : begin
+ $display("Attribute Syntax Error : The attribute DATA_RATE_OQ on OSERDESE1 instance %m is set to %s. Legal values for this attribute are SDR or DDR", DATA_RATE_OQ);
+ $display("finish OSERDESE1 1");
+ $finish;
+ end
+ endcase // case(DATA_RATE_OQ)
+
+//-------------------------------------------------
+//----- DATA_RATE_TQ check
+//-------------------------------------------------
+ case (DATA_RATE_TQ)
+
+ "BUF" : data_rate_tq_int <= 2'b00;
+ "SDR" : data_rate_tq_int <= 2'b01;
+ "DDR" : data_rate_tq_int <= 2'b10;
+ default : begin
+ $display("Attribute Syntax Error : The attribute DATA_RATE_TQ on OSERDESE1 instance %m is set to %s. Legal values for this attribute are BUF, SDR or DDR", DATA_RATE_TQ);
+ $display("finish OSERDESE1 2");
+ $finish;
+ end
+
+ endcase // case(DATA_RATE_TQ)
+
+//-------------------------------------------------
+//----- DATA_WIDTH check
+//-------------------------------------------------
+ case (DATA_WIDTH)
+
+ 2, 3, 4, 5, 6, 7, 8, 10 : data_width_int = DATA_WIDTH;
+ default : begin
+ $display("Attribute Syntax Error : The attribute DATA_WIDTH on OSERDESE1 instance %m is set to %d. Legal values for this attribute are 2, 3, 4, 5, 6, 7, 8, or 10", DATA_WIDTH);
+ $display("finish OSERDESE1 3");
+ $finish;
+ end
+ endcase // case(DATA_WIDTH)
+
+//-------------------------------------------------
+//----- DDR3_DATA check
+//-------------------------------------------------
+ case (DDR3_DATA)
+ 0 : ddr3_data_int <= 1'b0;
+ 1 : ddr3_data_int <= 1'b1;
+ default : begin
+ $display("Attribute Syntax Error : The attribute DDR3_DATA on OSERDESE1 instance %m is set to %d. Legal values for this attribute are 0 or 1", DDR3_DATA);
+ $display("finish OSERDESE1 4");
+ $finish;
+ end
+ endcase // case(DDR3_DATA)
+
+//-------------------------------------------------
+//----- INTERFACE_TYPE check
+//-------------------------------------------------
+ case (INTERFACE_TYPE)
+ "DEFAULT" : interface_type_int <= 1'b0;
+ "MEMORY_DDR3" : interface_type_int <= 1'b1;
+ default : begin
+ $display("Attribute Syntax Error : The attribute INTERFACE_TYPE on OSERDESE1 instance %m is set to %s. Legal values for this attribute are DEFAULT, or MEMORY_DDR3", INTERFACE_TYPE);
+ $display("finish OSERDESE1 5");
+ $finish;
+ end
+ endcase // INTERFACE_TYPE
+
+
+//-------------------------------------------------
+//----- ODELAY_USED check
+//-------------------------------------------------
+ case (ODELAY_USED)
+
+// "FALSE" : odelay_used_int <= 1'b0;
+// "TRUE" : odelay_used_int <= 1'b1;
+ 0 : odelay_used_int <= 1'b0;
+ 1 : odelay_used_int <= 1'b1;
+ default : begin
+ $display("Attribute Syntax Error : The attribute ODELAY_USED on OSERDESE1 instance %m is set to %s. Legal values for this attribute are FALSE or TRUE", ODELAY_USED);
+ $display("finish OSERDESE1 6");
+ $finish;
+ end
+
+ endcase // case(ODELAY_USED)
+
+//-------------------------------------------------
+//----- SERDES_MODE check
+//-------------------------------------------------
+ case (SERDES_MODE)
+
+ "MASTER" : serdes_mode_int <= 1'b0;
+ "SLAVE" : serdes_mode_int <= 1'b1;
+ default : begin
+ $display("Attribute Syntax Error : The attribute SERDES_MODE on OSERDESE1 instance %m is set to %s. Legal values for this attribute are MASTER or SLAVE", SERDES_MODE);
+ $display("finish OSERDESE1 7");
+ $finish;
+ end
+
+ endcase // case(SERDES_MODE)
+
+//-------------------------------------------------
+//----- TRISTATE_WIDTH check
+//-------------------------------------------------
+ case (TRISTATE_WIDTH)
+
+ 1 : tristate_width_int <= 2'b00;
+ 2 : tristate_width_int <= 2'b01;
+ 4 : tristate_width_int <= 2'b10;
+ default : begin
+ $display("Attribute Syntax Error : The attribute TRISTATE_WIDTH on OSERDESE1 instance %m is set to %d. Legal values for this attribute are 1, 2 or 4", TRISTATE_WIDTH);
+ $display("finish OSERDESE1 8");
+ $finish;
+ end
+
+ endcase // case(TRISTATE_WIDTH)
+// $display("Info: The attribute TRISTATE_WIDTH on OSERDESE1 instance %m is set to %d", TRISTATE_WIDTH);
+
+//-------------------------------------------------
+ end // initial begin
+
+//-------------------------------------------------
+
+ assign SERDES = 1'b1;
+ assign SRTYPE = 6'b111111;
+ assign DDR_CLK_EDGE = 1'b1;
+ assign WC_DELAY = 1'b0;
+ assign SELFHEAL = 5'b00000;
+
+ assign #0 CLKD = CLK;
+ assign #0 CLKDIVD = CLKDIV;
+
+
+ assign #10 ofb_out = (ODELAY_USED == 1)? CLKPERF : oq_out;
+ assign #10 tfb_out = iodelay_state;
+
+
+/////////////////////////////////////////////////////////
+//
+// Delay assignments
+//
+/////////////////////////////////////////////////////////
+
+// Data output delays
+defparam dfront.FFD = 1; // clock to out delay for flip flops
+// driven by clk
+defparam datao.FFD = 1; // clock to out delay for flip flops
+// driven by clk
+defparam dfront.FFCD = 1; // clock to out delay for flip flops
+// driven by clkdiv
+defparam dfront.MXD = 1; // mux delay
+
+defparam dfront.MXR1 = 1; // mux before 2nd rank of flops
+
+// Programmable load generator
+defparam dfront.ldgen.ffdcnt = 1;
+defparam dfront.ldgen.mxdcnt = 1;
+defparam dfront.ldgen.FFRST = 145; // clock to out delay for flop in PLSG
+
+// Tristate output delays
+defparam tfront.ffd = 1; // clock to out delay for flip flops
+defparam tfront.mxd = 1; // mux delay
+
+defparam trio.ffd = 1; // clock to out delay for flip flops
+defparam trio.mxd = 1; // mux delay
+
+//------------------------------------------------------------------
+// Instantiate output data section
+//------------------------------------------------------------------
+
+rank12d_oserdese1_vlog dfront (.D1(D1_in), .D2(D2_in), .D3(D3_in), .D4(D4_in), .D5(D5_in), .D6(D6_in),
+ .d2rnk2(d2rnk2),
+ .SHIFTIN1(SHIFTIN1_in), .SHIFTIN2(SHIFTIN2_in),
+ .C(CLK_in), .CLKDIV(CLKDIV_in), .SR(RST_in), .OCE(OCE_in),
+ .data1(data1), .data2(data2), .SHIFTOUT1(shiftout1_out), .SHIFTOUT2(shiftout2_out),
+ .DATA_RATE_OQ(data_rate_oq_int), .DATA_WIDTH(data_width_int),
+ .SERDES_MODE(serdes_mode_int), .load(load),
+ .IOCLK_GLITCH(ioclkglitch_out),
+ .INIT_OQ(INIT_OQ), .SRVAL_OQ(SRVAL_OQ));
+
+
+trif_oserdese1_vlog tfront (.T1(T1_in), .T2(T2_in), .T3(T3_in), .T4(T4_in), .load(load),
+ .C(CLK_in), .CLKDIV(CLKDIV_in), .SR(RST_in), .TCE(TCE_in),
+ .DATA_RATE_TQ(data_rate_tq_int), .TRISTATE_WIDTH(tristate_width_int),
+ .INIT_TQ(INIT_TQ), .SRVAL_TQ(SRVAL_TQ),
+ .data1(triin1), .data2(triin2));
+
+
+txbuffer_oserdese1_vlog DDR3FIFO (.iodelay_state(iodelay_state), .qmux1(qmux1), .qmux2(qmux2), .tmux1(tmux1), .tmux2(tmux2),
+ .d1(data1), .d2(data2), .t1(triin1), .t2(triin2), .trif(tq_out),
+ .WC(WC_in), .ODV(ODV_in), .extra(ocbextend_out),
+ .clk(CLK_in), .clkdiv(CLKDIV_in), .bufo(CLKPERFDELAY_in), .bufop(CLKPERF_in), .rst(RST_in),
+ .ODELAY_USED(odelay_used_int), .DDR3_DATA(ddr3_data_int),
+ .DDR3_MODE(interface_type_int));
+
+dout_oserdese1_vlog datao (.data1(qmux1), .data2(qmux2),
+ .CLK(CLK_in), .BUFO(CLKPERFDELAY_in), .SR(RST_in), .OCE(OCE_in),
+ .OQ(oq_out), .d2rnk2(d2rnk2),
+ .DATA_RATE_OQ(data_rate_oq_int),
+ .INIT_OQ(INIT_OQ), .SRVAL_OQ(SRVAL_OQ),
+ .DDR3_MODE(interface_type_int));
+
+tout_oserdese1_vlog trio (.data1(tmux1), .data2(tmux2),
+ .CLK(CLK_in), .BUFO(CLKPERFDELAY_in), .SR(RST_in), .TCE(TCE_in),
+ .DATA_RATE_TQ(data_rate_tq_int), .TRISTATE_WIDTH(tristate_width_int),
+ .INIT_TQ(INIT_TQ), .SRVAL_TQ(SRVAL_TQ),
+ .TQ(tq_out), .DDR3_MODE(interface_type_int));
+
+
+`ifndef XIL_TIMING
+ specify
+ ( CLK => OFB) = (100, 100);
+ ( CLK => OQ) = (100, 100);
+ ( CLK => TQ) = (100, 100);
+ ( CLKPERF => OQ) = (100, 100);
+ ( CLKPERF => TQ) = (100, 100);
+ ( CLKPERFDELAY => OQ) = (100, 100);
+ ( CLKPERFDELAY => TQ) = (100, 100);
+ ( T1 => TQ) = (0, 0);
+
+ specparam PATHPULSE$ = 0;
+
+ endspecify
+`endif // `ifndef XIL_TIMING
+
+`ifdef XIL_TIMING
+//*** Timing Checks Start here
+
+ specify
+ ( CLK => OFB) = (100:100:100, 100:100:100);
+ ( CLK => OQ) = (100:100:100, 100:100:100);
+ ( CLK => TQ) = (100:100:100, 100:100:100);
+ ( CLKPERF => OQ) = (100:100:100, 100:100:100);
+ ( CLKPERF => TQ) = (100:100:100, 100:100:100);
+ ( CLKPERFDELAY => OQ) = (100:100:100, 100:100:100);
+ ( CLKPERFDELAY => TQ) = (100:100:100, 100:100:100);
+ ( T1 => TQ) = (0:0:0, 0:0:0);
+
+ $setuphold (posedge CLK, negedge OCE, 0:0:0, 0:0:0, notifier,,, CLK_in, OCE_in);
+ $setuphold (posedge CLK, negedge T1, 0:0:0, 0:0:0, notifier,,, CLK_in, T1_in);
+ $setuphold (posedge CLK, negedge TCE, 0:0:0, 0:0:0, notifier,,, CLK_in, TCE_in);
+ $setuphold (posedge CLK, posedge OCE, 0:0:0, 0:0:0, notifier,,, CLK_in, OCE_in);
+ $setuphold (posedge CLK, posedge T1, 0:0:0, 0:0:0, notifier,,, CLK_in, T1_in);
+ $setuphold (posedge CLK, posedge TCE, 0:0:0, 0:0:0, notifier,,, CLK_in, TCE_in);
+ $setuphold (posedge CLKDIV, negedge D1, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D1_in);
+ $setuphold (posedge CLKDIV, negedge D2, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D2_in);
+ $setuphold (posedge CLKDIV, negedge D3, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D3_in);
+ $setuphold (posedge CLKDIV, negedge D4, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D4_in);
+ $setuphold (posedge CLKDIV, negedge D5, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D5_in);
+ $setuphold (posedge CLKDIV, negedge D6, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D6_in);
+ $setuphold (posedge CLKDIV, negedge RST, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, RST_in);
+ $setuphold (posedge CLKDIV, negedge T1, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T1_in);
+ $setuphold (posedge CLKDIV, negedge T2, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T2_in);
+ $setuphold (posedge CLKDIV, negedge T3, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T3_in);
+ $setuphold (posedge CLKDIV, negedge T4, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T4_in);
+ $setuphold (posedge CLKDIV, negedge WC, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, WC_in);
+ $setuphold (posedge CLKDIV, posedge D1, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D1_in);
+ $setuphold (posedge CLKDIV, posedge D2, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D2_in);
+ $setuphold (posedge CLKDIV, posedge D3, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D3_in);
+ $setuphold (posedge CLKDIV, posedge D4, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D4_in);
+ $setuphold (posedge CLKDIV, posedge D5, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D5_in);
+ $setuphold (posedge CLKDIV, posedge D6, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, D6_in);
+ $setuphold (posedge CLKDIV, posedge RST, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, RST_in);
+ $setuphold (posedge CLKDIV, posedge T1, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T1_in);
+ $setuphold (posedge CLKDIV, posedge T2, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T2_in);
+ $setuphold (posedge CLKDIV, posedge T3, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T3_in);
+ $setuphold (posedge CLKDIV, posedge T4, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, T4_in);
+ $setuphold (posedge CLKDIV, posedge WC, 0:0:0, 0:0:0, notifier,,, CLKDIV_in, WC_in);
+
+ specparam PATHPULSE$ = 0;
+
+ endspecify
+`endif // `ifdef XIL_TIMING
+
+
+endmodule // OSERDESE1
+
+`timescale 1ps/1ps
+/////////////////////////////////////////////////////////
+//
+// module selfheal_oserdese1_vlog
+//
+///////////////////////////////////////////////////////
+//
+// Self healing circuit for Mt Blanc
+// This model ONLY works for SERDES operation!!
+//
+//
+//
+////////////////////////////////////////////////////////
+//
+//
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+// dq3 - dq0: Data from load counter
+// CLKDIV: Divided clock from PLL
+// srint: RESET from load generator
+// rst: Set/Reset control
+//
+//
+//
+// Outputs:
+// SHO: Data output
+//
+//
+//
+// Programmable Points
+// SELFHEAL: String of 5 bits. 1 as enable and 4 as compare
+// Test attributes in model
+//
+//
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module selfheal_oserdese1_vlog (dq3, dq2, dq1, dq0,
+ CLKDIV, srint, rst,
+ SHO);
+
+input dq3, dq2, dq1, dq0;
+
+input CLKDIV, srint, rst;
+
+output SHO;
+
+
+reg shr;
+
+reg SHO;
+
+
+wire clkint;
+
+wire error;
+
+wire rst_in, rst_self_heal;
+
+
+// Programmable Points
+
+wire [4:0] SELFHEAL;
+assign SELFHEAL = 5'b00000;
+
+
+
+//////////////////////////////////////////////////
+// Delay values
+//
+parameter FFD = 10; // clock to out delay for flip flops
+// driven by clk
+parameter FFCD = 10; // clock to out delay for flip flops
+// driven by clkdiv
+parameter MXD = 10; // 60 ps mux delay
+
+parameter MXR1 = 10;
+
+
+
+/////////////////////////////////////////
+
+
+assign clkint = CLKDIV & SELFHEAL[4];
+
+assign error = (((~SELFHEAL[4] ^ SELFHEAL[3]) ^ dq3) | ((~SELFHEAL[4] ^ SELFHEAL[2]) ^ dq2) | ((~SELFHEAL[4] ^ SELFHEAL[1]) ^ dq1) | ((~SELFHEAL[4] ^ SELFHEAL[0]) ^ dq0));
+
+assign rst_in = (~SELFHEAL[4] | ~srint);
+
+assign rst_self_heal = (rst | ~shr);
+
+/////////////////////////////////////////
+// Reset Flop
+////////////////////////////////////////
+
+always @ (posedge clkint or posedge rst)
+begin
+ begin
+ if (rst)
+ begin
+ shr <= # FFD 1'b0;
+ end
+ else begin
+ shr <= #FFD rst_in;
+ end
+ end
+end
+
+// Self heal flop
+always @ (posedge clkint or posedge rst_self_heal)
+begin
+ begin
+
+ if (rst_self_heal)
+ begin
+ SHO <= 1'b0;
+ end
+ else
+ begin
+ SHO <= # FFD error;
+ end
+ end
+end
+
+
+
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module plg_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+//
+// Programmable Load Generator (PLG)
+// Divide by 2-8 counter with load enable output
+//
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+// c23: Selects between divide by 2 or 3
+// c45: Selects between divide by 4 or 5
+// c67: Selects between divide by 6 or 7
+// sel: Selects which divide function is chosen
+// 00:2 or 3, 01:4 or 5, 10:6 or 7, 11:8
+// clk: High speed clock from DCM
+// clkdiv: Low speed clock from DCM
+// rst: Reset
+//
+//
+//
+// Outputs:
+//
+// load: Loads serdes register at terminal count
+//
+//
+// Test attributes:
+// INIT_LOADCNT: 4-bits to init counter
+// SRTYPE: 1-bit to control synchronous or asynchronous operation
+// SELFHEAL: 5-bits to control self healing feature
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module plg_oserdese1_vlog (c23, c45, c67, sel,
+ clk, clkdiv, rst,
+ load, IOCLK_GLITCH);
+
+input c23, c45, c67;
+
+input [1:0] sel;
+
+input clk, clkdiv, rst;
+
+output load;
+
+output IOCLK_GLITCH;
+
+wire SRTYPE;
+wire [3:0] INIT_LOADCNT;
+wire [4:0] SELFHEAL;
+assign SRTYPE = 1'b1;
+assign INIT_LOADCNT = 4'b0000;
+assign SELFHEAL = 5'b00000;
+
+reg q0, q1, q2, q3;
+
+reg qhr, qlr;
+
+reg load, mux;
+
+wire cntrrst;
+
+
+assign cntrrst = IOCLK_GLITCH | rst;
+
+
+
+// Parameters for gate delays
+parameter ffdcnt = 1;
+parameter mxdcnt = 1;
+parameter FFRST = 145; // clock to out delay for flop in PLSG
+
+
+
+//////////////////////////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ force q3 = INIT_LOADCNT[3];
+ force q2 = INIT_LOADCNT[2];
+ force q1 = INIT_LOADCNT[1];
+ force q0 = INIT_LOADCNT[0];
+ end
+ else
+ begin
+ release q3;
+ release q2;
+ release q1;
+ release q0;
+ end
+end
+
+
+
+
+
+
+
+// flops for counter
+// asynchronous reset
+always @ (posedge qhr or posedge clk)
+begin
+ if (qhr & !SRTYPE)
+ begin
+ q0 <= # ffdcnt 1'b0;
+ q1 <= # ffdcnt 1'b0;
+ q2 <= # ffdcnt 1'b0;
+ q3 <= # ffdcnt 1'b0;
+ end
+ else if (!SRTYPE)
+ begin
+ q3 <= # ffdcnt q2;
+ q2 <= # ffdcnt (!(!q0 & !q2) & q1);
+ q1 <= # ffdcnt q0;
+ q0 <= # ffdcnt mux;
+ end
+end
+// synchronous reset
+always @ (posedge clk)
+begin
+ if (qhr & SRTYPE)
+ begin
+ q0 <= # ffdcnt 1'b0;
+ q1 <= # ffdcnt 1'b0;
+ q2 <= # ffdcnt 1'b0;
+ q3 <= # ffdcnt 1'b0;
+ end
+ else if (SRTYPE)
+ begin
+ q3 <= # ffdcnt q2;
+ q2 <= # ffdcnt (!(!q0 & !q2) & q1);
+ q1 <= # ffdcnt q0;
+ q0 <= # ffdcnt mux;
+ end
+end
+
+
+// mux settings for counter
+always @ (sel or c23 or c45 or c67 or q0 or q1 or q2 or q3)
+ begin
+ case (sel)
+ 2'b00: mux <= # mxdcnt (!q0 & !(c23 & q1));
+ 2'b01: mux <= # mxdcnt (!q1 & !(c45 & q2));
+ 2'b10: mux <= # mxdcnt (!q2 & !(c67 & q3));
+ 2'b11: mux <= # mxdcnt !q3;
+ default: mux <= # mxdcnt 1'b0;
+ endcase
+ end
+
+
+// mux decoding for load signal
+always @ (sel or c23 or c45 or c67 or q0 or q1 or q2 or q3)
+ begin
+ case (sel)
+ 2'b00: load <= # mxdcnt q0;
+ 2'b01: load <= # mxdcnt q0 & q1;
+ 2'b10: load <= # mxdcnt q0 & q2;
+ 2'b11: load <= # mxdcnt q0 & q3;
+ default: load <= # mxdcnt 1'b0;
+ endcase
+ end
+
+// flops to reset counter
+
+// Low speed flop
+// asynchronous reset
+always @ (posedge cntrrst or posedge clkdiv)
+ begin
+ if (cntrrst & !SRTYPE)
+ begin
+ qlr <= # FFRST 1'b1;
+ end
+ else if (!SRTYPE)
+ begin
+ qlr <= # FFRST 1'b0;
+ end
+ end
+// synchronous reset
+always @ (posedge clkdiv)
+ begin
+ if (cntrrst & SRTYPE)
+ begin
+ qlr <= # FFRST 1'b1;
+ end
+ else if (SRTYPE)
+ begin
+ qlr <= # FFRST 1'b0;
+ end
+ end
+
+
+
+// High speed flop
+// asynchronous reset
+always @ (posedge cntrrst or posedge clk)
+ begin
+ if (cntrrst & !SRTYPE)
+ begin
+ qhr <= # ffdcnt 1'b1;
+ end
+ else if (!SRTYPE)
+ begin
+ qhr <= # ffdcnt qlr;
+ end
+ end
+// synchronous reset
+always @ (posedge clk)
+ begin
+ if (cntrrst & SRTYPE)
+ begin
+ qhr <= # ffdcnt 1'b1;
+ end
+ else if (SRTYPE)
+ begin
+ qhr <= # ffdcnt qlr;
+ end
+ end
+
+selfheal_oserdese1_vlog fixcntr (.dq3(q3), .dq2(q2), .dq1(q1), .dq0(q0),
+ .CLKDIV(clkdiv), .srint(qlr), .rst(rst),
+ .SHO(IOCLK_GLITCH));
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module rank12d_oserdese1_vlog
+//
+//
+// This model ONLY works for SERDES operation!!
+// Does not include tristate circuit
+//
+//
+////////////////////////////////////////////////////////
+//
+// Inputs:
+// D1: Data input 1
+// D2: Data input 2
+// D3: Data input 3
+// D4: Data input 4
+// D5: Data input 5
+// D6: Data input 6
+// C: High speed clock from DCM
+// OCE: Clock enable for output data flops
+// SR: Set/Reset control. For the last 3 flops in OQ
+// (d1rnk2, d2rnk2 and d2nrnk2) this function is
+// controlled bythe attributes SRVAL_OQ. In SERDES mode,
+// SR is a RESET ONLY for all other flops! The flops will
+// still be RESET even if SR is programmed to a SET!
+// CLKDIV: Low speed divided clock from DCM
+// SHIFTIN1: Carry in data 1 for master from slave
+// SHIFTIN2: Carry in data 2 for master from slave
+//
+//
+//
+// Outputs:
+// data1: Data output mux for top flop
+// data2: Data output mux for bottom flop
+// SHIFTOUT1: Carry out data 1 for slave
+// SHIFTOUT2: Carry out data 2 for slave
+// load: Used for the tristate when combined into a single model
+//
+//
+//
+// Programmable Points
+// DATA_RATE_OQ: Rate control for data output, 1-bit
+// sdr (1), ddr (0)
+// DATA_WIDTH: Input data width,
+// 4-bits, values can be from 2 to 10
+// SERDES_MODE: Denotes master (0) or slave (1)
+// SIM_X_INPUT: This attribute is NOT SUPPORTED in this model!!!
+//
+//
+//
+// Programmable points for Test model
+// SRTYPE: This is a 4-bit field Sets asynchronous (0) or synchronous (1) set/reset
+// 1st bit (msb) sets rank1 flops, 2nd bit sets 4 flops in rank 2,
+// 3rd bit sets "3 legacy flops, and 4th (lsb) bit sets the counter
+// INIT_ORANK1: Init value for 6 registers in 1st rank (6-bits)
+// INIT_ORANK2_PARTIAL: Init value for bottom 4 registers in the 2nd rank (4-bits)
+// INIT_LOADCNT: Init value for the load counter (4-bits)
+// The other 2 registers in the load counter have init bits, but are
+// not supported in this model
+// SERDES: Indicates that SERDES mode is chosen
+// SLEFHEAL: 5-bit to set self heal circuit
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module rank12d_oserdese1_vlog (D1, D2, D3, D4, D5, D6, d2rnk2,
+ SHIFTIN1, SHIFTIN2,
+ C, CLKDIV, SR, OCE,
+ data1, data2, SHIFTOUT1, SHIFTOUT2,
+ DATA_RATE_OQ, DATA_WIDTH,
+ SERDES_MODE, load,
+ IOCLK_GLITCH,
+ INIT_OQ, SRVAL_OQ);
+
+input D1, D2, D3, D4, D5, D6;
+
+input d2rnk2;
+
+input SHIFTIN1, SHIFTIN2;
+
+input C, CLKDIV, SR, OCE;
+
+input INIT_OQ, SRVAL_OQ;
+
+output data1, data2;
+
+output SHIFTOUT1, SHIFTOUT2;
+
+output load;
+
+output IOCLK_GLITCH;
+
+// Programmable Points
+
+input DATA_RATE_OQ;
+
+input [3:0] DATA_WIDTH;
+
+input SERDES_MODE;
+
+wire DDR_CLK_EDGE, SERDES;
+wire [3:0] SRTYPE;
+wire [4:0] SELFHEAL;
+
+wire [3:0] INIT_ORANK2_PARTIAL;
+wire [5:0] INIT_ORANK1;
+
+assign DDR_CLK_EDGE = 1'b1;
+assign SERDES = 1'b1;
+assign SRTYPE = 4'b1111;
+assign SELFHEAL = 5'b00000;
+
+assign INIT_ORANK2_PARTIAL = 4'b0000;
+assign INIT_ORANK1 = 6'b000000;
+
+reg d1r, d2r, d3r, d4r, d5r, d6r;
+
+reg d3rnk2, d4rnk2, d5rnk2, d6rnk2;
+
+reg data1, data2, data3, data4, data5, data6;
+
+reg ddr_data, odata_edge, sdata_edge;
+
+reg c23, c45, c67;
+
+reg [1:0] sel;
+
+wire C2p, C3;
+
+wire loadint;
+
+wire [3:0] seloq;
+
+wire oqsr, oqrev;
+
+wire [2:0] sel1_4;
+
+wire [3:0] sel5_6;
+
+wire [4:0] plgcnt;
+
+assign C2p = (C & DDR_CLK_EDGE) | (!C & !DDR_CLK_EDGE);
+
+assign C3 = !C2p;
+
+assign plgcnt = {DATA_RATE_OQ,DATA_WIDTH};
+
+assign sel1_4 = {SERDES,loadint,DATA_RATE_OQ};
+
+assign sel5_6 = {SERDES,SERDES_MODE,loadint,DATA_RATE_OQ};
+
+assign load = loadint;
+
+assign seloq = {OCE,DATA_RATE_OQ,oqsr,oqrev};
+
+assign oqsr = !SRTYPE[1] & SR & !SRVAL_OQ;
+
+assign oqrev = !SRTYPE[1] & SR & SRVAL_OQ;
+
+
+
+//////////////////////////////////////////////////
+// Delay values
+//
+parameter FFD = 1; // clock to out delay for flip flops
+// driven by clk
+parameter FFCD = 1; // clock to out delay for flip flops
+// driven by clkdiv
+parameter MXD = 1; // 60 ps mux delay
+
+parameter MXR1 = 1;
+
+////////////////////////////////////////////
+// Initialization of flops with GSR for test model
+///////////////////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ force d6rnk2 = INIT_ORANK2_PARTIAL[3];
+ force d5rnk2 = INIT_ORANK2_PARTIAL[2];
+ force d4rnk2 = INIT_ORANK2_PARTIAL[1];
+ force d3rnk2 = INIT_ORANK2_PARTIAL[0];
+
+ force d6r = INIT_ORANK1[5];
+ force d5r = INIT_ORANK1[4];
+ force d4r = INIT_ORANK1[3];
+ force d3r = INIT_ORANK1[2];
+ force d2r = INIT_ORANK1[1];
+ force d1r = INIT_ORANK1[0];
+ end
+ else
+ begin
+ release d6rnk2;
+ release d5rnk2;
+ release d4rnk2;
+ release d3rnk2;
+ release d6r;
+ release d5r;
+ release d4r;
+ release d3r;
+ release d2r;
+ release d1r;
+ end
+end
+
+/////////////////////////////////////////
+
+
+
+// Assign shiftout1 and shiftout2
+
+assign SHIFTOUT1 = d3rnk2 & SERDES_MODE;
+
+assign SHIFTOUT2 = d4rnk2 & SERDES_MODE;
+
+
+
+
+
+
+// last 4 flops which only have reset and init
+// asynchronous operation
+always @ (posedge C or posedge SR)
+begin
+ begin
+ if (SR & !SRTYPE[2])
+ begin
+ d3rnk2 <= # FFD 1'b0;
+ d4rnk2 <= # FFD 1'b0;
+ d5rnk2 <= # FFD 1'b0;
+ d6rnk2 <= # FFD 1'b0;
+ end
+ else if (!SRTYPE[2])
+ begin
+ d3rnk2 <= # FFD data3;
+ d4rnk2 <= # FFD data4;
+ d5rnk2 <= # FFD data5;
+ d6rnk2 <= # FFD data6;
+
+ end
+ end
+end
+// synchronous operation
+always @ (posedge C)
+begin
+ begin
+ if (SR & SRTYPE[2])
+ begin
+ d3rnk2 <= # FFD 1'b0;
+ d4rnk2 <= # FFD 1'b0;
+ d5rnk2 <= # FFD 1'b0;
+ d6rnk2 <= # FFD 1'b0;
+ end
+ else if (SRTYPE[2])
+ begin
+ d3rnk2 <= # FFD data3;
+ d4rnk2 <= # FFD data4;
+ d5rnk2 <= # FFD data5;
+ d6rnk2 <= # FFD data6;
+
+ end
+ end
+end
+
+
+
+
+
+
+
+///////////////////////////////////////////////////
+// First rank of flops for input data
+//////////////////////////////////////////////////
+
+// asynchronous operation
+always @ (posedge CLKDIV or posedge SR)
+begin
+ begin
+ if (SR & !SRTYPE[3])
+ begin
+ d1r <= # FFCD 1'b0;
+ d2r <= # FFCD 1'b0;
+ d3r <= # FFCD 1'b0;
+ d4r <= # FFCD 1'b0;
+ d5r <= # FFCD 1'b0;
+ d6r <= # FFCD 1'b0;
+ end
+ else if (!SRTYPE[3])
+ begin
+ d1r <= # FFCD D1;
+ d2r <= # FFCD D2;
+ d3r <= # FFCD D3;
+ d4r <= # FFCD D4;
+ d5r <= # FFCD D5;
+ d6r <= # FFCD D6;
+
+ end
+ end
+end
+// synchronous operation
+always @ (posedge CLKDIV)
+begin
+ begin
+ if (SR & SRTYPE[3])
+ begin
+ d1r <= # FFCD 1'b0;
+ d2r <= # FFCD 1'b0;
+ d3r <= # FFCD 1'b0;
+ d4r <= # FFCD 1'b0;
+ d5r <= # FFCD 1'b0;
+ d6r <= # FFCD 1'b0;
+ end
+ else if (SRTYPE[3])
+ begin
+ d1r <= # FFCD D1;
+ d2r <= # FFCD D2;
+ d3r <= # FFCD D3;
+ d4r <= # FFCD D4;
+ d5r <= # FFCD D5;
+ d6r <= # FFCD D6;
+
+ end
+ end
+end
+
+// Muxs for 2nd rank of flops
+always @ (sel1_4 or d1r or d2rnk2 or d3rnk2)
+ begin
+
+ casex (sel1_4)
+ 3'b100: data1 <= # MXR1 d3rnk2;
+ 3'b110: data1 <= # MXR1 d1r;
+ 3'b101: data1 <= # MXR1 d2rnk2;
+ 3'b111: data1 <= # MXR1 d1r;
+ default: data1 <= # MXR1 d3rnk2;
+ endcase
+ end
+
+always @ (sel1_4 or d2r or d3rnk2 or d4rnk2)
+ begin
+ casex (sel1_4)
+ 3'b100: data2 <= # MXR1 d4rnk2;
+ 3'b110: data2 <= # MXR1 d2r;
+ 3'b101: data2 <= # MXR1 d3rnk2;
+ 3'b111: data2 <= # MXR1 d2r;
+ default: data2 <= # MXR1 d4rnk2;
+ endcase
+ end
+
+//Note: To stop data rate of 00 from being illegal, register data is fed to mux
+always @ (sel1_4 or d3r or d4rnk2 or d5rnk2)
+ begin
+ casex (sel1_4)
+ 3'b100: data3 <= # MXR1 d5rnk2;
+ 3'b110: data3 <= # MXR1 d3r;
+ 3'b101: data3 <= # MXR1 d4rnk2;
+ 3'b111: data3 <= # MXR1 d3r;
+ default: data3 <= # MXR1 d5rnk2;
+ endcase
+ end
+
+always @ (sel1_4 or d4r or d5rnk2 or d6rnk2)
+ begin
+ casex (sel1_4)
+ 3'b100: data4 <= # MXR1 d6rnk2;
+ 3'b110: data4 <= # MXR1 d4r;
+ 3'b101: data4 <= # MXR1 d5rnk2;
+ 3'b111: data4 <= # MXR1 d4r;
+ default: data4 <= # MXR1 d6rnk2;
+ endcase
+ end
+
+always @ (sel5_6 or d5r or d6rnk2 or SHIFTIN1)
+ begin
+ casex (sel5_6)
+ 4'b1000: data5 <= # MXR1 SHIFTIN1;
+ 4'b1010: data5 <= # MXR1 d5r;
+ 4'b1001: data5 <= # MXR1 d6rnk2;
+ 4'b1011: data5 <= # MXR1 d5r;
+ 4'b1100: data5 <= # MXR1 1'b0;
+ 4'b1110: data5 <= # MXR1 d5r;
+ 4'b1101: data5 <= # MXR1 d6rnk2;
+ 4'b1111: data5 <= # MXR1 d5r;
+ default: data5 <= # MXR1 SHIFTIN1;
+ endcase
+ end
+
+always @ (sel5_6 or D6 or d6r or SHIFTIN1 or SHIFTIN2)
+ begin
+ casex (sel5_6)
+ 4'b1000: data6 <= # MXR1 SHIFTIN2;
+ 4'b1010: data6 <= # MXR1 d6r;
+ 4'b1001: data6 <= # MXR1 SHIFTIN1;
+ 4'b1011: data6 <= # MXR1 d6r;
+ 4'b1100: data6 <= # MXR1 1'b0;
+ 4'b1110: data6 <= # MXR1 d6r;
+ 4'b1101: data6 <= # MXR1 1'b0;
+ 4'b1111: data6 <= # MXR1 d6r;
+ default: data6 <= # MXR1 SHIFTIN2;
+ endcase
+ end
+
+
+
+
+// instantiate programmable load generator
+plg_oserdese1_vlog ldgen (.c23(c23), .c45(c45), .c67(c67), .sel(sel),
+ .clk(C), .clkdiv(CLKDIV), .rst(SR),
+ .load(loadint), .IOCLK_GLITCH(IOCLK_GLITCH));
+
+// Set value of counter in programmable load generator
+always @ (plgcnt or c23 or c45 or c67 or sel)
+begin
+ casex (plgcnt)
+ 5'b00100: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b00; end
+ 5'b00110: begin c23=1'b1; c45=1'b0; c67=1'b0; sel=2'b00; end
+ 5'b01000: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b01; end
+ 5'b01010: begin c23=1'b0; c45=1'b1; c67=1'b0; sel=2'b01; end
+ 5'b10010: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b00; end
+ 5'b10011: begin c23=1'b1; c45=1'b0; c67=1'b0; sel=2'b00; end
+ 5'b10100: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b01; end
+ 5'b10101: begin c23=1'b0; c45=1'b1; c67=1'b0; sel=2'b01; end
+ 5'b10110: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b10; end
+ 5'b10111: begin c23=1'b0; c45=1'b0; c67=1'b1; sel=2'b10; end
+ 5'b11000: begin c23=1'b0; c45=1'b0; c67=1'b0; sel=2'b11; end
+ default: $display("DATA_WIDTH %b and DATA_RATE_OQ %b at %t is an illegal value", DATA_WIDTH, DATA_RATE_OQ, $time);
+ endcase
+end
+
+endmodule
+`timescale 1ps/1ps
+//////////////////////////////////////////////////////////
+//
+// module trif_oserdese1_vlog
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+//
+// T1, T2, T3, T4: tristate inputs
+// load: Programmable load generator output
+// TCE: Tristate clock enable
+// SR: Set/Reset control. For the last 3 flops in TQ
+// (qt1, qt2 and qt2n) this function is
+// controlled bythe attributes SRVAL_TQ. In SERDES mode,
+// SR is a RESET ONLY for all other flops! The flops will
+// still be RESET even if SR is programmed to a SET!
+// C, C2: High speed clocks
+// C2 drives 2nd latch and C3 (inverse of C2) drives
+// 3rd latch in output section
+// CLKDIV: Low speed clock
+//
+//
+//
+//
+// Outputs:
+//
+// TQ: Output of tristate mux
+//
+//
+// Programmable Options:
+//
+// DATA_RATE_TQ: 2-bit field for types of operaiton
+// 0 (buf from T1), 1 (registered output from T1), 2 (ddr)
+// TRISTATE_WIDTH: 2-bit field for input width
+// 0 (width 1), 1 (width 2), 2 (width 4)
+// INIT_TQ: Init TQ output (0,1)
+// SRVAL_TQ: This bit to controls value of SR input.
+// Only the last 3 flops (qt1, qt2 and qt2n) are
+// affected by this bit.For SERDES mode, this bit
+// should be set to '0' making SR a reset. This is the
+// desired state since all other flops only
+// respond to this pin as a reset. Their function
+// cannot be changed. SR is 'O' for SET and '1' for RESET.
+//
+//
+// Programmable Test Options:
+// SRTYPE: Control S and R as asynchronous (0) or synchronous (1)
+// 2-bit value. 1st bit (msb) controls the 4 input flops
+// and the 2nd bit (lsb) controls the "3 legacy flops"
+// DDR_CLK_EDGE: Same or opposite edge operation
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module trif_oserdese1_vlog (T1, T2, T3, T4, load,
+ C, CLKDIV, SR, TCE,
+ DATA_RATE_TQ, TRISTATE_WIDTH,
+ INIT_TQ, SRVAL_TQ,
+ data1, data2);
+
+input T1, T2, T3, T4, load;
+
+input C, CLKDIV, SR, TCE;
+
+input [1:0] TRISTATE_WIDTH;
+
+input [1:0] DATA_RATE_TQ;
+
+input INIT_TQ, SRVAL_TQ;
+
+output data1, data2;
+
+wire DDR_CLK_EDGE;
+wire [3:0] INIT_TRANK1;
+wire [1:0] SRTYPE;
+assign SRTYPE = 2'b11;
+assign DDR_CLK_EDGE = 1'b1;
+assign INIT_TRANK1 = 4'b0000;
+
+reg t1r, t2r, t3r, t4r;
+
+reg qt1, qt2, qt2n;
+
+reg data1, data2;
+
+reg sdata_edge, odata_edge, ddr_data;
+
+wire C2p, C3;
+
+wire load;
+
+wire [6:0] tqsel;
+
+wire [4:0] sel;
+
+assign sel = {load,DATA_RATE_TQ,TRISTATE_WIDTH};
+
+
+
+
+
+//////////////////////////////////////////////////
+
+
+// Parameters for gate delays
+parameter ffd = 1;
+parameter mxd = 1;
+
+
+/////////////////////////////
+// Initialization of Flops
+////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ force t1r = INIT_TRANK1[0];
+ force t2r = INIT_TRANK1[1];
+ force t3r = INIT_TRANK1[2];
+ force t4r = INIT_TRANK1[3];
+
+ end
+ else
+ begin
+ release t1r;
+ release t2r;
+ release t3r;
+ release t4r;
+ end
+end
+
+
+
+
+// First rank of flops
+// asynchronous reset operation
+always @ (posedge CLKDIV or posedge SR)
+begin
+ begin
+ if (SR & !SRTYPE[1])
+ begin
+ t1r <= # ffd 1'b0;
+ t2r <= # ffd 1'b0;
+ t3r <= # ffd 1'b0;
+ t4r <= # ffd 1'b0;
+ end
+ else if (!SRTYPE[1])
+ begin
+ t1r <= # ffd T1;
+ t2r <= # ffd T2;
+ t3r <= # ffd T3;
+ t4r <= # ffd T4;
+ end
+ end
+end
+
+// synchronous reset operation
+always @ (posedge CLKDIV)
+begin
+ begin
+ if (SR & SRTYPE[1])
+ begin
+ t1r <= # ffd 1'b0;
+ t2r <= # ffd 1'b0;
+ t3r <= # ffd 1'b0;
+ t4r <= # ffd 1'b0;
+ end
+ else if (SRTYPE[1])
+ begin
+ t1r <= # ffd T1;
+ t2r <= # ffd T2;
+ t3r <= # ffd T3;
+ t4r <= # ffd T4;
+ end
+ end
+end
+
+
+
+
+
+// Data Muxs for tristate otuput signals
+always @ (sel or T1 or t1r or t3r)
+ begin
+
+ casex (sel)
+ 5'b00000: data1 <= # mxd T1;
+ 5'b10000: data1 <= # mxd T1;
+ 5'bX0000: data1 <= # mxd T1;
+ 5'b00100: data1 <= # mxd T1;
+ 5'b10100: data1 <= # mxd T1;
+ 5'bX0100: data1 <= # mxd T1;
+ 5'b01001: data1 <= # mxd T1;
+ 5'b11001: data1 <= # mxd T1;
+ 5'b01010: data1 <= # mxd t3r;
+ 5'b11010: data1 <= # mxd t1r;
+// CR 551953 -- enabled TRISTATE_WIDTH to be 1 in DDR mode. No func change, but removed warnings
+ 5'b01000: ;
+ 5'b11000: ;
+ 5'bX1000: ;
+
+ default:
+ begin
+ $display("DATA_RATE_TQ %b and/or TRISTATE_WIDTH %b at time %t are not supported by OSERDES", DATA_RATE_TQ,TRISTATE_WIDTH,$time);
+ $display("1.sel= %b",sel);
+ end
+ endcase
+ end
+// For data 2, width of 1 is inserted as acceptable for buf and sdr
+// The capability exists in the device if the feature is added
+always @ (sel or T2 or t2r or t4r)
+ begin
+ casex (sel)
+ 5'b00000: data2 <= # mxd T2;
+ 5'b00100: data2 <= # mxd T2;
+ 5'b10000: data2 <= # mxd T2;
+ 5'b10100: data2 <= # mxd T2;
+ 5'bX0000: data2 <= # mxd T2;
+ 5'bX0100: data2 <= # mxd T2;
+ 5'b00X00: data2 <= # mxd T2;
+ 5'b10X00: data2 <= # mxd T2;
+ 5'bX0X00: data2 <= # mxd T2;
+ 5'b01001: data2 <= # mxd T2;
+ 5'b11001: data2 <= # mxd T2;
+ 5'bX1001: data2 <= # mxd T2;
+ 5'b01010: data2 <= # mxd t4r;
+ 5'b11010: data2 <= # mxd t2r;
+// CR 551953 -- enabled TRISTATE_WIDTH to be 1 in DDR mode. No func change, but removed warnings
+ 5'b01000: ;
+ 5'b11000: ;
+ 5'bX1000: ;
+
+ default:
+ begin
+ $display("DATA_RATE_TQ %b and/or TRISTATE_WIDTH %b at time %t are not supported by OSERDES", DATA_RATE_TQ,TRISTATE_WIDTH,$time);
+ $display("2.sel= %b",sel);
+ end
+ endcase
+ end
+
+
+endmodule
+`timescale 1ps/1ps
+//////////////////////////////////////////////////////////
+//
+// module txbuffer_oserdese1_vlog
+//
+/////////////////////////////////////////////////////////
+//
+// FIFO and Control circuit for OSERDES
+
+module txbuffer_oserdese1_vlog (iodelay_state, qmux1, qmux2, tmux1, tmux2,
+ d1, d2, t1, t2, trif,
+ WC, ODV, extra,
+ clk, clkdiv, bufo, bufop, rst,
+ ODELAY_USED, DDR3_DATA,
+ DDR3_MODE);
+
+input d1, d2, t1, t2;
+
+input trif;
+
+input WC, ODV;
+
+input rst;
+
+input clk, clkdiv, bufo, bufop;
+
+input ODELAY_USED, DDR3_DATA;
+
+input DDR3_MODE;
+
+output iodelay_state, extra;
+
+output qmux1, qmux2, tmux1, tmux2;
+
+wire WC_DELAY;
+assign WC_DELAY = 1'b0;
+
+wire rd_gap1;
+
+wire rst_bufo_p, rst_bufg_p;
+
+
+wire rst_bufo_rc, rst_bufg_wc, rst_cntr, rst_bufop_rc;
+
+wire [1:0] qwc, qrd;
+
+wire bufo_out;
+
+
+fifo_tdpipe_oserdese1_vlog data1 (.muxout(inv_qmux1), .din(~d1), .qwc(qwc), .qrd(qrd),
+ .rd_gap1(rd_gap1),
+ .bufg_clk(clk), .bufo_clk(bufo), .rst_bufo_p(rst_bufo_p), .rst_bufg_p(rst_bufg_p),
+ .DDR3_DATA(DDR3_DATA), .extra(extra), .ODV(ODV), .DDR3_MODE(DDR3_MODE)
+
+ );
+
+fifo_tdpipe_oserdese1_vlog data2 (.muxout(inv_qmux2), .din(~d2), .qwc(qwc), .qrd(qrd),
+ .rd_gap1(rd_gap1),
+ .bufg_clk(clk), .bufo_clk(bufo), .rst_bufo_p(rst_bufo_p), .rst_bufg_p(rst_bufg_p),
+ .DDR3_DATA(DDR3_DATA), .extra(extra), .ODV(ODV), .DDR3_MODE(DDR3_MODE)
+
+ );
+
+fifo_tdpipe_oserdese1_vlog tris1 (.muxout(inv_tmux1), .din(~t1), .qwc(qwc), .qrd(qrd),
+ .rd_gap1(rd_gap1),
+ .bufg_clk(clk), .bufo_clk(bufo), .rst_bufo_p(rst_bufo_p), .rst_bufg_p(rst_bufg_p),
+ .DDR3_DATA(DDR3_DATA), .extra(extra), .ODV(ODV), .DDR3_MODE(DDR3_MODE)
+
+ );
+
+fifo_tdpipe_oserdese1_vlog tris2 (.muxout(inv_tmux2), .din(~t2), .qwc(qwc), .qrd(qrd),
+ .rd_gap1(rd_gap1),
+ .bufg_clk(clk), .bufo_clk(bufo), .rst_bufo_p(rst_bufo_p), .rst_bufg_p(rst_bufg_p),
+ .DDR3_DATA(DDR3_DATA), .extra(extra), .ODV(ODV), .DDR3_MODE(DDR3_MODE)
+
+ );
+
+wire qmux1 = ~inv_qmux1;
+wire qmux2 = ~inv_qmux2;
+wire tmux1 = ~inv_tmux1;
+wire tmux2 = ~inv_tmux2;
+
+fifo_reset_oserdese1_vlog rstckt (.rst_bufo_p(rst_bufo_p), .rst_bufo_rc(rst_bufo_rc),
+ .rst_bufg_p(rst_bufg_p), .rst_bufg_wc(rst_bufg_wc),
+ .rst_cntr(rst_cntr),
+ .bufg_clk(clk), .bufo_clk(bufo), .clkdiv(clkdiv), .rst(rst),
+ .divide_2(WC_DELAY), .bufop_clk(bufop), .rst_bufop_rc(rst_bufop_rc)
+
+ );
+
+
+
+
+fifo_addr_oserdese1_vlog addcntr (.qwc(qwc), .qrd(qrd), .rd_gap1(rd_gap1), .rst_bufg_wc(rst_bufg_wc), .rst_bufo_rc(rst_bufo_rc), .bufg_clk(clk), .bufo_clk(bufo),
+ .data(DDR3_DATA), .extra(extra), .rst_bufop_rc(rst_bufop_rc), .bufop_clk(bufop)
+
+ );
+
+
+
+iodlyctrl_npre_oserdese1_vlog idlyctrl (.iodelay_state(iodelay_state), .bufo_out(bufo_out), .rst_cntr(rst_cntr),
+ .wc(WC), .trif(trif),
+ .rst(rst_bufg_p), .bufg_clk(clk), .bufo_clk(bufo), .bufg_clkdiv(clkdiv),
+ .ddr3_dimm(ODELAY_USED), .wl6(WC_DELAY)
+ );
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module fifo_tdpipe_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+
+// FIFO for write path
+
+module fifo_tdpipe_oserdese1_vlog (muxout, din, qwc, qrd,
+ rd_gap1,
+ bufg_clk, bufo_clk, rst_bufo_p, rst_bufg_p,
+ DDR3_DATA, extra, ODV, DDR3_MODE
+
+ );
+
+
+input din;
+
+input [1:0] qwc, qrd;
+
+input rd_gap1;
+
+input rst_bufo_p, rst_bufg_p;
+
+input bufg_clk, bufo_clk;
+
+input DDR3_DATA, ODV;
+
+input extra;
+
+input DDR3_MODE;
+
+output muxout;
+
+
+reg muxout;
+
+reg qout1, qout2;
+
+reg qout_int, qout_int2;
+
+reg [4:1] fifo;
+
+reg cin1;
+
+reg omux;
+
+wire [2:0] sel;
+
+reg pipe1, pipe2;
+
+wire selqoi, selqoi2;
+
+wire [2:0] selmuxout;
+
+
+
+
+
+
+// 4 flops that make up the basic FIFO. They are all clocked
+// off of fast BUFG. The first flop is the top flop in the chain.
+// The CE input is used to mux the inputs. If the flop is selected,
+// CE is high and it takes data from the output of the mux. If the
+// flop is not selected, it retains its data.
+
+always @ (posedge bufg_clk or posedge rst_bufg_p)
+ begin
+ if (rst_bufg_p)
+ begin
+ fifo <= #10 4'b0000;
+ end
+ else if (!qwc[1] & !qwc[0])
+ begin
+ fifo <= #10 {fifo[4:2],din};
+ end
+ else if (!qwc[1] & qwc[0])
+ begin
+ fifo <= #10 {fifo[4:3],din,fifo[1]};
+ end
+ else if (qwc[1] & qwc[0])
+ begin
+ fifo <= #10 {fifo[4],din,fifo[2:1]};
+ end
+ else if (qwc[1] & !qwc[0])
+ begin
+ fifo <= #10 {din,fifo[3:1]};
+ end
+ end
+
+
+
+// Capture stage top
+// This is the top flop of the "3 flops" for ODDR. This flop, along with the read
+// counter will be clocked off of bufo. A 4:1 mux wil decode the outputs of the
+// read counter and load the write data. A subsequent 2:1 mux will decode between
+// the fifo and the legacy operation
+
+
+// OMUX
+
+always @ (qrd or fifo)
+ begin
+ case (qrd)
+ 2'b00: omux <= #10 fifo[1];
+ 2'b01: omux <= #10 fifo[2];
+ 2'b10: omux <= #10 fifo[4];
+ 2'b11: omux <= #10 fifo[3];
+ default: omux <= #10 fifo[1];
+ endcase
+ end
+
+
+always @ (posedge bufo_clk or posedge rst_bufo_p)
+ begin
+ if (rst_bufo_p)
+ begin
+ qout_int <= #10 1'b0;
+ qout_int2 <= #10 1'b0;
+ end
+ else
+ begin
+ qout_int <= #10 omux;
+ qout_int2 <= #10 qout_int;
+ end
+ end
+
+assign #10 selqoi = ODV | rd_gap1;
+
+
+always @ (selqoi or qout_int or omux)
+ begin
+ case(selqoi)
+ 1'b0: qout1 <= #10 omux;
+ 1'b1: qout1 <= #10 qout_int;
+ default: qout1 <= #10 omux;
+ endcase
+ end
+
+assign #10 selqoi2 = ODV & rd_gap1;
+
+always @ (selqoi2 or qout_int2 or qout_int)
+ begin
+ case(selqoi2)
+ 1'b0: qout2 <= #10 qout_int;
+ 1'b1: qout2 <= #10 qout_int2;
+ default qout2 <= #10 qout_int;
+ endcase
+ end
+
+
+assign #14 selmuxout = {DDR3_MODE,DDR3_DATA,extra};
+
+
+always @ (selmuxout or din or omux or qout1 or qout2)
+ begin
+ case (selmuxout)
+ 3'b000: muxout = #1 din;
+ 3'b001: muxout = #1 din;
+ 3'b010: muxout = #1 din;
+ 3'b011: muxout = #1 din;
+ 3'b100: muxout = #1 omux;
+ 3'b101: muxout = #1 omux;
+ 3'b110: muxout = #1 qout1;
+ 3'b111: muxout = #1 qout2;
+ default: muxout = #10 din;
+ endcase
+ end
+
+
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module fifo_reset_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+//
+// TX FIFO reset
+//
+// This design performs 2 functions. One function is to reset all the
+// flops in the TX FIFO. The other function is to respond to the signal
+// rst_cntr. This signal comes from iodlyctrl and will be used to initiate an
+// orderly transition to switch the DQ/DQS I/O from and read to a write.
+// This process is required only for DDR3 DIMM support because the IODELAY
+// is used for both the inputs and the outputs. The signal from the
+// squelch circuit is a present fabric output. An additional input
+// indicating that a write command was issued will be
+// required for all I/O to support this signal.
+//
+// This design uses an asynchronous reset to reset all flops. After the
+// reset is disabled, a 0 is propagated through the pipe stages to terminate
+// the reset. The first 2 flops run off of the clkdiv domain. Their output
+// feeds a latch to cross between the clkdiv and bufg_clk domain. The pipe
+// stage for the bufg_clk domain is 3 deep, where the last flop is the
+// reset signal for the bufg_clk domain. The 2nd flop of the bufg_clk pipe
+// is fed to 2 flops that are in the bufo_clk domain. The 2 flops are
+// to resolve metastability between the 2 clock domains.
+//
+// The circuit to enable an orderly transition from read to write uses the
+// PREAMBLE_SYNCHED output of a portion of the squelch circuit. This pulse
+// will initiate the reset sequence and also generate an enable which will
+// switch the IODELAY from an IDELAY to an ODELAY. Timing is as specified in
+// the "State of the Union" presentation.
+//
+//
+
+
+module fifo_reset_oserdese1_vlog (rst_bufo_p, rst_bufo_rc,
+ rst_bufg_p, rst_bufg_wc,
+ rst_cntr,
+ bufg_clk, bufo_clk, clkdiv, rst,
+ divide_2, bufop_clk, rst_bufop_rc
+
+ );
+
+
+input rst_cntr;
+
+input rst;
+
+input bufg_clk, bufo_clk, clkdiv;
+
+input bufop_clk;
+
+
+// Memory cell input to support divide by 1 operation
+input divide_2;
+
+
+output rst_bufo_p, rst_bufo_rc;
+output rst_bufg_p, rst_bufg_wc;
+
+output rst_bufop_rc;
+
+
+reg [1:0] clkdiv_pipe;
+
+reg bufg_pipe;
+
+reg rst_cntr_reg;
+
+reg [2:0] bufo_rst_p, bufo_rst_rc;
+
+reg [1:0] bufop_rst_rc;
+
+reg [1:0] bufg_rst_p, bufg_rst_wc;
+
+wire bufg_clkdiv_latch, ltint1, ltint2, ltint3;
+
+wire latch_in;
+
+
+
+
+
+
+
+// 2 stage pipe for clkdiv domain to allow user to properly
+// time everything
+
+
+always @ (posedge bufg_clk or posedge rst)
+ begin
+ if (rst)
+ begin
+ rst_cntr_reg <= #10 1'b0;
+ end
+ else
+ begin
+ rst_cntr_reg <= #10 rst_cntr;
+ end
+ end
+
+
+always @ (posedge clkdiv or posedge rst)
+ begin
+ if (rst)
+ begin
+ clkdiv_pipe <= #10 2'b11;
+ end
+ else
+ begin
+ clkdiv_pipe <= #10 {clkdiv_pipe[0],1'b0};
+ end
+ end
+
+// Latch to compensate for clkdiv and bufg_clk clock skew
+// Built of actual gates
+
+assign #1 latch_in = clkdiv_pipe[1];
+
+assign #1 bufg_clkdiv_latch = !(ltint1 && ltint3);
+assign #1 ltint1 = !(latch_in && bufg_clk);
+assign #1 ltint2 = !(ltint1 && bufg_clk);
+assign #1 ltint3 = !(bufg_clkdiv_latch && ltint2);
+
+
+
+
+
+// BUFG flop to register latch signal
+always @ (posedge bufg_clk or posedge rst)
+ begin
+ if (rst)
+ begin
+ bufg_pipe <= #10 1'b1;
+ end
+ else
+ begin
+ bufg_pipe <= #10 bufg_clkdiv_latch;
+ end
+ end
+
+
+
+
+// BUFG clock domain resests
+
+always @ (posedge bufg_clk or posedge rst)
+ begin
+ if (rst)
+ begin
+ bufg_rst_p <= #10 2'b11;
+ end
+ else
+ begin
+ bufg_rst_p <= #10 {bufg_rst_p[0],bufg_pipe};
+ end
+ end
+
+
+always @ (posedge bufg_clk or posedge rst_cntr or posedge rst)
+ begin
+ if (rst || rst_cntr)
+ begin
+ bufg_rst_wc <= #10 2'b11;
+ end
+ else
+ begin
+ bufg_rst_wc <= #10 {bufg_rst_wc[0],bufg_pipe};
+ end
+ end
+
+
+
+// BUFO clock domain Resets
+always @ (posedge bufo_clk or posedge rst)
+ begin
+ if (rst)
+ begin
+ bufo_rst_p <= #10 3'b111;
+ end
+ else
+ begin
+ bufo_rst_p <= #10 {bufo_rst_p[1:0],bufg_pipe};
+ end
+ end
+
+always @ (posedge bufo_clk or posedge rst or posedge rst_cntr)
+ begin
+ if (rst || rst_cntr)
+ begin
+ bufo_rst_rc <= #10 3'b111;
+ end
+ else
+ begin
+ bufo_rst_rc <= #10 {bufo_rst_rc[1:0],bufg_pipe};
+ end
+ end
+
+
+
+always @ (posedge bufop_clk or posedge rst or posedge rst_cntr)
+ begin
+ if (rst || rst_cntr)
+ begin
+ bufop_rst_rc <= #10 2'b11;
+ end
+ else
+ begin
+ bufop_rst_rc <= #10 {bufop_rst_rc[0],bufg_pipe};
+ end
+ end
+
+
+// final reset assignments
+assign rst_bufo_rc = bufo_rst_rc[1];
+
+assign rst_bufo_p = bufo_rst_p[1];
+
+assign rst_bufop_rc = bufop_rst_rc[1];
+
+assign rst_bufg_wc = bufg_rst_wc[1];
+
+assign rst_bufg_p = bufg_rst_p[1];
+
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module fifo_addr_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+// Read and Write address generators for TX FIFO
+//
+// This circuit contains 2 greycode read and write address generators
+// that will be used with the TX FIFO. Both counters generate a
+// count sequence of 00 -> 01 -> 11 -> 10 -> 00.
+
+
+
+module fifo_addr_oserdese1_vlog (qwc, qrd, rd_gap1, rst_bufg_wc, rst_bufo_rc, bufg_clk, bufo_clk,
+ data, extra, rst_bufop_rc, bufop_clk
+
+ );
+
+
+input bufg_clk, bufo_clk;
+
+input rst_bufo_rc, rst_bufg_wc;
+
+input rst_bufop_rc;
+
+input data; // mc to tell if I/O is DDR3 DQ or DQS
+
+input bufop_clk;
+
+output [1:0]qwc, qrd; // Scalar port ``qwc'' has a vectored net declaration [1:0]
+
+output rd_gap1, extra;
+
+
+
+
+reg [1:0] qwc; // unisims/OSERDESE1.v:2073 error: Scalar port ``qwc'' has a vectored net declaration [1:0]
+
+reg [1:0] qrd; // unisims/OSERDESE1.v:2075: error: Scalar port ``qrd'' has a vectored net declaration [1:0]
+
+
+reg stop_rd, rd_gap1, extra;
+
+reg rd_cor, rd_cor_cnt, rd_cor_cnt1;
+
+
+wire qwc0_latch, qwc1_latch;
+
+wire li01, li02, li03;
+
+wire li11, li12, li13;
+
+
+wire qwc0_latchn, qwc1_latchn;
+
+wire li01n, li02n, li03n;
+
+wire li11n, li12n, li13n;
+
+
+reg stop_rdn, rd_cor_cntn, rd_cor_cnt1n, stop_rc;
+
+
+
+
+reg [1:0] qwcd;
+
+reg [1:0] qrdd;
+
+
+reg stop_rdd, rd_gap1d, extrad;
+
+reg rd_cord, rd_cor_cntd, rd_cor_cnt1d;
+
+
+wire qwcd0_latch, qwcd1_latch;
+
+wire li01d, li02d, li03d;
+
+wire li11d, li12d, li13d;
+
+
+
+// Write counter
+// The write counter uses 2 flops to create the grey code pattern of
+// 00 -> 01 -> 11 -> 10 -> 00. The write counter is initialized
+// to 11 and the read counter will be initialized to 00. This gives
+// a basic 2 clock separation to compensate for the phase differences.
+// The write counter is clocked off of the bufg clock
+
+always @ (posedge bufg_clk or posedge rst_bufg_wc)
+ begin
+ if (rst_bufg_wc)
+ begin
+ qwc <= # 10 2'b11;
+ end
+ else if (qwc[1] ^ qwc[0])
+ begin
+ qwc[1] <= # 10 ~qwc[1];
+ qwc[0] <= # 10 qwc[0];
+ end
+ else
+ begin
+ qwc[1] <= # 10 qwc[1];
+ qwc[0] <= # 10 ~qwc[0];
+ end
+ end
+
+
+
+
+
+
+// Read counter
+// The read counter uses 2 flops to create the grey code pattern of
+// 00 -> 01 -> 11 -> 10 -> 00. The read counter is initialized
+// to 00 and the write counter will be initialized to 11. This gives
+// a basic 2 clock separation to compensate for the phase differences.
+// The read counter is clocked off of the bufo clock
+
+always @ (posedge bufo_clk or posedge rst_bufo_rc)
+
+ begin
+ if (rst_bufo_rc)
+ begin
+ qrd <= # 10 2'b00;
+ end
+ else if (stop_rd && !data)
+ begin
+ qrd <= #10 qrd;
+ end
+ else if (qrd[1] ^ qrd[0])
+ begin
+ qrd[1] <= # 10 ~qrd[1];
+ qrd[0] <= # 10 qrd[0];
+ end
+ else
+ begin
+ qrd[1] <= # 10 qrd[1];
+ qrd[0] <= # 10 ~qrd[0];
+ end
+ end
+
+always @ (posedge bufo_clk or posedge rst_bufo_rc)
+
+ begin
+ if (rst_bufo_rc)
+ begin
+ rd_gap1 <= # 10 1'b0;
+ end
+// else if ((qwc1_latch && qwc0_latch) && (qrd[0] ^ qrd[1]))
+ else if ((qwc1_latch && qwc0_latch) && (qrd[0]))
+ begin
+ rd_gap1 <= # 10 1'b1;
+ end
+ else
+ begin
+ rd_gap1 <= # 10 rd_gap1;
+ end
+ end
+
+
+
+
+
+// Looking for 11
+
+assign #1 qwc0_latch = !(li01 & li03);
+assign #1 li01 = !(qwc[0] & bufo_clk);
+assign #1 li02 = !(li01 & bufo_clk);
+assign #1 li03 = !(qwc0_latch & li02);
+
+
+assign #1 qwc1_latch = !(li11 & li13);
+assign #1 li11 = !(qwc[1] & bufo_clk);
+assign #1 li12 = !(li11 & bufo_clk);
+assign #1 li13 = !(qwc1_latch & li12);
+
+
+// The following counter is to match the control counter to see if the
+// read counter did a hold after reset. This knowledge will enable the
+// computation of the 'extra' output. This in turn can add the
+// proper number of pipe stages to the output. The circuit must use
+// the output of BUFO and not be modified by ODELAY. This is because
+// the control pins PP clock was not modified by BUFO. If the
+// control pins PP clock was modified by BUFO, the reset must be done
+// with this in mind.
+
+// Read counter
+// The read counter uses 2 flops to create the grey code pattern of
+// 00 -> 01 -> 11 -> 10 -> 00. The read counter is initialized
+// to 00 and the write counter will be initialized to 11. This gives
+// a basic 2 clock separation to compensate for the phase differences.
+// The read counter is clocked off of the bufo clock
+
+always @ (posedge bufop_clk or posedge rst_bufop_rc)
+
+ begin
+ if (rst_bufop_rc)
+ begin
+ qrdd <= # 10 2'b00;
+ end
+ else if (qrdd[1] ^ qrdd[0])
+ begin
+ qrdd[1] <= # 10 ~qrdd[1];
+ qrdd[0] <= # 10 qrdd[0];
+ end
+ else
+ begin
+ qrdd[1] <= # 10 qrdd[1];
+ qrdd[0] <= # 10 ~qrdd[0];
+ end
+ end
+
+
+
+// Looking for 11
+
+assign #1 qwcd0_latch = !(li01d & li03d);
+assign #1 li01d = !(qwc[0] & bufop_clk);
+assign #1 li02d = !(li01d & bufop_clk);
+assign #1 li03d = !(qwcd0_latch & li02d);
+
+
+assign #1 qwcd1_latch = !(li11d & li13d);
+assign #1 li11d = !(qwc[1] & bufop_clk);
+assign #1 li12d = !(li11d & bufop_clk);
+assign #1 li13d = !(qwcd1_latch & li12d);
+
+
+
+// Circuit to fix read address counters in non data pins
+always @ (posedge bufop_clk or posedge rst_bufo_rc)
+
+ begin
+ if (rst_bufop_rc)
+ begin
+ stop_rd <= # 10 1'b0;
+ rd_cor_cnt <= #10 1'b0;
+ rd_cor_cnt1 <= #10 1'b0;
+ end
+ else if (((qwcd1_latch && qwcd0_latch) && (qrdd[0] ^ qrdd[1]) && !rd_cor_cnt1))
+ begin
+ stop_rd <= #10 1'b1;
+ rd_cor_cnt <= #10 1'b1;
+ rd_cor_cnt1 <= #10 rd_cor_cnt;
+ end
+ else
+ begin
+ stop_rd <= #10 1'b0;
+ rd_cor_cnt <= #10 1'b1;
+ rd_cor_cnt1 <= #10 rd_cor_cnt;
+ end
+ end
+
+// Circuit to inform data if control counters habe been fixed
+
+always @ (posedge bufop_clk or posedge rst_bufop_rc)
+ begin
+ if (rst_bufop_rc)
+ begin
+ extra <= #10 1'b0;
+ end
+ else if (stop_rd)
+ begin
+ extra <= #10 1'b1;
+ end
+ end
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// module iodlyctrl_npre_oserdese1_vlog
+//
+////////////////////////////////////////////////////////
+//
+// Circuit to automatically switch IODELAY from IDELAY to ODELAY using knowledge
+// of write command. This circuit forces the user to wait 3 extra CLK/CLK# cycles
+// when performing a read to write turnaround. The JEDEC DDR3 spec states that
+// the turnaround can be done in 2 clock cycles. This circuit requires 5 clock
+// cycles.
+// This circuit is only used for a DDR3 appplication that uses DIMMs
+
+
+
+module iodlyctrl_npre_oserdese1_vlog (iodelay_state, bufo_out, rst_cntr,
+ wc, trif,
+ rst, bufg_clk, bufo_clk, bufg_clkdiv,
+ ddr3_dimm, wl6
+ );
+
+
+input wc;
+
+input trif;
+
+input rst;
+
+input bufo_clk, bufg_clk, bufg_clkdiv;
+
+input ddr3_dimm, wl6;
+
+output iodelay_state, rst_cntr;
+
+output bufo_out;
+
+
+reg qw0cd, qw1cd;
+
+reg turn, turn_p1;
+
+reg rst_cntr;
+
+reg w_to_w;
+
+reg [2:0] wtw_cntr;
+
+reg cmd0, cmd0_n6, cmd0_6, cmd1;
+
+
+
+
+wire wr_cmd0;
+
+wire lt0int1, lt0int2, lt0int3;
+
+wire lt1int1, lt1int2, lt1int3;
+
+wire latch_in;
+
+reg qwcd;
+
+
+
+
+
+assign bufo_out = bufo_clk;
+
+
+// create turn signal for IODELAY
+assign iodelay_state = (trif && ~w_to_w) & ((~turn && ~turn_p1) || ~ddr3_dimm);
+
+
+
+// Registers to detect write command
+
+// Registers using bufg clkdiv
+always @ (posedge bufg_clkdiv)
+begin
+ if (rst)
+ begin
+ qwcd <= #10 0;
+ end
+ else
+ begin
+ qwcd <= #10 wc;
+ end
+end
+
+
+
+// Latch to allow skew between CLK and CLKDIV from BUFGs
+assign #1 wr_cmd0 = !(lt0int1 && lt0int3);
+assign #1 lt0int1 = !(qwcd && bufg_clk);
+assign #1 lt0int2 = !(lt0int1 && bufg_clk);
+assign #1 lt0int3 = !(wr_cmd0 && lt0int2);
+
+always @ (posedge bufg_clk)
+ begin
+ if (rst)
+ begin
+ cmd0_n6 <= #10 1'b0;
+ cmd0_6 <= #10 1'b0;
+ end
+ else
+ begin
+ cmd0_n6 <= #10 wr_cmd0;
+ cmd0_6 <= #10 cmd0_n6;
+ end
+ end
+
+
+
+// mux to add extra pipe stage for WL = 6
+always @ (cmd0_n6 or wl6 or cmd0_6)
+ begin
+ case (wl6)
+ 1'b0: cmd0 <= #10 cmd0_n6;
+ 1'b1: cmd0 <= #10 cmd0_6;
+ default: cmd0 <= #10 cmd0_n6;
+ endcase
+ end
+
+
+// Turn IODELAY and reset FIFO read/write counters
+//always @ (posedge bufg_clk)
+// begin
+// if (rst)
+//
+// begin
+// turn <= #10 1'b0;
+// rst_cntr <= #10 1'b0;
+// end
+// else if (w_to_w)
+// begin
+// turn <= #10 1'b1;
+// rst_cntr <= #10 1'b0;
+// end
+// else if (cmd0 && !turn)
+// begin
+// turn <= #10 1'b1;
+// rst_cntr <= #10 1'b1;
+// end
+// else if (~trif)
+// begin
+// turn <= #10 1'b0;
+// rst_cntr <= #10 1'b0;
+// end
+// else if (turn)
+// begin
+// turn <= #10 1'b1;
+// rst_cntr <= #10 1'b0;
+// end
+// else
+// begin
+// turn <= #10 1'b0;
+// rst_cntr <= #10 1'b0;
+// end
+// end
+
+
+
+always @ (posedge bufg_clk)
+begin
+ begin
+ if (rst)
+ begin
+ turn <= #10 1'b0;
+ end
+ else
+ begin
+ turn <= #10 (w_to_w || (cmd0 && ~turn) ||
+ (~wtw_cntr[2] && turn));
+ end
+
+ end
+
+ begin
+ if (rst)
+ begin
+ rst_cntr <= #10 1'b0;
+ end
+ else
+ begin
+ rst_cntr <= #10 (~w_to_w && (cmd0 && ~turn));
+ end
+ end
+end
+
+
+
+
+always @ (posedge bufg_clk)
+ begin
+ if (rst)
+ begin
+ turn_p1 <= #10 1'b0;
+ end
+ else
+ begin
+ turn_p1 <= #10 turn;
+ end
+ end
+
+
+
+
+// Detect multiple write commands and don"t turn IODELAY
+//always @ (posedge bufg_clk)
+// begin
+// if (rst)
+// begin
+// w_to_w <= #10 1'b0;
+// wtw_cntr <= #10 3'b000;
+// end
+// else if (cmd0 && turn_p1)
+// begin
+// w_to_w <= #10 1'b1;
+// wtw_cntr <= #10 3'b000;
+// end
+// else if (wtw_cntr == 3'b101)
+// begin
+// w_to_w <= #10 1'b0;
+// wtw_cntr <= #10 3'b000;
+// end
+// else if (w_to_w)
+// begin
+// w_to_w <= #10 1'b1;
+// wtw_cntr <= #10 wtw_cntr + 1;
+// end
+// end
+
+
+always @ (posedge bufg_clk)
+begin
+ begin
+ if (rst)
+ begin
+ w_to_w <= #10 1'b0;
+ end
+ else
+ begin
+ w_to_w <= #10 ((cmd0 && turn_p1) ||
+ (w_to_w && (~wtw_cntr[2] || ~wtw_cntr[1])));
+ end
+ end
+end
+
+
+always @ (posedge bufg_clk)
+
+ begin
+ if (!(w_to_w || turn) || (cmd0 && turn_p1))
+ begin
+ wtw_cntr <= #10 3'b000;
+ end
+ else if (w_to_w || turn_p1)
+ begin
+ wtw_cntr <= #10 wtw_cntr + 1;
+ end
+ end
+
+endmodule
+`timescale 1ps/1ps
+////////////////////////////////////////////////////////
+//
+// MODULE dout_oserdese1_vlog
+//
+// This model ONLY works for SERDES operation!!
+// Does not include tristate circuit
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+// data1: Data from FIFO
+// data2: Data input FIFO
+// CLK: High speed clock from DCM
+// BUFO: Clock from performance path
+// OCE: Clock enable for output data flops
+// SR: Set/Reset control. For the last 3 flops in OQ
+// (d1rnk2, d2rnk2 and d2nrnk2) this function is
+// controlled bythe attributes SRVAL_OQ. In SERDES mode,
+// SR is a RESET ONLY for all other flops! The flops will
+// still be RESET even if SR is programmed to a SET!
+//
+//
+//
+// Outputs:
+// OQ: Data output
+//
+//
+//
+// Programmable Points
+// DATA_RATE_OQ: Rate control for data output, 1-bit
+// sdr (1), ddr (0)
+// INIT_OQ: Init OQ output "flop"
+// SRVAL_OQ: This bit to controls value of SR input.
+// Only the last 3 flops (d1rnk2, d2rnk2 and d2nrnk2)
+// are affected by this bit.For SERDES mode, this bit
+// should be set to '0' making SR a reset. This is the
+// desired state since all other flops only respond to
+// this pin as a reset. Their function cannot be
+// changed. SR is '1' for SET and '0' for RESET.
+//
+//
+//
+// Programmable points for Test model
+// SRTYPE: This is a 4-bit field Sets asynchronous (0) or synchronous (1) set/reset
+// 1st bit (msb) sets rank1 flops, 2nd bit sets 4 flops in rank 2,
+// 3rd bit sets "3 legacy flops, and 4th (lsb) bit sets the counter
+// DDR_CLK_EDGE: Controls use of 2 or 3 flops for single case. Default to 1 for
+// SERDES operation
+//
+//
+///////////////////////////////////////////////////////////////////////////////
+//
+
+module dout_oserdese1_vlog (data1, data2,
+ CLK, BUFO, SR, OCE,
+ OQ, d2rnk2,
+ DATA_RATE_OQ,
+ INIT_OQ, SRVAL_OQ,
+ DDR3_MODE);
+
+input data1, data2;
+
+input CLK, SR, OCE;
+
+input BUFO;
+
+input INIT_OQ, SRVAL_OQ;
+
+input DDR3_MODE;
+
+output OQ;
+
+output d2rnk2;
+
+
+// Programmable Points
+
+input DATA_RATE_OQ;
+
+wire DDR_CLK_EDGE;
+wire [3:0] SRTYPE;
+assign DDR_CLK_EDGE = 1'b1;
+assign SRTYPE = 4'b1111;
+reg d1rnk2, d2rnk2, d2nrnk2;
+
+reg OQ;
+
+reg ddr_data, odata_edge, sdata_edge;
+
+reg c23, c45, c67;
+
+wire C;
+
+wire C2p, C3;
+
+wire [3:0] seloq;
+
+wire oqsr, oqrev;
+
+assign C = (BUFO & DDR3_MODE) | (CLK & !DDR3_MODE);
+
+assign C2p = (C & DDR_CLK_EDGE) | (!C & !DDR_CLK_EDGE);
+
+assign C3 = !C2p;
+
+assign seloq = {OCE,DATA_RATE_OQ,oqsr,oqrev};
+
+assign oqsr = !SRTYPE[1] & SR & !SRVAL_OQ;
+
+assign oqrev = !SRTYPE[1] & SR & SRVAL_OQ;
+
+
+
+//////////////////////////////////////////////////
+// Delay values
+//
+parameter FFD = 1; // clock to out delay for flip flops
+// driven by clk
+parameter FFCD = 1; // clock to out delay for flip flops
+// driven by clkdiv
+parameter MXD = 1; // 60 ps mux delay
+
+parameter MXR1 = 1;
+
+////////////////////////////////////////////
+// Initialization of flops with GSR for test model
+///////////////////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ assign OQ = INIT_OQ;
+ assign d1rnk2 = INIT_OQ;
+ assign d2rnk2 = INIT_OQ;
+ assign d2nrnk2 = INIT_OQ;
+ end
+ else
+ begin
+ deassign OQ;
+ deassign d1rnk2;
+ deassign d2rnk2;
+ deassign d2nrnk2;
+ end
+end
+
+/////////////////////////////////////////
+
+
+
+
+
+
+/////////////////////////////////////////
+// 3 flops to create DDR operations of 4 latches
+////////////////////////////////////////
+
+// Representation of top latch
+// asynchronous operation
+always @ (posedge C or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_OQ & !SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & !SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & !SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD OQ;
+ end
+ else if (!SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD data1;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C)
+begin
+ begin
+
+ if (SR & !SRVAL_OQ & SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD OQ;
+ end
+ else if (SRTYPE[1])
+ begin
+ d1rnk2 <= # FFD data1;
+ end
+ end
+end
+
+
+
+
+// Representation of 2nd latch
+// asynchronous operation
+always @ (posedge C2p or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_OQ & !SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & !SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & !SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD OQ;
+ end
+ else if (!SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD data2;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C2p)
+begin
+ begin
+
+ if (SR & !SRVAL_OQ & SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD OQ;
+ end
+ else if (SRTYPE[1])
+ begin
+ d2rnk2 <= # FFD data2;
+ end
+ end
+end
+
+
+
+
+// Representation of 3rd flop ( latch and output latch)
+// asynchronous operation
+always @ (posedge C3 or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_OQ & !SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & !SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & !SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD OQ;
+ end
+ else if (!SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD d2rnk2;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C3)
+begin
+
+ begin
+ if (SR & !SRVAL_OQ & SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD 1'b0;
+ end
+ else if (SR & SRVAL_OQ & SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD 1'b1;
+ end
+ else if (!OCE & SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD OQ;
+ end
+ else if (SRTYPE[1])
+ begin
+ d2nrnk2 <= # FFD d2rnk2;
+ end
+ end
+end
+
+
+// Logic to generate same edge data from d1rnk2 and d2nrnk2;
+always @ (C or C3 or d1rnk2 or d2nrnk2)
+ begin
+ sdata_edge <= # MXD (d1rnk2 & C) | (d2nrnk2 & C3);
+ end
+
+// Mux to create opposite edge DDR data from d1rnk2 and d2rnk2
+always @ (C or d1rnk2 or d2rnk2)
+ begin
+ case (C)
+ 1'b0: odata_edge <= # MXD d2rnk2;
+ 1'b1: odata_edge <= # MXD d1rnk2;
+ default: odata_edge <= # MXD d1rnk2;
+ endcase
+ end
+
+// Logic to same edge and opposite data into just ddr data
+always @ (ddr_data or sdata_edge or odata_edge or DDR_CLK_EDGE)
+ begin
+ ddr_data <= # MXD (odata_edge & !DDR_CLK_EDGE) | (sdata_edge & DDR_CLK_EDGE);
+ end
+
+
+// Output mux to generate OQ
+always @ (seloq or d1rnk2 or ddr_data or OQ)
+ begin
+ casex (seloq)
+ 4'bXX01: OQ <= # MXD 1'b1;
+ 4'bXX10: OQ <= # MXD 1'b0;
+ 4'bXX11: OQ <= # MXD 1'b0;
+ 4'bX000: OQ <= # MXD ddr_data;
+ 4'bX100: OQ <= # MXD d1rnk2;
+ default: OQ <= # MXD ddr_data;
+ endcase
+ end
+
+
+endmodule
+`timescale 1ps/1ps
+//////////////////////////////////////////////////////////
+//
+// module tout_oserdese1_vlog
+//
+// Tristate Output cell for Mt Blanc
+//
+//
+////////////////////////////////////////////////////////
+//
+//
+//
+/////////////////////////////////////////////////////////
+//
+// Inputs:
+//
+// data1, data2: tristate inputs
+// TCE: Tristate clock enable
+// SR: Set/Reset control. For the last 3 flops in TQ
+// (qt1, qt2 and qt2n) this function is
+// controlled bythe attributes SRVAL_TQ. In SERDES mode,
+// SR is a RESET ONLY for all other flops! The flops will
+// still be RESET even if SR is programmed to a SET!
+// CLK: High speed clocks
+// C2 drives 2nd latch and C3 (inverse of C2) drives
+// 3rd latch in output section
+// BUFO: Performance path clock
+//
+//
+//
+//
+// Outputs:
+//
+// TQ: Output of tristate mux
+//
+//
+// Programmable Options:
+//
+// DATA_RATE_TQ: 2-bit field for types of operaiton
+// 0 (buf from T1), 1 (registered output from T1), 2 (ddr)
+// TRISTATE_WIDTH: 2-bit field for input width
+// 0 (width 1), 1 (width 2), 2 (width 4)
+// INIT_TQ: Init TQ output (0,1)
+// SRVAL_TQ: This bit to controls value of SR input.
+// Only the last 3 flops (qt1, qt2 and qt2n) are
+// affected by this bit.For SERDES mode, this bit
+// should be set to '0' making SR a reset. This is the
+// desired state since all other flops only
+// respond to this pin as a reset. Their function
+// cannot be changed. SR is 'O' for SET and '1' for RESET.
+//
+//
+// Programmable Test Options:
+// SRTYPE: Control S and R as asynchronous (0) or synchronous (1)
+// 2-bit value. 1st bit (msb) controls the 4 input flops
+// and the 2nd bit (lsb) controls the "3 legacy flops"
+// DDR_CLK_EDGE: Same or opposite edge operation
+//
+//
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+
+module tout_oserdese1_vlog (data1, data2,
+ CLK, BUFO, SR, TCE,
+ DATA_RATE_TQ, TRISTATE_WIDTH,
+ INIT_TQ, SRVAL_TQ,
+ TQ, DDR3_MODE);
+
+input data1, data2;
+
+input CLK, BUFO, SR, TCE;
+
+input [1:0] DATA_RATE_TQ, TRISTATE_WIDTH;
+
+input INIT_TQ, SRVAL_TQ;
+
+input DDR3_MODE;
+
+output TQ;
+
+wire DDR_CLK_EDGE;
+wire [1:0] SRTYPE;
+assign SRTYPE = 2'b11;
+assign DDR_CLK_EDGE = 1'b1;
+
+reg TQ;
+
+reg t1r, t2r, t3r, t4r;
+
+reg qt1, qt2, qt2n;
+
+reg sdata_edge, odata_edge, ddr_data;
+
+wire C;
+
+wire C2p, C3;
+
+wire load;
+
+wire [5:0] tqsel;
+
+wire tqsr, tqrev;
+
+wire [4:0] sel;
+
+assign C = (BUFO & DDR3_MODE) | (CLK & !DDR3_MODE);
+
+assign C2p = (C & DDR_CLK_EDGE) | (!C & !DDR_CLK_EDGE);
+
+assign C3 = !C2p;
+
+assign tqsr = (!SRTYPE[0] & SR & !SRVAL_TQ) | (!SRTYPE[0] & SRVAL_TQ);
+
+assign tqrev = (!SRTYPE[0] & SR & SRVAL_TQ) | (!SRTYPE[0] & !SRVAL_TQ);
+
+assign tqsel = {TCE,DATA_RATE_TQ,TRISTATE_WIDTH,tqsr};
+
+
+
+
+
+//////////////////////////////////////////////////
+
+
+// Parameters for gate delays
+parameter ffd = 1;
+parameter mxd = 1;
+
+
+/////////////////////////////
+// Initialization of Flops
+////////////////////////////
+
+tri0 GSR = glbl.GSR;
+
+always @(GSR)
+begin
+ if (GSR)
+ begin
+ assign TQ = INIT_TQ;
+ assign qt1 = INIT_TQ;
+ assign qt2 = INIT_TQ;
+ assign qt2n = INIT_TQ;
+ end
+ else
+ begin
+ deassign TQ;
+ deassign qt1;
+ deassign qt2;
+ deassign qt2n;
+ end
+end
+
+
+
+/////////////////////////////////////////
+// 3 flops to create DDR operations of 4 latches
+////////////////////////////////////////
+
+// Representation of top latch
+// asynchronous operation
+always @ (posedge C or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt1 <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt1 <= # ffd 1'b1;
+ end
+ else if (!TCE & !SRTYPE[0])
+ begin
+ qt1 <= # ffd TQ;
+ end
+ else if (!SRTYPE[0])
+ begin
+ qt1 <= # ffd data1;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C)
+begin
+ begin
+
+ if (SR & !SRVAL_TQ & SRTYPE[0])
+ begin
+ qt1 <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & SRTYPE[0])
+ begin
+ qt1 <= # ffd 1'b1;
+ end
+ else if (!TCE & SRTYPE[0])
+ begin
+ qt1 <= # ffd TQ;
+ end
+ else if (SRTYPE[0])
+ begin
+ qt1 <= # ffd data1;
+ end
+ end
+end
+
+
+
+
+// Representation of 2nd latch
+// asynchronous operation
+always @ (posedge C2p or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt2 <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt2 <= # ffd 1'b1;
+ end
+ else if (!TCE & !SRTYPE[0])
+ begin
+ qt2 <= # ffd TQ;
+ end
+ else if (!SRTYPE[0])
+ begin
+ qt2 <= # ffd data2;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C2p)
+begin
+ begin
+ if (SR & !SRVAL_TQ & SRTYPE[0])
+ begin
+ qt2 <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & SRTYPE[0])
+ begin
+ qt2 <= # ffd 1'b1;
+ end
+ else if (!TCE & SRTYPE[0])
+ begin
+ qt2 <= # ffd TQ;
+ end
+ else if (SRTYPE[0])
+ begin
+ qt2 <= # ffd data2;
+ end
+ end
+end
+
+
+
+
+// Representation of 3rd flop ( latch and output latch)
+// asynchronous operation
+always @ (posedge C3 or posedge SR)
+begin
+ begin
+ if (SR & !SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt2n <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & !SRTYPE[0])
+ begin
+ qt2n <= # ffd 1'b1;
+ end
+ else if (!TCE & !SRTYPE[0])
+ begin
+ qt2n <= # ffd TQ;
+ end
+ else if (!SRTYPE[0])
+ begin
+ qt2n <= # ffd qt2;
+ end
+ end
+end
+
+// synchronous operation
+always @ (posedge C3)
+begin
+
+ begin
+ if (SR & !SRVAL_TQ & SRTYPE[0])
+ begin
+ qt2n <= # ffd 1'b0;
+ end
+ else if (SR & SRVAL_TQ & SRTYPE[0])
+ begin
+ qt2n <= # ffd 1'b1;
+ end
+ else if (!TCE & SRTYPE[0])
+ begin
+ qt2n <= # ffd TQ;
+ end
+ else if (SRTYPE[0])
+ begin
+ qt2n <= # ffd qt2;
+ end
+ end
+end
+
+
+// Logic to generate same edge data from qt1, qt3;
+always @ (C or C3 or qt1 or qt2n)
+ begin
+ sdata_edge <= # mxd (qt1 & C) | (qt2n & C3);
+ end
+
+// Mux to create opposite edge DDR function
+always @ (C or qt1 or qt2)
+ begin
+ case (C)
+ 1'b0: odata_edge <= # mxd qt2;
+ 1'b1: odata_edge <= # mxd qt1;
+ default: odata_edge <= 1'b0;
+ endcase
+ end
+
+// Logic to same edge and opposite data into just ddr data
+always @ (ddr_data or sdata_edge or odata_edge or DDR_CLK_EDGE)
+ begin
+ ddr_data <= # mxd (odata_edge & !DDR_CLK_EDGE) | (sdata_edge & DDR_CLK_EDGE);
+ end
+
+// Output mux to generate TQ
+// Note that the TQ mux can also support T2 combinatorial or
+// registered outputs.
+always @ (tqsel or data1 or ddr_data or qt1 or TQ)
+ begin
+ casex (tqsel)
+ 6'bX01XX1: TQ <= # mxd 1'b0;
+ 6'bX10XX1: TQ <= # mxd 1'b0;
+ 6'bX01XX1: TQ <= # mxd 1'b0;
+ 6'bX10XX1: TQ <= # mxd 1'b0;
+ 6'bX0000X: TQ <= # mxd data1;
+ // 6'b001000: TQ <= # mxd TQ;
+ // 6'b010010: TQ <= # mxd TQ;
+ // 6'b010100: TQ <= # mxd TQ;
+ 6'bX01000: TQ <= # mxd qt1;
+ 6'bX10010: TQ <= # mxd ddr_data;
+ 6'bX10100: TQ <= # mxd ddr_data;
+ default: TQ <= # mxd ddr_data;
+ endcase
+ end
+
+
+endmodule
+
+`endcelldefine
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment