UberDDR3/testbench/models/ISERDESE2_model.v

207 lines
6.5 KiB
Verilog
Executable File

`timescale 1 ps / 1 ps
module ISERDESE2_model (
input wire CLK,
input wire CLKB,
input wire CLKDIV,
input wire RST,
input wire BITSLIP,
input wire DDLY,
output reg Q1,
output reg Q2,
output reg Q3,
output reg Q4,
output reg Q5,
output reg Q6,
output reg Q7,
output reg Q8,
// NOT MODELLED
output wire O,
output wire SHIFTOUT1,
output wire SHIFTOUT2,
input wire CE1,
input wire CE2,
input wire CLKDIVP,
input wire D,
input wire DYNCLKDIVSEL,
input wire DYNCLKSEL,
input wire OCLK,
input wire OCLKB,
input wire OFB,
input wire SHIFTIN1,
input wire SHIFTIN2
);
parameter DATA_RATE = "DDR";
parameter integer DATA_WIDTH = 4;
parameter [0:0] INIT_Q1 = 1'b0;
parameter [0:0] INIT_Q2 = 1'b0;
parameter [0:0] INIT_Q3 = 1'b0;
parameter [0:0] INIT_Q4 = 1'b0;
parameter INTERFACE_TYPE = "MEMORY";
parameter IOBDELAY = "NONE";
parameter integer NUM_CE = 2;
parameter OFB_USED = "FALSE";
parameter [0:0] SRVAL_Q1 = 1'b0;
parameter [0:0] SRVAL_Q2 = 1'b0;
parameter [0:0] SRVAL_Q3 = 1'b0;
parameter [0:0] SRVAL_Q4 = 1'b0;
`ifdef NO_TEST_MODEL
parameter TEST_MODEL = 0;
`else
parameter TEST_MODEL = 1;
`endif
// stop simulation if this modelfile does not support the settings
initial begin
if(DATA_RATE != "DDR" || DATA_WIDTH != 8) begin
$display("DATA_RATE must be 8 and DATA_WIDTH must be 8!");
$stop;
end
if(INTERFACE_TYPE != "NETWORKING") begin
$display("INTERFACE_TYPE must be NETWORKING!");
$stop;
end
if(IOBDELAY != "IFD") begin
$display("IOBDELAY must be IFD!");
$stop;
end
if(OFB_USED != "FALSE") begin
$display("OFB_USED must be FALSE!");
$stop;
end
end
reg[7:0] Q_clk_0, Q_clk_1;
reg[2:0] counter;
reg clk_delayed, clkdiv_delayed;
reg[2:0] bitslip_counter = 0;
always @(CLK) clk_delayed <= #100 CLK;
always @(CLKDIV) clkdiv_delayed <= #100 CLKDIV;
always @(posedge CLKDIV) begin
if(RST) begin
counter <= 0;
end
if(BITSLIP) begin
bitslip_counter <= bitslip_counter + 1;
end
end
always @(posedge clk_delayed or negedge clk_delayed) begin
counter <= counter + 1;
end
always @(posedge CLK or negedge CLK) begin
case(counter)
3'd4 + bitslip_counter[2:0]: Q_clk_0[7] <= DDLY;
3'd5 + bitslip_counter[2:0]: Q_clk_0[6] <= DDLY;
3'd6 + bitslip_counter[2:0]: Q_clk_0[5] <= DDLY;
3'd7 + bitslip_counter[2:0]: Q_clk_0[4] <= DDLY;
3'd0 + bitslip_counter[2:0]: Q_clk_0[3] <= DDLY;
3'd1 + bitslip_counter[2:0]: Q_clk_0[2] <= DDLY;
3'd2 + bitslip_counter[2:0]: Q_clk_0[1] <= DDLY;
3'd3 + bitslip_counter[2:0]: begin
Q_clk_0[0] <= DDLY;
Q_clk_1 <= {Q_clk_0[7:1],DDLY};
end
endcase
end
always @(posedge clkdiv_delayed) begin
Q8 <= Q_clk_1[7];
Q7 <= Q_clk_1[6];
Q6 <= Q_clk_1[5];
Q5 <= Q_clk_1[4];
Q4 <= Q_clk_1[3];
Q3 <= Q_clk_1[2];
Q2 <= Q_clk_1[1];
Q1 <= Q_clk_1[0];
end
generate
if(TEST_MODEL == 1) begin
wire Q1_test, Q2_test, Q3_test, Q4_test, Q5_test, Q6_test, Q7_test, Q8_test;
reg unequal = 0;
ISERDESE2 #(
.DATA_RATE("DDR"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
// INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.INIT_Q3(1'b0),
.INIT_Q4(1'b0),
.INTERFACE_TYPE("NETWORKING"), // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE
.IOBDELAY("IFD"), // NONE, BOTH, IBUF, IFD
.NUM_CE(1),// Number of clock enables (1,2)
.OFB_USED("FALSE"), // Select OFB path (FALSE, TRUE)
// SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)
.SRVAL_Q1(1'b0),
.SRVAL_Q2(1'b0),
.SRVAL_Q3(1'b0),
.SRVAL_Q4(1'b0)
)
ISERDESE2_test_model (
.O(),
// 1-bit output: Combinatorial output
// Q1 - Q8: 1-bit (each) output: Registered data outputs
.Q1(Q1_test),//56
.Q2(Q2_test), //48
.Q3(Q3_test),
.Q4(Q4_test),
.Q5(Q5_test),
.Q6(Q6_test),
.Q7(Q7_test),
.Q8(Q8_test),
// SHIFTOUT1-SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
.SHIFTOUT1(),
.SHIFTOUT2(),
.BITSLIP(BITSLIP),
// 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to
// CLKDIV when asserted (active High). Subsequently, the data seen on the Q1
// to Q8 output ports will shift, as in a barrel-shifter operation, one
// position every time Bitslip is invoked (DDR operation is different from
// SDR).
// CE1, CE2: 1-bit (each) input: Data register clock enable inputs
.CE1(1'b1),
.CE2(1'b1),
.CLKDIVP(), // 1-bit input: TBD
// Clocks: 1-bit (each) input: ISERDESE2 clock input ports
.CLK(CLK), // 1-bit input: High-speed clock
.CLKB(CLKB), // 1-bit input: High-speed secondary clock
.CLKDIV(CLKDIV), // 1-bit input: Divided clock
.OCLK(), // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY"
// Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity
.DYNCLKDIVSEL(), // 1-bit input: Dynamic CLKDIV inversion
.DYNCLKSEL(), // 1-bit input: Dynamic CLK/CLKB inversion
// Input Data: 1-bit (each) input: ISERDESE2 data input ports
.D(), // 1-bit input: Data input
.DDLY(DDLY), // 1-bit input: Serial data from IDELAYE2
.OFB(), // 1-bit input: Data feedback from OSERDESE2
.OCLKB(), // 1-bit input: High speed negative edge output clock
.RST(RST), // 1-bit input: Active high asynchronous reset
// SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports
.SHIFTIN1(),
.SHIFTIN2()
);
// check if OQ and TQ matches with the actual OSERDES primitive, if not then stop simulation
always @* begin
#1;
if(({Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1} !== {Q8_test,Q7_test,Q6_test,Q5_test,Q4_test,Q3_test,Q2_test,Q1_test}) && (RST === 0) && ($time > 500_000)) begin
$display("ISERDES MODEL does not match: time = %t", $time);
unequal <= 1;
// $stop;
end
end
initial begin
$display("---------------------------------------- TESTING ISERDESE2 Model ----------------------------------------");
end
end
endgenerate
endmodule