added files needed for icarus simulation (not yet working)

This commit is contained in:
AngeloJacobo 2025-05-18 15:24:10 +08:00
parent 157cca28d8
commit 4be9a30ff8
15 changed files with 1137 additions and 57 deletions

View File

@ -181,7 +181,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("SDR"), // DDR, SDR
.DATA_RATE_TQ("SDR"), // DDR, SDR
.DATA_WIDTH(4), // Parallel data width (2-8,10,14)
@ -231,7 +231,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("SDR"), // DDR, SDR
.DATA_RATE_TQ("SDR"), // DDR, SDR
.DATA_WIDTH(4), // Parallel data width (2-8,10,14)
@ -305,7 +305,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("SDR"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
@ -352,7 +352,7 @@ module ddr3_phy #(
//Delay the DQ
// Delay resolution: 1/(32 x 2 x F REF ) = 78.125ps
(* IODELAY_GROUP="DDR3-GROUP" *)
ODELAYE2 #(
ODELAYE2_model #(
.DELAY_SRC("ODATAIN"), // Delay input (ODATAIN, CLKIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter to 5ps ("TRUE"), Reduced power but high jitter 9ns ("FALSE")
.ODELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
@ -380,12 +380,12 @@ module ddr3_phy #(
// OBUFDS: Differential Output Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
OBUFDS OBUFDS0_inst (
OBUFDS_model OBUFDS0_inst (
.O(o_ddr3_clk_p[0]), // Diff_p output (connect directly to top-level port)
.OB(o_ddr3_clk_n[0]), // Diff_n output (connect directly to top-level port)
.I(ddr3_clk_delayed) // Buffer input
);
OBUFDS OBUFDS1_inst (
OBUFDS_model OBUFDS1_inst (
.O(o_ddr3_clk_p[1]), // Diff_p output (connect directly to top-level port)
.OB(o_ddr3_clk_n[1]), // Diff_n output (connect directly to top-level port)
.I(ddr3_clk_delayed) // Buffer input
@ -396,7 +396,7 @@ module ddr3_phy #(
// OBUFDS: Differential Output Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
OBUFDS OBUFDS_inst (
OBUFDS_model OBUFDS_inst (
.O(o_ddr3_clk_p), // Diff_p output (connect directly to top-level port)
.OB(o_ddr3_clk_n), // Diff_n output (connect directly to top-level port)
.I(ddr3_clk_delayed) // Buffer input
@ -411,12 +411,12 @@ module ddr3_phy #(
// OBUFDS: Differential Output Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
OBUFDS OBUFDS0_inst (
OBUFDS_model OBUFDS0_inst (
.O(o_ddr3_clk_p[1]), // Diff_p output (connect directly to top-level port)
.OB(o_ddr3_clk_n[1]), // Diff_n output (connect directly to top-level port)
.I(!i_ddr3_clk) // Buffer input
);
OBUFDS OBUFDS1_inst (
OBUFDS_model OBUFDS1_inst (
.O(o_ddr3_clk_p[0]), // Diff_p output (connect directly to top-level port)
.OB(o_ddr3_clk_n[0]), // Diff_n output (connect directly to top-level port)
.I(!i_ddr3_clk) // Buffer input
@ -427,7 +427,7 @@ module ddr3_phy #(
// OBUFDS: Differential Output Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
OBUFDS OBUFDS_inst (
OBUFDS_model OBUFDS_inst (
.O(o_ddr3_clk_p), // Diff_p output (connect directly to top-level port)
.OB(o_ddr3_clk_n), // Diff_n output (connect directly to top-level port)
.I(!i_ddr3_clk) // Buffer input
@ -445,7 +445,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("BUF"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
@ -495,7 +495,7 @@ module ddr3_phy #(
//Delay the DQ
// Delay resolution: 1/(32 x 2 x F REF ) = 78.125ps
(* IODELAY_GROUP="DDR3-GROUP" *)
ODELAYE2 #(
ODELAYE2_model #(
.DELAY_SRC("ODATAIN"), // Delay input (ODATAIN, CLKIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter to 5ps ("TRUE"), Reduced power but high jitter 9ns ("FALSE")
.ODELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
@ -525,7 +525,7 @@ module ddr3_phy #(
// May only be placed in High Performance (HP) Banks
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
IOBUF_DCIEN #(
IOBUF_DCIEN_model #(
.IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE"
.SLEW("FAST"), // Specify the output slew rate
.USE_IBUFDISABLE("FALSE") // Use IBUFDISABLE function, "TRUE" or "FALSE"
@ -544,7 +544,7 @@ module ddr3_phy #(
// IOBUF: Single-ended Bi-directional Buffer
//All devices
// Xilinx HDL Libraries Guide, version 13.4
IOBUF #(
IOBUF_model #(
//.DRIVE(12), // Specify the output drive strength
.IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE"
//.IOSTANDARD("SSTL15"), // Specify the I/O standard
@ -561,7 +561,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("BUF"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
@ -607,7 +607,7 @@ module ddr3_phy #(
// IOBUF: Single-ended Bi-directional Buffer
//All devices
// Xilinx HDL Libraries Guide, version 13.4
IOBUF #(
IOBUF_model #(
//.DRIVE(12), // Specify the output drive strength
.IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE"
//.IOSTANDARD("SSTL15"), // Specify the I/O standard
@ -624,7 +624,7 @@ module ddr3_phy #(
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
(* IODELAY_GROUP="DDR3-GROUP" *)
IDELAYE2 #(
IDELAYE2_model #(
.DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN)
.HIGH_PERFORMANCE_MODE("TRUE"), //Reduced jitter ("TRUE"), Reduced power ("FALSE")
.IDELAY_TYPE("VAR_LOAD"), //FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
@ -653,7 +653,7 @@ module ddr3_phy #(
// ISERDESE2: Input SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
ISERDESE2 #(
ISERDESE2_model #(
.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)
@ -726,7 +726,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("BUF"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
@ -776,7 +776,7 @@ module ddr3_phy #(
//Delay the DQ
// Delay resolution: 1/(32 x 2 x F REF ) = 78.125ps
(* IODELAY_GROUP="DDR3-GROUP" *)
ODELAYE2 #(
ODELAYE2_model #(
.DELAY_SRC("ODATAIN"), // Delay input (ODATAIN, CLKIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter to 5ps ("TRUE"), Reduced power but high jitter 9ns ("FALSE")
.ODELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
@ -803,7 +803,7 @@ module ddr3_phy #(
// OBUF: Single-ended Output Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
OBUF #(
OBUF_model #(
//.IOSTANDARD("SSTL_15"), // Specify the output I/O standard
.SLEW("FAST") // Specify the output slew rate
) OBUF_dm (
@ -816,7 +816,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("BUF"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
@ -862,7 +862,7 @@ module ddr3_phy #(
// OBUF: Single-ended Output Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
OBUF #(
OBUF_model #(
//.IOSTANDARD("SSTL_15"), // Specify the output I/O standard
.SLEW("FAST") // Specify the output slew rate
) OBUF_dm (
@ -881,7 +881,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("BUF"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
@ -930,7 +930,7 @@ module ddr3_phy #(
// Xilinx HDL Libraries Guide, version 13.4
//Delay the DQ
(* IODELAY_GROUP="DDR3-GROUP" *)
ODELAYE2 #(
ODELAYE2_model #(
.DELAY_SRC("ODATAIN"), // Delay input (ODATAIN, CLKIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
.ODELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
@ -960,7 +960,7 @@ module ddr3_phy #(
// May only be placed in High Performance (HP) Banks
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
IOBUFDS_DCIEN #(
IOBUFDS_DCIEN_model #(
.IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE"
.SLEW("FAST"), // Specify the output slew rate
.USE_IBUFDISABLE("FALSE") // Use IBUFDISABLE function, "TRUE" or "FALSE"
@ -980,7 +980,7 @@ module ddr3_phy #(
// IOBUFDS: Differential Bi-directional Buffer
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
IOBUFDS #(
IOBUFDS_model #(
//.DIFF_TERM("FALSE"), // Differential Termination ("TRUE"/"FALSE")
.IBUF_LOW_PWR("FALSE") // Low Power - "TRUE", High Performance = "FALSE"
//.IOSTANDARD("DIFF_SSTL15") // Specify the I/O standard. CONSULT WITH DATASHEET
@ -1000,7 +1000,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("BUF"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
@ -1046,7 +1046,7 @@ module ddr3_phy #(
// IOBUFDS: Differential Bi-directional Buffer
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
IOBUFDS #(
IOBUFDS_model #(
//.DIFF_TERM("FALSE"), // Differential Termination ("TRUE"/"FALSE")
.IBUF_LOW_PWR("FALSE") // Low Power - "TRUE", High Performance = "FALSE"
//.IOSTANDARD("DIFF_SSTL15") // Specify the I/O standard. CONSULT WITH DATASHEET
@ -1065,7 +1065,7 @@ module ddr3_phy #(
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
(* IODELAY_GROUP="DDR3-GROUP" *)
IDELAYE2 #(
IDELAYE2_model #(
.DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN)
.HIGH_PERFORMANCE_MODE("TRUE"), //Reduced jitter ("TRUE"), Reduced power ("FALSE")
.IDELAY_TYPE("VAR_LOAD"), //FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
@ -1095,7 +1095,7 @@ module ddr3_phy #(
// ISERDESE2: Input SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
ISERDESE2 #(
ISERDESE2_model #(
.DATA_RATE("DDR"), // DDR, SDR
.DATA_WIDTH(serdes_ratio*2), // Parallel data width (2-8,10,14)
// INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)
@ -1186,7 +1186,7 @@ module ddr3_phy #(
// ISERDESE2: Input SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
ISERDESE2 #(
ISERDESE2_model #(
.DATA_RATE("DDR"), // DDR, SDR
.DATA_WIDTH(serdes_ratio*2), // Parallel data width (2-8,10,14)
// INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)
@ -1252,7 +1252,7 @@ module ddr3_phy #(
// OSERDESE2: Output SERial/DESerializer with bitslip
//7 Series
// Xilinx HDL Libraries Guide, version 13.4
OSERDESE2 #(
OSERDESE2_model #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("BUF"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
@ -1305,7 +1305,7 @@ module ddr3_phy #(
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
(* IODELAY_GROUP="DDR3-GROUP" *)
IDELAYCTRL IDELAYCTRL_inst (
IDELAYCTRL_model IDELAYCTRL_inst (
.RDY(idelayctrl_rdy), // 1-bit output: Ready output
.REFCLK(i_ref_clk), // 1-bit input: Reference clock input.The frequency of REFCLK must be 200 MHz to guarantee the tap-delay value specified in the applicable data sheet.
.RST(sync_rst) // 1-bit input: Active high reset input, To ,Minimum Reset pulse width is 52ns

18
testbench/IDELAYCTRL_model.v Executable file
View File

@ -0,0 +1,18 @@
`timescale 1 ns/1 ps
module IDELAYCTRL_model (
output reg RDY,
input REFCLK,
input RST
);
initial RDY = 0;
always @(posedge RST) begin
RDY <= 0;
end
always @(negedge RST) begin
# 10; // 10ns delay before RDY assertion
RDY <= 1;
end
endmodule

103
testbench/IDELAYE2_model.v Executable file
View File

@ -0,0 +1,103 @@
`timescale 1 ps / 1 ps
module IDELAYE2_model (
output reg DATAOUT,
input wire C,
input wire[4:0] CNTVALUEIN,
input wire LD,
input wire IDATAIN,
// NOT MODELLED
input wire[4:0] CNTVALUEOUT,
input wire CE,
input wire CINVCTRL,
input wire DATAIN,
input wire INC,
input wire LDPIPEEN,
input wire REGRST
);
parameter CINVCTRL_SEL = "FALSE";
parameter DELAY_SRC = "IDATAIN";
parameter HIGH_PERFORMANCE_MODE = "FALSE";
parameter IDELAY_TYPE = "FIXED";
parameter integer IDELAY_VALUE = 0;
parameter PIPE_SEL = "FALSE";
parameter real REFCLK_FREQUENCY = 200.0;
parameter SIGNAL_PATTERN = "DATA";
`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(DELAY_SRC != "IDATAIN") begin
$display("DELAY_SRC must be IDATAIN!");
$stop;
end
if(IDELAY_TYPE != "VAR_LOAD") begin
$display("IDELAY_TYPE must be VAR_LOAD!");
$stop;
end
if(REFCLK_FREQUENCY != 200) begin
$display("REFCLK_FREQUENCY must be 200!");
$stop;
end
end
integer delay_value;
initial DATAOUT = 0;
always @(IDATAIN) DATAOUT <= #(delay_value) IDATAIN;
initial delay_value = 600;
always @(posedge C) begin
if(LD) begin
delay_value <= 600 + 78*CNTVALUEIN;
end
end
generate
if(TEST_MODEL == 1) begin
wire DATAOUT_test;
reg unequal = 0;
IDELAYE2 #(
.DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN)
.HIGH_PERFORMANCE_MODE("TRUE"), //Reduced jitter ("TRUE"), Reduced power ("FALSE")
.IDELAY_TYPE("VAR_LOAD"), //FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.IDELAY_VALUE(0), //Input delay tap setting (0-31)
.PIPE_SEL("FALSE"), //Select pipelined mode, FALSE, TRUE
.REFCLK_FREQUENCY(200.0), //IDELAYCTRL clock input frequency in MHz (190.0-210.0).
.SIGNAL_PATTERN("CLOCK") //DATA, CLOCK input signal
)
IDELAYE2_test_model (
.CNTVALUEOUT(), // 5-bit output: Counter value output
.DATAOUT(DATAOUT_test), // 1-bit output: Delayed data output
.C(C), // 1-bit input: Clock input
.CE(1'b0), // 1-bit input: Active high enable increment/decrement input
.CINVCTRL(1'b0),// 1-bit input: Dynamic clock inversion input
.CNTVALUEIN(CNTVALUEIN), // 5-bit input: Counter value input
.DATAIN(), //1-bit input: Internal delay data input
.IDATAIN(IDATAIN), // 1-bit input: Data input from the I/O
.INC(1'b0), // 1-bit input: Increment / Decrement tap delay input
.LD(LD), // 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input
.REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input
);
// check if delayed signal matches with the actual IDELAY primitive, if not then stop simulation
always @* begin
#1;
if((DATAOUT_test !== DATAOUT) && ($time > 500_000)) begin
$display("IDELAYE2 MODEL does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING IDELAYE2 Model ----------------------------------------");
end
end
endgenerate
endmodule

17
testbench/IOBUFDS_DCIEN_model.v Executable file
View File

@ -0,0 +1,17 @@
`timescale 1 ps / 1 ps
module IOBUFDS_DCIEN_model #(
parameter IBUF_LOW_PWR = "TRUE",
parameter SLEW = "SLOW",
parameter USE_IBUFDISABLE = "TRUE"
)(
output O,
inout IO,
inout IOB,
input DCITERMDISABLE,
input I,
input IBUFDISABLE,
input T
);
// black box
endmodule

78
testbench/IOBUFDS_model.v Executable file
View File

@ -0,0 +1,78 @@
`timescale 1 ps / 1 ps
module IOBUFDS_model (
output O,
inout IO,
inout IOB,
input I,
input T
);
`ifdef NO_TEST_MODEL
parameter TEST_MODEL = 0;
`else
parameter TEST_MODEL = 1;
`endif
parameter IBUF_LOW_PWR = "FALSE";
assign IO = T ? 1'bz : I;
assign IOB = T ? 1'bz : ~I;
reg o_out;
always @(IO or IOB) begin
if (IO == 1'b1 && IOB == 1'b0)
o_out <= 1'b1;
else if (IO == 1'b0 && IOB == 1'b1)
o_out <= 1'b0;
else if ((IO === 1'bz || IO == 1'b0) && (IOB === 1'bz || IOB == 1'b1))
o_out <= 1'bx;
else if ((IO === 1'bx) || (IOB == 1'bx))
o_out <= 1'bx;
end
assign O = o_out;
generate
if(TEST_MODEL == 1) begin
wire O_test, IO_test, IOB_test;
reg unequal = 0;
bufif0 (IO_test, IO, 1'b0);
bufif0 (IOB_test, IOB, 1'b0);
IOBUFDS IOBUFDS_test_model (
.O(O_test), // Buffer output
.IO(IO_test), // Diff_p inout (connect directly to top-level port)
.IOB(IOB_test), // Diff_n inout (connect directly to top-level port)
.I(I), // Buffer input
.T(T) // 3-state enable input, high=input, low=output
);
integer address_plus_index;
integer address_inv;
always @* begin
address_plus_index = address + index;
address_inv = ~address;
end
always @* begin
#1;
if((O !== O_test) && ($time > 500_000)) begin
$display("IOBUFDS MODEL O does not match: time = %t", $time);
unequal <= 1;
$stop;
end
if(((IO != IO_test) || (IOB != IOB_test)) && ($time > 500_000)) begin
$display("IOBUFDS MODEL IO/IOB does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING IOBUFDS Model ----------------------------------------");
end
end
endgenerate
endmodule
`endcelldefine

18
testbench/IOBUF_DCIEN.v Executable file
View File

@ -0,0 +1,18 @@
`timescale 1 ps / 1 ps
module IOBUF_DCIEN_model #(
parameter IBUF_LOW_PWR = "TRUE",
parameter SLEW = "SLOW",
parameter USE_IBUFDISABLE = "TRUE"
)(
output O,
inout IO,
input I,
input T,
input DCITERMDISABLE,
input IBUFDISABLE
);
// black box
endmodule

61
testbench/IOBUF_model.v Executable file
View File

@ -0,0 +1,61 @@
`timescale 1 ps / 1 ps
module IOBUF_model (
output O,
inout IO,
input I,
input T
);
parameter IBUF_LOW_PWR = "TRUE";
parameter SLEW = "SLOW";
`ifdef NO_TEST_MODEL
parameter TEST_MODEL = 0;
`else
parameter TEST_MODEL = 1;
`endif
bufif0 T1 (IO, I, T);
buf B1 (O, IO);
generate
if(TEST_MODEL == 1) begin
reg unequal = 0;
wire O_test, IO_test;
bufif0 (IO_test, IO, 1'b0);
IOBUF #(
.IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE"
.SLEW("FAST") // Specify the output slew rate
) IOBUF_test_model (
.O(O_test),// Buffer output
.IO(IO_test), // Buffer inout port (connect directly to top-level port)
.I(I), // Buffer input
.T(T) // 3-state enable input, high=read, low=write
);
always @* begin
#1;
if((O !== O_test) && ($time > 500_000)) begin
$display("IOBUF MODEL O does not match: time = %t", $time);
unequal <= 1;
$stop;
end
if((IO != IO_test) && ($time > 500_000)) begin
$display("IOBUF MODEL IO does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING IOBUF Model ----------------------------------------");
end
end
endgenerate
endmodule

206
testbench/ISERDESE2_model.v Executable file
View File

@ -0,0 +1,206 @@
`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

49
testbench/OBUFDS_model.v Executable file
View File

@ -0,0 +1,49 @@
`timescale 1 ps/1 ps
module OBUFDS_model (
output wire O,
output wire OB,
input wire I
);
`ifdef NO_TEST_MODEL
parameter TEST_MODEL = 0;
`else
parameter TEST_MODEL = 1;
`endif
bufif0 (O, I, 1'b0);
notif0 (OB, I, 1'b0);
generate
if(TEST_MODEL == 1) begin
wire O_test, OB_test;
reg unequal = 0;
OBUFDS OBUFDS_test_model (
.O(O_test), // Diff_p output (connect directly to top-level port)
.OB(OB_test), // Diff_n output (connect directly to top-level port)
.I(I) // Buffer input
);
always @* begin
#1;
if((O !== O_test) && ($time > 500_000)) begin
$display("OBUFDS MODEL O does not match: time = %t", $time);
unequal <= 1;
$stop;
end
if((OB !== OB_test) && ($time > 500_000)) begin
$display("OBUFDS MODEL OB does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING OBUFDS Model ----------------------------------------");
end
end
endgenerate
endmodule

50
testbench/OBUF_model.v Executable file
View File

@ -0,0 +1,50 @@
`timescale 1 ps / 1 ps
module OBUF_model (
output O,
input I
);
parameter SLEW ="FAST";
`ifdef NO_TEST_MODEL
parameter TEST_MODEL = 0;
`else
parameter TEST_MODEL = 1;
`endif
bufif0 B1 (O, I, 0);
generate
if(TEST_MODEL == 1) begin
wire O_test;
reg unequal = 0;
OBUF #(
.SLEW("FAST") // Specify the output slew rate
) OBUF_test_model (
.O(O_test), // Buffer output (connect directly to top-level port)
.I(I) // Buffer input
);
always @* begin
#1;
if((O !== O_test) && ($time > 500_000)) begin
$display("OBUF MODEL O does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING OBUF Model ----------------------------------------");
end
end
endgenerate
endmodule

155
testbench/ODELAYE2_model.v Executable file
View File

@ -0,0 +1,155 @@
`timescale 1 ps / 1 ps
module ODELAYE2_model (
output reg DATAOUT,
input wire C,
input wire[4:0] CNTVALUEIN,
input wire LD,
input wire ODATAIN,
// NOT MODELLED
output wire[4:0] CNTVALUEOUT,
input wire CE,
input wire CINVCTRL,
input wire CLKIN,
input wire INC,
input wire LDPIPEEN,
input wire REGRST
);
parameter CINVCTRL_SEL = "FALSE";
parameter DELAY_SRC = "ODATAIN";
parameter HIGH_PERFORMANCE_MODE = "FALSE";
parameter [0:0] IS_C_INVERTED = 1'b0;
parameter [0:0] IS_ODATAIN_INVERTED = 1'b0;
parameter ODELAY_TYPE = "FIXED";
parameter integer ODELAY_VALUE = 0;
parameter PIPE_SEL = "FALSE";
parameter real REFCLK_FREQUENCY = 200.0;
parameter SIGNAL_PATTERN = "DATA";
parameter TEST_MODEL = 1;
// stop simulation if this modelfile does not support the settings
initial begin
if(DELAY_SRC != "ODATAIN") begin
$display("DELAY_SRC must be ODATAIN!");
$stop;
end
if(ODELAY_TYPE != "VAR_LOAD" && ODELAY_TYPE != "FIXED") begin
$display("ODELAY_TYPE must be VAR_LOAD or FIXED!");
$stop;
end
if(REFCLK_FREQUENCY != 200) begin
$display("REFCLK_FREQUENCY must be 200!");
$stop;
end
end
integer delay_value;
always @(ODATAIN) DATAOUT <= #(delay_value) ODATAIN;
generate
//---------------------------------------------------------------------------------------//
//----------------------------------- ODELAY_TYPE = VAR_LOAD ----------------------------//
//---------------------------------------------------------------------------------------//
if(ODELAY_TYPE == "VAR_LOAD") begin
initial delay_value = 600;
always @(posedge C) begin
if(LD) begin
delay_value <= 600 + 78*CNTVALUEIN;
end
end
if(TEST_MODEL == 1) begin
wire DATAOUT_test;
reg unequal = 0;
ODELAYE2 #(
.DELAY_SRC("ODATAIN"), // Delay input (ODATAIN, CLKIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter to 5ps ("TRUE"), Reduced power but high jitter 9ns ("FALSE")
.ODELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.ODELAY_VALUE(0), // Output delay tap setting (0-31)
.REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0).
.SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal
)
ODELAYE2_test_model_var_load (
.CNTVALUEOUT(), // 5-bit output: Counter value output
.DATAOUT(DATAOUT_test), // 1-bit output: Delayed data/clock output
.C(C), // 1-bit input: Clock input, when using OSERDESE2, C is connected to CLKDIV
.CE(1'b0), // 1-bit input: Active high enable increment/decrement input
.CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input
.CLKIN(1'b0), // 1-bit input: Clock delay input
.CNTVALUEIN(CNTVALUEIN), // 5-bit input: Counter value input
.INC(1'b0), // 1-bit input: Increment / Decrement tap delay input
.LD(LD), // 1-bit input: Loads ODELAY_VALUE tap delay in VARIABLE mode, in VAR_LOAD or
// VAR_LOAD_PIPE mode, loads the value of CNTVALUEIN
.LDPIPEEN(1'b0), // 1-bit input: Enables the pipeline register to load data
.ODATAIN(ODATAIN), // 1-bit input: Output delay data input
.REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input
);
// check if delayed signal matches with the actual ODELAY primitive, if not then stop simulation
always @* begin
#1;
if((DATAOUT_test !== DATAOUT) && ($time > 500_000)) begin
$display("ODELAYE2 MODEL does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING ODELAYE2 Model ----------------------------------------");
end
end
end
//---------------------------------------------------------------------------------------//
//----------------------------------- ODELAY_TYPE = FIXED -------------------------------//
//---------------------------------------------------------------------------------------//
else if(ODELAY_TYPE == "FIXED") begin
initial delay_value = 600 + 78*ODELAY_VALUE;
if(TEST_MODEL == 1) begin
wire DATAOUT_test;
reg unequal = 0;
ODELAYE2 #(
.DELAY_SRC("ODATAIN"), // Delay input (ODATAIN, CLKIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter to 5ps ("TRUE"), Reduced power but high jitter 9ns ("FALSE")
.ODELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.ODELAY_VALUE(ODELAY_VALUE), // Output delay tap setting (0-31)
.REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0).
.SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal
)
ODELAYE2_test_model_fixed (
.CNTVALUEOUT(), // 5-bit output: Counter value output
.DATAOUT(DATAOUT_test), // 1-bit output: Delayed data/clock output
.C(C), // 1-bit input: Clock input, when using OSERDESE2, C is connected to CLKDIV
.CE(1'b0), // 1-bit input: Active high enable increment/decrement input
.CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input
.CLKIN(1'b0), // 1-bit input: Clock delay input
.CNTVALUEIN(0), // 5-bit input: Counter value input
.INC(1'b0), // 1-bit input: Increment / Decrement tap delay input
.LD(LD), // 1-bit input: Loads ODELAY_VALUE tap delay in VARIABLE mode, in VAR_LOAD or
// VAR_LOAD_PIPE mode, loads the value of CNTVALUEIN
.LDPIPEEN(1'b0), // 1-bit input: Enables the pipeline register to load data
.ODATAIN(ODATAIN), // 1-bit input: Output delay data input
.REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input
);
// check if delayed signal matches with the actual ODELAY primitive, if not then stop simulation
always @* begin
#1;
if((DATAOUT_test !== DATAOUT) && ($time > 500_000)) begin
$display("ODELAYE2 MODEL does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING ODELAYE2 Model ----------------------------------------");
end
end
end
endgenerate
endmodule // ODELAYE2
`endcelldefine

289
testbench/OSERDESE2_model.v Executable file
View File

@ -0,0 +1,289 @@
`timescale 1 ps / 1 ps
module OSERDESE2_model (
// Clocks and reset
input wire CLK,
input wire CLKDIV,
input wire RST,
// D1 - D8: Parallel data inputs
input wire D1,
input wire D2,
input wire D3,
input wire D4,
input wire D5,
input wire D6,
input wire D7,
input wire D8,
// Buffer input/output for tristate controlle
input wire T1,
output reg TQ,
// Serial output
output wire OFB,
output reg OQ,
// NOT MODELLED
output wire SHIFTOUT1,
output wire SHIFTOUT2,
output wire TBYTEOUT,
output wire TFB,
input wire OCE,
input wire TCE,
input wire SHIFTIN1,
input wire SHIFTIN2,
input wire T2,
input wire T3,
input wire T4,
input wire TBYTEIN
);
parameter DATA_RATE_OQ = "DDR";
parameter DATA_RATE_TQ = "DDR";
parameter integer DATA_WIDTH = 4;
parameter [0:0] INIT_OQ = 1'b0;
parameter [0:0] INIT_TQ = 1'b0;
parameter integer TRISTATE_WIDTH = 4;
`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_OQ == "SDR" && DATA_WIDTH != 4) begin
$display("DATA_WIDTH must be 4 if DATA_RATE_OQ is SDR");
$stop;
end
if(DATA_RATE_OQ == "DDR" && DATA_WIDTH != 8) begin
$display("DATA_WIDTH must be 8 if DATA_RATE_OQ is DDR");
$stop;
end
end
reg[7:0] D_clkdiv_q;
reg[7:0] D_clk_q;
reg[2:0] counter = 0;
reg clk_delayed;
reg D1_delayed;
reg D2_delayed;
reg D3_delayed;
reg D4_delayed;
reg D5_delayed;
reg D6_delayed;
reg D7_delayed;
reg D8_delayed;
always @(CLK) clk_delayed <= #100 CLK;
always @(D1) D1_delayed <= #100 D1;
always @(D2) D2_delayed <= #100 D2;
always @(D3) D3_delayed <= #100 D3;
always @(D4) D4_delayed <= #100 D4;
always @(D5) D5_delayed <= #100 D5;
always @(D6) D6_delayed <= #100 D6;
always @(D7) D7_delayed <= #100 D7;
always @(D8) D8_delayed <= #100 D8;
always @(T1) TQ <= #100 T1;
generate
//---------------------------------------------------------------------------------------//
//----------------------------------- DATA RATE = DDR -----------------------------------//
//---------------------------------------------------------------------------------------//
if(DATA_RATE_OQ == "DDR") begin
// reset the counter on CLKDIV posedge to make sure first CLK posedge has counter == 0
always @(posedge CLKDIV) begin
if(RST) begin
counter <= 0;
end
end
// serialize out the D_clk_q on both edges
always @(posedge clk_delayed or negedge clk_delayed) begin
OQ <= D_clk_q[counter];
if(!(counter == 0 && !clk_delayed)) begin // should never happen where counter will increment up from zero @negedge (only @posedge will 0 increments to 1)
counter <= counter + 1; // counts from 0->1->2->...->7->0..
end
end
always @(posedge CLK) begin
if(counter == 0) begin // store D1-D8 at first CLK posedge after CLKDIV posedge (in short the time when counter == 0)
D_clkdiv_q <= {D8,D7,D6,D5,D4,D3,D2,D1};
D_clk_q <= D_clkdiv_q;
end
if(RST) begin
D_clkdiv_q <= 0;
D_clk_q <= 0;
end
end
// OFB output is just same as OQ
assign OFB = OQ;
if(TEST_MODEL == 1) begin // if model needs to be tested if it matches with the outputs from actual OSERDES primitive
wire OQ_test, TQ_test;
reg unequal = 0;
OSERDESE2 #(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("BUF"), // DDR, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
.INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1)
.TRISTATE_WIDTH(1)
)
OSERDESE2_test_model_ddr(
.OFB(), // 1-bit output: Feedback path for data
.OQ(OQ_test), // 1-bit output: Data path output
.CLK(CLK), // 1-bit input: High speed clock
.CLKDIV(CLKDIV), // 1-bit input: Divided clock
// D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
.D1(D1),
.D2(D2),
.D3(D3),
.D4(D4),
.D5(D5),
.D6(D6),
.D7(D7),
.D8(D8),
.TCE(1'b0),
.OCE(1'b1), // 1-bit input: Output data clock enable
.RST(RST), // 1-bit input: Reset
// unused signals but were added here to make vivado happy
.SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
.SHIFTOUT2(),
.TBYTEOUT(), // 1-bit output: Byte group tristate
.TFB(), // 1-bit output: 3-state control
.TQ(TQ_test), // 1-bit output: 3-state control
// SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
.SHIFTIN1(0),
.SHIFTIN2(0),
// T1 - T4: 1-bit (each) input: Parallel 3-state inputs
.T1(T1),
.T2(0),
.T3(0),
.T4(0),
.TBYTEIN(0)
// 1-bit input: Byte group tristate
);
// check if OQ and TQ matches with the actual OSERDES primitive, if not then stop simulation
always @* begin
#1;
if((OQ !== OQ_test) && (RST === 0) && ($time > 500_000)) begin
$display("OSERDES OQ MODEL does not match: time = %t", $time);
unequal <= 1;
$stop;
end
if((TQ !== TQ_test) && (RST === 0) && ($time > 500_000)) begin
$display("OSERDES TQ MODEL does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING OSERDESE2 Model ----------------------------------------");
end
end // end of if(TEST_MODEL == 1)
end // end of if(DATA_RATE_OQ == "DDR")
//---------------------------------------------------------------------------------------//
//----------------------------------- DATA RATE = SDR -----------------------------------//
//---------------------------------------------------------------------------------------//
if(DATA_RATE_OQ == "SDR") begin
// reset the counter on CLKDIV posedge to make sure first CLK posedge has counter == 0
always @(posedge CLKDIV) begin
if(RST) begin
counter <= 0;
end
end
// serialize out the D_clk_q on both edges
always @(posedge clk_delayed) begin
case(counter)
0: OQ <= D_clk_q[0];
1: OQ <= D_clk_q[1];
2: OQ <= D_clk_q[2];
3: OQ <= D_clk_q[3];
endcase
counter <= (counter == 3)? 0: counter + 1; // mod-4 counter
end
always @(posedge CLK) begin
if(counter == 0) begin // store D1-D8 at first CLK posedge after CLKDIV posedge (in short the time when counter == 0)
D_clkdiv_q <= {D4,D3,D2,D1};
end
if(counter == 0) begin
D_clk_q <= D_clkdiv_q;
end
if(RST) begin
D_clkdiv_q <= 0;
D_clk_q <= 0;
end
end
// OFB output is just same as OQ
assign OFB = OQ;
if(TEST_MODEL == 1) begin // if model needs to be tested if it matches with the outputs from actual OSERDES primitive
wire OQ_test, TQ_test;
reg unequal = 0;
OSERDESE2 #(
.DATA_RATE_OQ("SDR"), // DDR, SDR
.DATA_RATE_TQ("SDR"), // DDR, SDR
.DATA_WIDTH(4), // Parallel data width (2-8,10,14)
.INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1)
.TRISTATE_WIDTH(1)
)
OSERDESE2_test_model_sdr(
.OFB(), // 1-bit output: Feedback path for data
.OQ(OQ_test), // 1-bit output: Data path output
.CLK(CLK), // 1-bit input: High speed clock
.CLKDIV(CLKDIV), // 1-bit input: Divided clock
// D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
.D1(D1),
.D2(D2),
.D3(D3),
.D4(D4),
.TCE(1'b0),
.OCE(1'b1), // 1-bit input: Output data clock enable
.RST(RST), // 1-bit input: Reset
// unused signals but were added here to make vivado happy
.SHIFTOUT1(), // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
.SHIFTOUT2(),
.TBYTEOUT(), // 1-bit output: Byte group tristate
.TFB(), // 1-bit output: 3-state control
.TQ(TQ_test), // 1-bit output: 3-state control
// SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
.SHIFTIN1(0),
.SHIFTIN2(0),
// T1 - T4: 1-bit (each) input: Parallel 3-state inputs
.T1(T1),
.T2(0),
.T3(0),
.T4(0),
.TBYTEIN(0)
// 1-bit input: Byte group tristate
);
// check if OQ and TQ matches with the actual OSERDES primitive, if not then stop simulation
always @* begin
#1;
if((OQ !== OQ_test) && (RST === 0) && ($time > 500_000)) begin
$display("OSERDES OQ MODEL does not match: time = %t", $time);
unequal <= 1;
$stop;
end
if((TQ !== TQ_test) && (RST === 0) && ($time > 500_000)) begin
$display("OSERDES TQ MODEL does not match: time = %t", $time);
unequal <= 1;
$stop;
end
end
initial begin
$display("---------------------------------------- TESTING OSERDESE2 Model ----------------------------------------");
end
end // end of if(TEST_MODEL == 1)
end // end of if(DATA_RATE_OQ == "SDR")
endgenerate
endmodule

View File

@ -2501,8 +2501,7 @@ module ddr3 (
end
task cmd_addr_timing_check;
input i;
reg [4:0] i;
input reg [4:0] i;
begin
if (rst_n_in && prev_cke) begin
if ((i == 0) && ($time - tm_ck_pos < TIH)) // always check tIH for CS#
@ -2545,8 +2544,7 @@ module ddr3 (
// Processes to check setup and hold of data signals
task dm_timing_check;
input i;
reg [4:0] i;
input reg [4:0] i;
begin
if (dqs_in_valid) begin
if ($time - tm_dqs[i] < TDH)
@ -2596,8 +2594,7 @@ module ddr3 (
always @(dm_in[31]) dm_timing_check(31);
task dq_timing_check;
input i;
reg [6:0] i;
input reg [6:0] i;
begin
if (dqs_in_valid) begin
if ($time - tm_dqs[i/(`DQ_PER_DQS)] < TDH)
@ -2743,8 +2740,7 @@ module ddr3 (
always @(dq_in[127]) dq_timing_check(127);
task dqs_pos_timing_check;
input i;
reg [5:0] i;
input reg [5:0] i;
reg [4:0] j;
begin
if (write_levelization && i<32) begin
@ -2878,8 +2874,7 @@ module ddr3 (
always @(negedge dqs_in[63]) if (!dqs_in[63]) dqs_pos_timing_check(63);
task dqs_neg_timing_check;
input i;
reg [5:0] i;
input reg [5:0] i;
reg [4:0] j;
begin
if (write_levelization && i<32) begin

View File

@ -53,7 +53,7 @@ module ddr3_dimm_micron_sim;
`ifdef EIGHT_LANES_x8
localparam BYTE_LANES = 8,
ODELAY_SUPPORTED = 0;
ODELAY_SUPPORTED = 1;
`endif
@ -68,6 +68,9 @@ module ddr3_dimm_micron_sim;
BIST_MODE = 2, // 0 = No BIST, 1 = run through all address space ONCE , 2 = run through all address space for every test (burst w/r, random w/r, alternating r/w)
DLL_OFF = 0;
localparam WB_DATA_BITS = 8*BYTE_LANES*4*2,
WB_SEL_BITS = WB_DATA_BITS / 8;
reg i_controller_clk, i_ddr3_clk, i_ref_clk, i_ddr3_clk_90;
reg i_rst_n;
// Wishbone Interface
@ -76,7 +79,7 @@ module ddr3_dimm_micron_sim;
reg i_wb_we; //write-enable (1 = write, 0 = read)
reg[$bits(ddr3_top.i_wb_addr)-1:0] i_wb_addr; //burst-addressable {row,bank,col}
reg[$bits(ddr3_top.i_wb_data)-1:0] i_wb_data; //write data, for a 4:1 controller data width is 8 times the number of pins on the device
reg[ddr3_top.wb_sel_bits - 1:0] i_wb_sel; //byte strobe for write (1 = write the byte)
reg[WB_SEL_BITS - 1:0] i_wb_sel; //byte strobe for write (1 = write the byte)
wire o_wb_stall; //1 = busy, cannot accept requests
wire o_wb_ack; //1 = read/write request has completed
wire[$bits(ddr3_top.o_wb_data)-1:0] o_wb_data; //read data, for a 4:1 controller data width is 8 times the number of pins on the device
@ -288,7 +291,7 @@ ddr3_top #(
`endif
reg[ddr3_top.ddr3_controller_inst.wb_data_bits-1:0] orig_phy_data;
reg[WB_DATA_BITS-1:0] orig_phy_data;
// Force change for ECC tests
// Uncommented since there is ECC_TEST parameter inside ddr3_controller to test ECC
// generate
@ -343,6 +346,10 @@ ddr3_top #(
integer number_of_op = 0;
integer time_started = 0;
integer average_1, average_2, average_3, average_4;
integer address_plus_index;
integer read_address_plus_index;
integer address_inv;
localparam MAX_READS = (2**COL_BITS)*(2**BA_BITS + 1)/8; //1 row = 2**(COL_BITS) addresses/8 burst = 128 words per row. Times 8 to pass all 8 banks
initial begin
i_user_self_refresh = 0;
@ -388,7 +395,8 @@ ddr3_top #(
@(posedge i_controller_clk) begin
if(!i_wb_stb || !o_wb_stall) begin
for (index = 0; index < $bits(ddr3_top.i_wb_data)/32; index = index + 1) begin
i_wb_data[index*32 +: 32] <= $random(address + index); //each $random only has 32 bits
address_plus_index = address + index;
i_wb_data[index*32 +: 32] <= $random(address_plus_index); //each $random only has 32 bits
end
i_wb_cyc <= 1;
i_wb_stb <= 1;
@ -463,7 +471,8 @@ ddr3_top #(
@(posedge i_controller_clk) begin
if(!i_wb_stb || !o_wb_stall) begin
for (index = 0; index < $bits(ddr3_top.i_wb_data)/32; index = index + 1) begin
i_wb_data[index*32 +: 32] <= $random(address + index); //each $random only has 32 bits
address_plus_index = address + index;
i_wb_data[index*32 +: 32] <= $random(address_plus_index); //each $random only has 32 bits
end
i_wb_cyc <= 1;
i_wb_stb <= 1;
@ -534,7 +543,8 @@ ddr3_top #(
@(posedge i_controller_clk) begin
if(!i_wb_stb || !o_wb_stall) begin
for (index = 0; index < $bits(ddr3_top.i_wb_data)/32; index = index + 1) begin
i_wb_data[index*32 +: 32] <= $random(address + index); //each $random only has 32 bits
address_plus_index = address + index;
i_wb_data[index*32 +: 32] <= $random(address_plus_index); //each $random only has 32 bits
end
i_wb_cyc <= 1;
i_wb_stb <= 1;
@ -610,13 +620,15 @@ ddr3_top #(
@(posedge i_controller_clk) begin
if(!i_wb_stb || !o_wb_stall) begin
for (index = 0; index < $bits(ddr3_top.i_wb_data)/32; index = index + 1) begin
i_wb_data[index*32 +: 32] <= $random(address + index); //each $random only has 32 bits
address_plus_index = address + index;
i_wb_data[index*32 +: 32] <= $random(address_plus_index); //each $random only has 32 bits
end
i_wb_cyc <= 1;
i_wb_stb <= 1;
i_wb_we <= 1;
i_aux <= 1;
i_wb_addr <= $random(~address); //write at random address
address_inv = ~address;
i_wb_addr <= $random(address_inv); //write at random address
if(address == random_start + ($bits(ddr3_top.i_wb_data)/32)*(MAX_READS-1)) begin //inject error at last row
number_of_injected_errors <= number_of_injected_errors + 1;
i_wb_data <= 64'h123456789;
@ -650,7 +662,8 @@ ddr3_top #(
i_wb_stb <= 1;
i_wb_we <= 0;
i_aux <= 0;
i_wb_addr <= $random(~address);
address_inv = ~address;
i_wb_addr <= $random(address_inv);
//$display("Read: Address = %0d", i_wb_addr);
number_of_reads <= number_of_reads + 1;
number_of_op <= number_of_op + 1;
@ -777,7 +790,8 @@ ddr3_top #(
@(posedge i_controller_clk);
if(o_wb_ack && ddr3_top.ddr3_controller_inst.state_calibrate == ddr3_top.ddr3_controller_inst.DONE_CALIBRATE && o_aux[2:0] == 0) begin
for (index = 0; index < $bits(ddr3_top.i_wb_data)/32; index = index + 1) begin
expected_read_data[index*32 +: 32] = $random(read_address + index); //each $random only has 32 bits
read_address_plus_index = read_address + index;
expected_read_data[index*32 +: 32] = $random(read_address_plus_index); //each $random only has 32 bits
end
if (ECC_ENABLE == 2) begin
expected_read_data[511 : ddr3_top.ddr3_controller_inst.ECC_INFORMATION_BITS] = 0;
@ -803,7 +817,8 @@ ddr3_top #(
@(posedge i_controller_clk);
if(o_wb_ack && ddr3_top.ddr3_controller_inst.state_calibrate == ddr3_top.ddr3_controller_inst.DONE_CALIBRATE && o_aux[2:0] == 0) begin
for (index = 0; index < $bits(ddr3_top.i_wb_data)/32; index = index + 1) begin
expected_read_data[index*32 +: 32] = $random(read_address + index); //each $random only has 32 bits
read_address_plus_index = read_address + index;
expected_read_data[index*32 +: 32] = $random(read_address_plus_index); //each $random only has 32 bits
end
if (ECC_ENABLE == 2) begin
expected_read_data[511 : ddr3_top.ddr3_controller_inst.ECC_INFORMATION_BITS] = 0;
@ -829,7 +844,8 @@ ddr3_top #(
@(posedge i_controller_clk);
if(o_wb_ack && ddr3_top.ddr3_controller_inst.state_calibrate == ddr3_top.ddr3_controller_inst.DONE_CALIBRATE && o_aux[2:0] == 0) begin
for (index = 0; index < $bits(ddr3_top.i_wb_data)/32; index = index + 1) begin
expected_read_data[index*32 +: 32] = $random(read_address + index); //each $random only has 32 bits
read_address_plus_index = read_address + index;
expected_read_data[index*32 +: 32] = $random(read_address_plus_index); //each $random only has 32 bits
end
if (ECC_ENABLE == 2) begin
expected_read_data[511 : ddr3_top.ddr3_controller_inst.ECC_INFORMATION_BITS] = 0;
@ -855,7 +871,8 @@ ddr3_top #(
@(posedge i_controller_clk);
if(o_wb_ack && ddr3_top.ddr3_controller_inst.state_calibrate == ddr3_top.ddr3_controller_inst.DONE_CALIBRATE && o_aux[2:0] == 0) begin
for (index = 0; index < $bits(ddr3_top.i_wb_data)/32; index = index + 1) begin
expected_read_data[index*32 +: 32] = $random(read_address + index); //each $random only has 32 bits
read_address_plus_index = read_address + index;
expected_read_data[index*32 +: 32] = $random(read_address_plus_index); //each $random only has 32 bits
end
if (ECC_ENABLE == 2) begin
expected_read_data[511 : ddr3_top.ddr3_controller_inst.ECC_INFORMATION_BITS] = 0;

24
testbench/sim_icarus.sh Executable file
View File

@ -0,0 +1,24 @@
rm -rf ./uberddr3_sim
iverilog -o uberddr3_sim -g2012 \
-DNO_TEST_MODEL \
-s ddr3_dimm_micron_sim \
-I ./ \
./ddr3_dimm_micron_sim.sv \
./ddr3.sv \
./IDELAYCTRL_model.v \
./IDELAYE2_model.v \
./IOBUF_DCIEN.v \
./IOBUF_model.v \
./IOBUFDS_DCIEN_model.v \
./IOBUFDS_model.v \
./ISERDESE2_model.v \
./OBUFDS_model.v \
./ODELAYE2_model.v \
./OSERDESE2_model.v \
./OBUF_model.v \
../rtl/ddr3_top.v \
../rtl/ddr3_controller.v \
../rtl/ddr3_phy.v
vvp ./uberddr3_sim