From 8aa7c1b9dd70eada733daeae18c0b7032871c2e9 Mon Sep 17 00:00:00 2001 From: Pawel Sagan Date: Wed, 1 Sep 2021 10:25:21 +0200 Subject: [PATCH] litex: adding oddr/iddr/ddrtristate simulation models Signed-off-by: Pawel Sagan --- litex/build/io.py | 12 ++++++++- litex/build/sim/common.py | 36 +++++++++++++++++++++++++- litex/build/sim/verilog/iddr_verilog.v | 24 +++++++++++++++++ litex/build/sim/verilog/oddr_verilog.v | 19 ++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 litex/build/sim/verilog/iddr_verilog.v create mode 100644 litex/build/sim/verilog/oddr_verilog.v diff --git a/litex/build/io.py b/litex/build/io.py index 1435488b6..1d1a59ab5 100644 --- a/litex/build/io.py +++ b/litex/build/io.py @@ -147,6 +147,16 @@ class DDROutput(Special): # DDR Tristate ------------------------------------------------------------------------------------- +class InferedDDRTristate(Module): + def __init__(self, i1, i2, o1, o2, oe1, oe2, io, clk): + _o = Signal() + _oe = Signal() + _i = Signal() + self.specials += DDROutput(i1, i2, _o, clk) + self.specials += DDROutput(oe1, oe2, _oe, clk) + self.specials += DDRInput(_i, o1, o2, clk) + self.specials += Tristate(io, _o, _oe, _i) + class DDRTristate(Special): def __init__(self, i1, i2, o1, o2, oe1, oe2, io, clk=ClockSignal()): Special.__init__(self) @@ -171,7 +181,7 @@ class DDRTristate(Special): @staticmethod def lower(dr): - raise NotImplementedError("Attempted to use a DDR tristate, but platform does not support them") + return InferedDDRTristate(dr.i1, dr.i2, dr.o1, dr.o2, dr.oe1, dr.oe2, dr.io, dr.clk) # Clock Reset Generator ---------------------------------------------------------------------------- diff --git a/litex/build/sim/common.py b/litex/build/sim/common.py index 38741fd4b..b5e795ac4 100644 --- a/litex/build/sim/common.py +++ b/litex/build/sim/common.py @@ -1 +1,35 @@ -sim_special_overrides = {} +from migen import * +from migen.fhdl.specials import Special + +from litex.build.io import * + +class InferedDDROutputSim(Module): + def __init__(self, o, i1, i2, clk): + self.specials += Instance("DDR_OUTPUT", + i_i1 = i1, + i_i2 = i2, + o_o = o, + i_clk = clk) + +class InferedDDRInputSim(Module): + def __init__(self, i, o1, o2, clk): + self.specials += Instance("DDR_INPUT", + o_o1 = o1, + o_o2 = o2, + i_i = i, + i_clk = clk) + +class DDROutputSim: + @staticmethod + def lower(dr): + return InferedDDROutputSim(dr.o, dr.i1, dr.i2, dr.clk) + +class DDRInputSim: + @staticmethod + def lower(dr): + return InferedDDRInputSim(dr.i, dr.o1, dr.o2, dr.clk) + +sim_special_overrides = { + DDROutput: DDROutputSim, + DDRInput: DDRInputSim, +} diff --git a/litex/build/sim/verilog/iddr_verilog.v b/litex/build/sim/verilog/iddr_verilog.v new file mode 100644 index 000000000..e58dabfe7 --- /dev/null +++ b/litex/build/sim/verilog/iddr_verilog.v @@ -0,0 +1,24 @@ +module DDR_INPUT( + output reg o1, + output reg o2, + input i, + input clk); + +reg _o1, _o2; + +always @ (posedge clk) + begin + o1 = _o1; + o2 = _o2; + end + +always @ (posedge clk) + begin + _o1 = i; + end + +always @ (negedge clk) + begin + _o2 = i; + end +endmodule diff --git a/litex/build/sim/verilog/oddr_verilog.v b/litex/build/sim/verilog/oddr_verilog.v new file mode 100644 index 000000000..0193cc60a --- /dev/null +++ b/litex/build/sim/verilog/oddr_verilog.v @@ -0,0 +1,19 @@ +module DDR_OUTPUT( + input i1, + input i2, + output o, + input clk); + +wire _o; +reg _i1, _i2; + +assign o = _o; +assign _o = (clk) ? _i1 : _i2; + +always @ (posedge clk) + begin + _i1 = i1; + _i2 = i2; + end + +endmodule