Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions dv/models/fpga/rtl/IOBUF.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// This is a crude model of the Xilinx IOBUF primitive; enough to make the
// OpenHBMC implementation simulate correctly.
module IOBUF #(
parameter DRIVE = 0,
parameter SLEW = "SLOW"
) (
output O,
inout IO,
input I,
input T
);

assign O = IO;
assign IO = T ? 1'bZ : I;

endmodule

83 changes: 83 additions & 0 deletions dv/models/fpga/rtl/ISERDESE2.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// This is a crude model of the Xilinx ISERDESE2 primitive; enough to make the
// OpenHBMC implementation simulate correctly.
module ISERDESE2 #(
parameter SERDES_MODE = "MASTER",
parameter INTERFACE_TYPE = "NETWORKING",
parameter DATA_RATE = "DDR",
parameter DATA_WIDTH = 6,
parameter DYN_CLKDIV_INV_EN = "FALSE",
parameter DYN_CLK_INV_EN = "FALSE",
parameter OFB_USED = "NONE",
parameter IOBDELAY = 0,
parameter NUM_CE = 1,
parameter INIT_Q1 = 1'b0,
parameter INIT_Q2 = 1'b0,
parameter INIT_Q3 = 1'b0,
parameter INIT_Q4 = 1'b0,
parameter SRVAL_Q1 = 1'b0,
parameter SRVAL_Q2 = 1'b0,
parameter SRVAL_Q3 = 1'b0,
parameter SRVAL_Q4 = 1'b0
) (
output O,

output Q1,
output Q2,
output Q3,
output Q4,
output Q5,
output Q6,
output Q7,
output Q8,

input BITSLIP,

input CE1,
input CE2,

input CLK,
input CLKB,

input CLKDIV,
input CLKDIVP,
input OCLK,
input OCLKB,

input D,
input DDLY,

input OFB,
input RST,

input DYNCLKDIVSEL,
input DYNCLKSEL,

output SHIFTOUT1,
output SHIFTOUT2,

input SHIFTIN1,
input SHIFTIN2
);

reg [8:1] iserdes_int;
always @(edge CLK or posedge RST) begin
if (RST) begin
iserdes_int <= {2{SRVAL_Q4, SRVAL_Q3, SRVAL_Q2, SRVAL_Q1}};
end else begin
iserdes_int <= {iserdes_int[7:1], D};
end
end

// In the ISERDESE2 module, Q8 is the oldest bit received.
assign {Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1} = iserdes_int;
assign O = D;

// These outputs are unused.
assign {SHIFTOUT2, SHIFTOUT1} = 2'b0;

endmodule

18 changes: 18 additions & 0 deletions dv/models/fpga/rtl/OBUF.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// This is a crude model of the Xilinx OBUF primitive; enough to make the
// OpenHBMC implementation simulate correctly.
module OBUF #(
parameter DRIVE = 0,
parameter SLEW = "SLOW"
) (
input I,
output O
);

assign O = I;

endmodule

52 changes: 52 additions & 0 deletions dv/models/fpga/rtl/ODDR.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// This is a crude model of the Xilinx ODDR primitive; enough to make the
// OpenHBMC implementation simulate correctly.
module ODDR #(
parameter DDR_CLK_EDGE = "SAME_EDGE",
parameter INIT = 1'b0,
parameter SRTYPE = "ASYNC"
) (
output Q, // DDR output.
input C, // Clock input.
input CE, // Clock Enable.
input D1, // Two data inputs.
input D2,
input R, // ReSet inputs.
input S
);

// Phase detection; PH is asserted during the second (negative edge)
// phase of the clock 'C.'
// ___ ___
// C ___/ \___/ \___
// PH 1 0 1 0 1

reg PH, PC, NC;
always @(posedge C) PC <= !PC;
always @(negedge C) NC <= !NC;
assign PH = !(PC ^ NC);

reg S2;
if (DDR_CLK_EDGE == "SAME_EDGE") begin : gen_same_edge
// Both data inputs are presented together on posedge.
always @(posedge C) begin
if (CE) S2 <= D2;
end
end else begin : gen_opposite_edge
// Inputs are presented on opposite edges.
assign S2 = D2;
end

// Output is clocked on both edges of clock input 'C'.
reg OUT;
always @(edge C, posedge R, posedge S) begin
if (R || S) OUT <= S & ~R;
else if (CE) OUT <= PH ? D1 : S2;
end
assign Q = OUT;

endmodule

Loading
Loading