allow DDR3 reset (rst) signal to be controlled by DFI commands,
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 25 Feb 2022 01:21:42 +0000 (01:21 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 25 Feb 2022 01:21:42 +0000 (01:21 +0000)
update icarus simulation to match, and
rename dfi.Interface reset signal to reset_n

gram/core/multiplexer.py
gram/dfii.py
gram/phy/dfi.py
gram/phy/ecp5ddrphy.py
gram/simulation/icarusecpix5platform.py
gram/simulation/simsoc.py
gram/simulation/simsoctb.v
gram/test/test_dfii.py

index 0817d35623f3c6f4536ea7fd01ddc3b0325514c2..458c301aeeda998edff5685e1301452fbaffe0d5 100644 (file)
@@ -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)
index 323ba975735b5bce2c5b2e6437831b16179acfe6..a1f5ad494681f10d1465b0e7db2e6003d902171c 100644 (file)
@@ -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
index a436fee62321a22dddfc1f53743a0142af76804f..91c4799b36b7f565ae5168bdbe412a8cd6c873ea 100644 (file)
@@ -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):
index 336b0635b6afbd7575e2e519792d9461574b568e..672d8b2c56ebe215dcc836d76cd681f80ce7060d 100644 (file)
@@ -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")),
index d2155b2a72e1a7ac2516d4a6305cd9390d6b4776..e3520c0ade9f2b11f22c1fa9dcd49f98767c029f 100644 (file)
@@ -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")),
index 2379715cbd7bf9f5e43001ed154a8e9700e94b64..ba3c8396cff6068f65e8b4c9ae864d8743a43ff9 100644 (file)
@@ -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)
 
index a866cc0d3d41b086a8b32cbeec7a10344c591ec8..3ef4ad9f11fa395cddc09594ceabf3b296bd0d69 100644 (file)
@@ -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)
index 7016da185e0566e63c7c3c180a27149420fe3561..4f5cc9b44f62b57a562ce2a1c495153e13d52675 100644 (file)
@@ -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")