blob: fdbcbd8e765fe0458717e2720661312de198d33b [file] [log] [blame] [edit]
module ioddr_tester (
input wire CLK,
input wire CLKB,
output wire ERR,
output wire Q,
input wire D
);
parameter USE_PHY_ODDR = 1;
parameter USE_PHY_IDDR = 1;
parameter USE_IDELAY = 0;
parameter DDR_CLK_EDGE = "SAME_EDGE";
// Data generator
wire [1:0] g_dat;
data_generator gen (
.CLK (CLK),
.CE (1'b1),
.D1 (g_dat[0]),
.D2 (g_dat[1])
);
// Data delay
wire [1:0] d_dat;
reg [1:0] d_d1;
reg [1:0] d_d2;
always @(posedge CLK) begin
d_d1 <= {g_dat[0], d_d1[1]};
d_d2 <= {g_dat[1], d_d2[1]};
end
assign d_dat = {d_d2[0], d_d1[0]};
// ODDR
oddr_wrapper # (
.USE_PHY_ODDR (USE_PHY_ODDR),
.DDR_CLK_EDGE (DDR_CLK_EDGE)
) oddr_wrapper (
.C (CLK),
.OCE (1'b1),
.S (0),
.R (0),
.D1 (g_dat[0]),
.D2 (g_dat[1]),
.OQ (Q)
);
// IDDR
wire [1:0] r_dat;
iddr_wrapper # (
.USE_IDELAY (USE_IDELAY),
.USE_PHY_IDDR (USE_PHY_IDDR),
.DDR_CLK_EDGE (DDR_CLK_EDGE)
) iddr_wrapper (
.C (CLK),
.CB (CLKB),
.CE (1'b1),
.S (0),
.R (0),
.D (D),
.Q1 (r_dat[1]),
.Q2 (r_dat[0])
);
// Re-clock received data in OPPOSITE_EDGE MODE
wire [1:0] r_dat2;
generate if(DDR_CLK_EDGE == "OPPOSITE_EDGE") begin
reg tmp;
always @(posedge CLK)
tmp <= r_dat[0];
assign r_dat2 = {r_dat[1], tmp};
end else begin
assign r_dat2 = r_dat;
end endgenerate
// Data comparator
reg err_r;
always @(posedge CLK)
err_r <= r_dat2 != d_dat;
// Error pulse prolonger
reg [20:0] cnt;
wire err = !cnt[20];
always @(posedge CLK)
if (err_r) cnt <= 1 << 24;
else if (err) cnt <= cnt - 1;
else cnt <= cnt;
assign ERR = err;
endmodule