Merge pull request #1021 from antmicro/ddr_sim
litex: Enable simulation of DDR IO by adding oddr/iddr/ddrtristate simulation models.
This commit is contained in:
commit
2b700057b7
|
@ -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 ----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue