From: Luke Kenneth Casson Leighton Date: Fri, 25 Feb 2022 01:21:42 +0000 (+0000) Subject: allow DDR3 reset (rst) signal to be controlled by DFI commands, X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b5553cc55a60c36c1068e0b90f0ad2065d0a495e;p=gram.git allow DDR3 reset (rst) signal to be controlled by DFI commands, update icarus simulation to match, and rename dfi.Interface reset signal to reset_n --- diff --git a/gram/core/multiplexer.py b/gram/core/multiplexer.py index 0817d35..458c301 100644 --- a/gram/core/multiplexer.py +++ b/gram/core/multiplexer.py @@ -159,8 +159,8 @@ class _Steerer(Elaboratable): for i, (phase, sel) in enumerate(zip(self.dfi.phases, self.sel)): nranks = len(phase.cs) rankbits = log2_int(nranks) - if hasattr(phase, "reset"): - m.d.comb += phase.reset.eq(0) + if hasattr(phase, "reset_n"): + m.d.comb += phase.reset_n.eq(1) m.d.comb += phase.clk_en.eq(Repl(1, nranks)) if hasattr(phase, "odt"): # FIXME: add dynamic drive for multi-rank (will be needed for high frequencies) diff --git a/gram/dfii.py b/gram/dfii.py index 323ba97..a1f5ad4 100644 --- a/gram/dfii.py +++ b/gram/dfii.py @@ -98,7 +98,7 @@ class DFIInjector(Elaboratable): for phase in self._inti.phases] m.d.comb += [phase.odt[i].eq(self._control.w_data[2]) for phase in self._inti.phases if hasattr(phase, "odt")] - m.d.comb += [phase.reset.eq(self._control.w_data[3]) - for phase in self._inti.phases if hasattr(phase, "reset")] + m.d.comb += [phase.reset_n.eq(self._control.w_data[3]) + for phase in self._inti.phases if hasattr(phase, "reset_n")] return m diff --git a/gram/phy/dfi.py b/gram/phy/dfi.py index a436fee..91c4799 100644 --- a/gram/phy/dfi.py +++ b/gram/phy/dfi.py @@ -18,7 +18,7 @@ def phase_description(addressbits, bankbits, nranks, databits): ("we", 1, DIR_FANOUT), ("clk_en", nranks, DIR_FANOUT), ("odt", nranks, DIR_FANOUT), - ("reset", 1, DIR_FANOUT), + ("reset_n", 1, DIR_FANOUT), ("act", 1, DIR_FANOUT), # wrdata description ("wrdata", databits, DIR_FANOUT), @@ -43,7 +43,6 @@ class Interface: nranks, databits), name=name) self.phases += [p] - p.reset.reset = 1 def connect(self, target): if not isinstance(target, Interface): diff --git a/gram/phy/ecp5ddrphy.py b/gram/phy/ecp5ddrphy.py index 336b063..672d8b2 100644 --- a/gram/phy/ecp5ddrphy.py +++ b/gram/phy/ecp5ddrphy.py @@ -239,13 +239,19 @@ class ECP5DDRPHY(Peripheral, Elaboratable): # requesting the resource: # ddr_pins = platform.request("ddr3", 0, xdr={"clk":4, "odt":4, ... }) controls = ["ras", "cas", "we", "clk_en", "odt"] - if hasattr(self.pads, "reset"): - controls.append("reset") + if hasattr(self.pads, "rst"): # this gets renamed later to match dfi + controls.append("rst") + if hasattr(self.pads, "reset_n"): + controls.append("reset_n") if hasattr(self.pads, "cs"): controls.append("cs") for name in controls: print ("clock", name, getattr(self.pads, name)) pad = getattr(self.pads, name) + # sigh, convention in nmigen_boards is "rst" but in + # dfi.Interface it is "reset" + if name == 'rst': + name = 'reset_n' m.d.comb += [ pad.o_clk.eq(ClockSignal("dramsync")), pad.o_fclk.eq(ClockSignal("sync2x")), diff --git a/gram/simulation/icarusecpix5platform.py b/gram/simulation/icarusecpix5platform.py index d2155b2..e3520c0 100644 --- a/gram/simulation/icarusecpix5platform.py +++ b/gram/simulation/icarusecpix5platform.py @@ -27,6 +27,7 @@ class IcarusECPIX5Platform(LatticeECP5Platform): ), Resource("ddr3", 0, + Subsignal("rst", Pins("fake", dir="o")), # for sim Subsignal("clk", Pins("H3", dir="o")), #Subsignal("clk", DiffPairs("H3", "J3", dir="o"), Attrs(IO_TYPE="SSTL135D_I")), Subsignal("clk_en", Pins("P1", dir="o")), diff --git a/gram/simulation/simsoc.py b/gram/simulation/simsoc.py index 2379715..ba3c839 100644 --- a/gram/simulation/simsoc.py +++ b/gram/simulation/simsoc.py @@ -25,7 +25,8 @@ class DDR3SoC(SoC, Elaboratable): features={"cti", "bte"}) ddr_pins = platform.request("ddr3", 0, dir={"dq":"-", "dqs":"-"}, - xdr={"clk":4, "a":4, "ba":4, "clk_en":4, "we_n":4, "odt":4, "ras":4, "cas":4, "we":4}) + xdr={"rst": 4, "clk":4, "a":4, "ba":4, "clk_en":4, "we_n":4, + "odt":4, "ras":4, "cas":4, "we":4}) self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins)) self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr) diff --git a/gram/simulation/simsoctb.v b/gram/simulation/simsoctb.v index a866cc0..3ef4ad9 100644 --- a/gram/simulation/simsoctb.v +++ b/gram/simulation/simsoctb.v @@ -40,12 +40,12 @@ module simsoctb; wire [1:0] dram_dm; wire dram_odt; wire [1:0] dram_tdqs_n; - reg dram_rst = 0; + wire dram_rst; ddr3 #( .check_strict_timing(0) ) ram_chip ( - .rst_n(~dram_rst), + .rst_n(dram_rst), .ck(dram_ck), .ck_n(~dram_ck), .cke(dram_cke), @@ -78,6 +78,7 @@ module simsoctb; //defparam ram_chip. top simsoctop ( + .ddr3_0__rst__io(dram_rst), .ddr3_0__dq__io(dram_dq), .ddr3_0__dqs__p(dram_dqs), .ddr3_0__clk__io(dram_ck), @@ -105,6 +106,7 @@ module simsoctb; begin $dumpfile("simsoc.fst"); $dumpvars(0, clkin); + $dumpvars(0, dram_rst); $dumpvars(0, dram_dq); $dumpvars(0, dram_dqs); $dumpvars(0, dram_ck); @@ -132,18 +134,13 @@ module simsoctb; reg [31:0] tmp; initial begin - dram_rst = 1; #350; // Wait for RESET and POR - // Software control - dram_rst = 0; - - #10; - $display("Release RESET_N"); wishbone_write(32'h0000900c >> 2, 32'h0); // p0 address wishbone_write(32'h00009010 >> 2, 32'h0); // p0 baddress wishbone_write(32'h00009000 >> 2, 8'h0C); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N + $display("Enable CKE"); wishbone_write(32'h00009000 >> 2, 8'h0E); // DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE if (dram_cke != 1) diff --git a/gram/test/test_dfii.py b/gram/test/test_dfii.py index 7016da1..4f5cc9b 100644 --- a/gram/test/test_dfii.py +++ b/gram/test/test_dfii.py @@ -162,10 +162,10 @@ class DFIInjectorTestCase(FHDLTestCase): def process(): yield from wb_write(csrhost.bus, DFII_CONTROL_ADDR >> 2, (1 << 3), sel=0xF) yield - self.assertTrue((yield dut.master.phases[0].reset)) + self.assertTrue((yield dut.master.phases[0].reset_n)) yield from wb_write(csrhost.bus, DFII_CONTROL_ADDR >> 2, 0, sel=0xF) yield - self.assertFalse((yield dut.master.phases[0].reset)) + self.assertFalse((yield dut.master.phases[0].reset_n)) runSimulation(m, process, "test_dfiinjector.vcd")