Use PinsN when possible (fixes #27)
authorJean THOMAS <git0@pub.jeanthomas.me>
Mon, 20 Jul 2020 10:41:46 +0000 (12:41 +0200)
committerJean THOMAS <git0@pub.jeanthomas.me>
Mon, 20 Jul 2020 10:41:51 +0000 (12:41 +0200)
13 files changed:
examples/ecpix5_85.py
examples/headless-ecpix5.py
gram/core/multiplexer.py
gram/dfii.py
gram/phy/dfi.py
gram/phy/ecp5ddrphy.py
gram/phy/fakephy.py
gram/simulation/icarusecpix5platform.py
gram/simulation/simsoc.py
gram/simulation/simsoctb.v
gram/test/test_dfii.py
libgram/src/dfii.c
libgram/src/dfii.h

index 9b0bdc996f277184f292dbad1b6485ff9c663272..01a8439e7f608a453109f31176ac44edd890abc3 100644 (file)
@@ -64,9 +64,9 @@ class _ECPIX5Platform(LatticeECP5Platform):
             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")),
-            Subsignal("we_n",   Pins("R3", dir="o")),
-            Subsignal("ras_n",  Pins("T3", dir="o")),
-            Subsignal("cas_n",  Pins("P2", dir="o")),
+            Subsignal("we",   PinsN("R3", dir="o")),
+            Subsignal("ras",  PinsN("T3", dir="o")),
+            Subsignal("cas",  PinsN("P2", dir="o")),
             Subsignal("a",      Pins("T5 M3 L3 V6 K2 W6 K3 L1 H2 L2 N1 J1 M1 K1", dir="o")),
             Subsignal("ba",     Pins("U6 N3 N4", dir="o")),
             #Subsignal("dqs",    DiffPairs("V4 V1", "U5 U2", dir="io"), Attrs(IO_TYPE="SSTL135D_I")),
index 0d61dc8989a773c6ec961d31a9b95c98ffc46d70..b01063278941e21cdff9562d3539da142b6805c4 100644 (file)
@@ -33,7 +33,7 @@ class DDR3SoC(SoC, Elaboratable):
         self.ub = UARTBridge(divisor=868, pins=platform.request("uart", 0))
 
         ddr_pins = platform.request("ddr3", 0, dir={"dq":"-", "dqs":"-"},
-            xdr={"clk":4, "a":4, "ba":4})
+            xdr={"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 cc61d09729d39ba37d4b9d420493653bc29d3768..62bc7b229e606d84b850fe7fe8d984c80ceb1dc4 100644 (file)
@@ -161,10 +161,10 @@ class _Steerer(Elaboratable):
                 return cmd.valid & cmd.ready & getattr(cmd, attr)
 
         for i, (phase, sel) in enumerate(zip(dfi.phases, self.sel)):
-            nranks = len(phase.cs_n)
+            nranks = len(phase.cs)
             rankbits = log2_int(nranks)
-            if hasattr(phase, "reset_n"):
-                m.d.comb += phase.reset_n.eq(1)
+            if hasattr(phase, "reset"):
+                m.d.comb += phase.reset.eq(0)
             m.d.comb += phase.clk_en.eq(Repl(Signal(reset=1), nranks))
             if hasattr(phase, "odt"):
                 # FIXME: add dynamic drive for multi-rank (will be needed for high frequencies)
@@ -176,24 +176,24 @@ class _Steerer(Elaboratable):
                     (Array(cmd.ba[-rankbits:] for cmd in commands)[sel]))
                 if i == 0:  # Select all ranks on refresh.
                     with m.If(sel == STEER_REFRESH):
-                        m.d.sync += phase.cs_n.eq(0)
+                        m.d.sync += phase.cs.eq(1)
                     with m.Else():
-                        m.d.sync += phase.cs_n.eq(~rank_decoder.o)
+                        m.d.sync += phase.cs.eq(rank_decoder.o)
                 else:
-                    m.d.sync += phase.cs_n.eq(~rank_decoder.o)
+                    m.d.sync += phase.cs.eq(rank_decoder.o)
                 m.d.sync += phase.bank.eq(Array(cmd.ba[:-rankbits]
                                                 for cmd in commands)[sel])
             else:
                 m.d.sync += [
-                    phase.cs_n.eq(0),
+                    phase.cs.eq(1),
                     phase.bank.eq(Array(cmd.ba[:] for cmd in commands)[sel]),
                 ]
 
             m.d.sync += [
                 phase.address.eq(Array(cmd.a for cmd in commands)[sel]),
-                phase.cas_n.eq(~Array(valid_and(cmd, "cas") for cmd in commands)[sel]),
-                phase.ras_n.eq(~Array(valid_and(cmd, "ras") for cmd in commands)[sel]),
-                phase.we_n.eq(~Array(valid_and(cmd, "we") for cmd in commands)[sel])
+                phase.cas.eq(Array(valid_and(cmd, "cas") for cmd in commands)[sel]),
+                phase.ras.eq(Array(valid_and(cmd, "ras") for cmd in commands)[sel]),
+                phase.we.eq(Array(valid_and(cmd, "we") for cmd in commands)[sel])
             ]
 
             rddata_ens = Array(valid_and(cmd, "is_read") for cmd in commands)
index 5b9664cca4076785db138103f13f25d1f50e7e81..f3e98849048eacad14a2a82826b64d2e9ad7fb97 100644 (file)
@@ -36,17 +36,17 @@ class PhaseInjector(Elaboratable):
 
         with m.If(self._command_issue.w_stb):
             m.d.comb += [
-                self._phase.cs_n.eq(Repl(value=~self._command.w_data[0], count=len(self._phase.cs_n))),
-                self._phase.we_n.eq(~self._command.w_data[1]),
-                self._phase.cas_n.eq(~self._command.w_data[2]),
-                self._phase.ras_n.eq(~self._command.w_data[3]),
+                self._phase.cs.eq(Repl(value=self._command.w_data[0], count=len(self._phase.cs))),
+                self._phase.we.eq(self._command.w_data[1]),
+                self._phase.cas.eq(self._command.w_data[2]),
+                self._phase.ras.eq(self._command.w_data[3]),
             ]
         with m.Else():
             m.d.comb += [
-                self._phase.cs_n.eq(Repl(value=1, count=len(self._phase.cs_n))),
-                self._phase.we_n.eq(1),
-                self._phase.cas_n.eq(1),
-                self._phase.ras_n.eq(1),
+                self._phase.cs.eq(Repl(value=0, count=len(self._phase.cs))),
+                self._phase.we.eq(0),
+                self._phase.cas.eq(0),
+                self._phase.ras.eq(0),
             ]
 
         with m.If(self._phase.rddata_valid):
@@ -65,7 +65,7 @@ class DFIInjector(Elaboratable):
         self.slave = dfi.Interface(addressbits, bankbits, nranks, databits, nphases)
         self.master = dfi.Interface(addressbits, bankbits, nranks, databits, nphases)
 
-        self._control = csr_bank.csr(4, "w")  # sel, clk_en, odt, reset_n
+        self._control = csr_bank.csr(4, "w")  # sel, clk_en, odt, reset
 
         self._phases = []
         for n, phase in enumerate(self._inti.phases):
@@ -87,7 +87,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_n.eq(self._control.w_data[3])
-                     for phase in self._inti.phases if hasattr(phase, "reset_n")]
+        m.d.comb += [phase.reset.eq(self._control.w_data[3])
+                     for phase in self._inti.phases if hasattr(phase, "reset")]
 
         return m
index 13ae1cf2240485063df1d6e2674eb59d56ba9146..7e58b990ba68a8a254d892201dafc2252128762d 100644 (file)
@@ -12,14 +12,14 @@ def phase_description(addressbits, bankbits, nranks, databits):
         # cmd description
         ("address", addressbits, DIR_FANOUT),
         ("bank", bankbits, DIR_FANOUT),
-        ("cas_n", 1, DIR_FANOUT),
-        ("cs_n", nranks, DIR_FANOUT),
-        ("ras_n", 1, DIR_FANOUT),
-        ("we_n", 1, DIR_FANOUT),
+        ("cas", 1, DIR_FANOUT),
+        ("cs", nranks, DIR_FANOUT),
+        ("ras", 1, DIR_FANOUT),
+        ("we", 1, DIR_FANOUT),
         ("clk_en", nranks, DIR_FANOUT),
         ("odt", nranks, DIR_FANOUT),
-        ("reset_n", 1, DIR_FANOUT),
-        ("act_n", 1, DIR_FANOUT),
+        ("reset", 1, DIR_FANOUT),
+        ("act", 1, DIR_FANOUT),
         # wrdata description
         ("wrdata", databits, DIR_FANOUT),
         ("wrdata_en", 1, DIR_FANOUT),
@@ -38,11 +38,7 @@ class Interface:
             p = Record(phase_description(
                 addressbits, bankbits, nranks, databits))
             self.phases += [p]
-            p.cas_n.reset = 1
-            p.cs_n.reset = (2**nranks-1)
-            p.ras_n.reset = 1
-            p.we_n.reset = 1
-            p.act_n.reset = 1
+            p.reset.reset = 1
 
     def connect(self, target):
         if not isinstance(target, Interface):
index 7d6f7dd969a2003376648aeb9e00baad697a6fa8..9f76e34be896575d81d6fcb290e63644e55fe04e 100644 (file)
@@ -106,7 +106,7 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
 
         addressbits = len(self.pads.a.o0)
         bankbits = len(self.pads.ba.o0)
-        nranks = 1 if not hasattr(self.pads, "cs_n") else len(self.pads.cs_n.o)
+        nranks = 1 if not hasattr(self.pads, "cs") else len(self.pads.cs.o0)
         databits = len(self.pads.dq.io)
         self.dfi = Interface(addressbits, bankbits, nranks, 4*databits, 4)
 
@@ -114,7 +114,7 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
         tck = 2/(2*2*self._sys_clk_freq)
         nphases = 2
         databits = len(self.pads.dq.io)
-        nranks = 1 if not hasattr(self.pads, "cs_n") else len(self.pads.cs_n.o)
+        nranks = 1 if not hasattr(self.pads, "cs") else len(self.pads.cs.o0)
         cl, cwl = get_cl_cw("DDR3", tck)
         cl_sys_latency = get_sys_latency(nphases, cl)
         cwl_sys_latency = get_sys_latency(nphases, cwl)
@@ -198,11 +198,11 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                 self.pads.ba.o3[i].eq(dfi.phases[1].bank[i]),
             ]
 
-        controls = ["ras_n", "cas_n", "we_n", "clk_en", "odt"]
-        if hasattr(self.pads, "reset_n"):
-            controls.append("reset_n")
-        if hasattr(self.pads, "cs_n"):
-            controls.append("cs_n")
+        controls = ["ras", "cas", "we", "clk_en", "odt"]
+        if hasattr(self.pads, "reset"):
+            controls.append("reset")
+        if hasattr(self.pads, "cs"):
+            controls.append("cs")
         for name in controls:
             m.d.comb += [
                 getattr(self.pads, name).o_clk.eq(ClockSignal("dramsync")),
index 3d1137136a016fa69565bf989cc33dce26845018..d1c4885f52c6c05234c2ae763720fa9bac905bdc 100644 (file)
@@ -129,16 +129,16 @@ class DFIPhaseModel(Elaboratable):
     def elaborate(self, platform):
         m = Module()
 
-        with m.If(~self.phase.cs_n & ~self.phase.ras_n & self.phase.cas_n):
+        with m.If(self.phase.cs & self.phase.ras & ~self.phase.cas):
             m.d.comb += [
-                self.activate.eq(self.phase.we_n),
-                self.precharge.eq(~self.phase.we_n),
+                self.activate.eq(~self.phase.we),
+                self.precharge.eq(self.phase.we),
             ]
 
-        with m.If(~self.phase.cs_n & self.phase.ras_n & ~self.phase.cas_n):
+        with m.If(self.phase.cs & ~self.phase.ras & self.phase.cas):
             m.d.comb += [
-                self.write.eq(~self.phase.we_n),
-                self.read.eq(self.phase.we_n),
+                self.write.eq(self.phase.we),
+                self.read.eq(~self.phase.we),
             ]
 
         return m
@@ -163,12 +163,12 @@ class TimingRule:
 class DFITimingsChecker(Elaboratable):
     CMDS = [
         # Name, cs & ras & cas & we value
-        ("PRE",  "0010"), # Precharge
-        ("REF",  "0001"), # Self refresh
-        ("ACT",  "0011"), # Activate
-        ("RD",   "0101"), # Read
-        ("WR",   "0100"), # Write
-        ("ZQCS", "0110"), # ZQCS
+        ("PRE",  "1101"), # Precharge
+        ("REF",  "1110"), # Self refresh
+        ("ACT",  "1100"), # Activate
+        ("RD",   "1010"), # Read
+        ("WR",   "1011"), # Write
+        ("ZQCS", "1001"), # ZQCS
     ]
 
     RULES = [
@@ -291,7 +291,7 @@ class DFITimingsChecker(Elaboratable):
             ps = Signal().like(cnt)
             m.d.comb += ps.eq((cnt + np)*int(self.timings["tCK"]))
             state = Signal(4)
-            m.d.comb += state.eq(Cat(phase.we_n, phase.cas_n, phase.ras_n, phase.cs_n))
+            m.d.comb += state.eq(Cat(phase.we, phase.cas, phase.ras, phase.cs))
             all_banks = Signal()
 
             m.d.comb += all_banks.eq(
index 9296f4555021ba13052f94cfe281a3decabf3297..7ab925094d221a5183b784af83960a81c47bcffd 100644 (file)
@@ -68,9 +68,9 @@ class IcarusECPIX5Platform(LatticeECP5Platform):
                  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")),
-                 Subsignal("we_n", Pins("R3", dir="o")),
-                 Subsignal("ras_n", Pins("T3", dir="o")),
-                 Subsignal("cas_n", Pins("P2", dir="o")),
+                 Subsignal("we", PinsN("R3", dir="o")),
+                 Subsignal("ras", PinsN("T3", dir="o")),
+                 Subsignal("cas", PinsN("P2", dir="o")),
                  Subsignal("a", Pins("T5 M3 L3 V6 K2 W6 K3 L1 H2 L2 N1 J1 M1 K1", dir="o")),
                  Subsignal("ba", Pins("U6 N3 N4", dir="o")),
                  #Subsignal("dqs",    DiffPairs("V4 V1", "U5 U2", dir="io"), Attrs(IO_TYPE="SSTL135D_I")),
index a151897f1e20c318fb14b1d735df484ec64bf67b..abfded248fc20d921a522ad3bb5358e78e523a83 100644 (file)
@@ -30,7 +30,7 @@ class DDR3SoC(SoC, Elaboratable):
         self._arbiter.add(self.ub.bus)
 
         ddr_pins = platform.request("ddr3", 0, dir={"dq":"-", "dqs":"-"},
-            xdr={"clk":4, "a":4, "ba":4})
+            xdr={"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 e90c19e7ab80651c14284d1d5d9ca2b0f3238567..5c25c2fa8e453fa60238c92070ada6ec931ec03b 100644 (file)
@@ -79,9 +79,9 @@ module simsoctb;
     .ddr3_0__dqs__io(dram_dqs),
     .ddr3_0__clk__io(dram_ck),
     .ddr3_0__clk_en__io(dram_cke),
-    .ddr3_0__we_n__io(dram_we_n),
-    .ddr3_0__ras_n__io(dram_ras_n),
-    .ddr3_0__cas_n__io(dram_cas_n),
+    .ddr3_0__we__io(dram_we_n),
+    .ddr3_0__ras__io(dram_ras_n),
+    .ddr3_0__cas__io(dram_cas_n),
     .ddr3_0__a__io(dram_a),
     .ddr3_0__ba__io(dram_ba),
     .ddr3_0__dm__io(dram_dm),
index 6bb238e794a0a5412aeae0c5c5dd0b0991466df3..195c9171916a24e86fa07824008d07fc785eaf4c 100644 (file)
@@ -46,10 +46,10 @@ class PhaseInjectorTestCase(FHDLTestCase):
         m, dfi, csrhost = self.generate_phaseinjector()
 
         def process():
-            self.assertTrue((yield dfi.phases[0].cas_n))
-            self.assertTrue((yield dfi.phases[0].ras_n))
-            self.assertTrue((yield dfi.phases[0].we_n))
-            self.assertTrue((yield dfi.phases[0].act_n))
+            self.assertFalse((yield dfi.phases[0].cas))
+            self.assertFalse((yield dfi.phases[0].ras))
+            self.assertFalse((yield dfi.phases[0].we))
+            self.assertFalse((yield dfi.phases[0].act))
             self.assertFalse((yield dfi.phases[0].wrdata_mask))
             self.assertFalse((yield dfi.phases[0].rddata_en))
             self.assertFalse((yield dfi.phases[0].wrdata_en))
@@ -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_n))
+            self.assertTrue((yield dut.master.phases[0].reset))
 
             yield from wb_write(csrhost.bus, DFII_CONTROL_ADDR >> 2, 0, sel=0xF)
             yield
-            self.assertFalse((yield dut.master.phases[0].reset_n))
+            self.assertFalse((yield dut.master.phases[0].reset))
 
         runSimulation(m, process, "test_dfiinjector.vcd")
index d64e8721482f76b4440c25852315a882e57f8f60..290906571eb09321ea4f457a93b00d7f824f5ba2 100644 (file)
@@ -15,9 +15,9 @@ static void dfii_setcontrol(struct gramCtx *ctx, uint8_t val) {
 
 void dfii_setsw(struct gramCtx *ctx, bool software_control) {
        if (software_control) {
-               dfii_setcontrol(ctx, DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
+               dfii_setcontrol(ctx, DFII_CONTROL_CKE|DFII_CONTROL_ODT);
        } else {
-               dfii_setcontrol(ctx, DFII_CONTROL_SEL);
+               dfii_setcontrol(ctx, DFII_CONTROL_SEL|DFII_CONTROL_RESET);
        }
 }
 
@@ -60,13 +60,13 @@ void dfii_initseq(struct gramCtx *ctx) {
        /* Release reset */
        dfii_set_p0_address(ctx, 0x0);
        dfii_set_p0_baddress(ctx, 0);
-       dfii_setcontrol(ctx, DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
+       dfii_setcontrol(ctx, DFII_CONTROL_ODT);
        cdelay(50000);
 
        /* Bring CKE high */
        dfii_set_p0_address(ctx, 0x0);
        dfii_set_p0_baddress(ctx, 0);
-       dfii_setcontrol(ctx, DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
+       dfii_setcontrol(ctx, DFII_CONTROL_CKE|DFII_CONTROL_ODT);
        cdelay(10000);
 
        /* Load Mode Register 2, CWL=5 */
index 1d53306da5448493fc278ad02f13f48ccd9ca767..f57c3606df67211d670ac06fbe238de2f3b02268 100644 (file)
@@ -6,7 +6,7 @@
 #define DFII_CONTROL_SEL (1 << 0)
 #define DFII_CONTROL_CKE (1 << 1)
 #define DFII_CONTROL_ODT (1 << 2)
-#define DFII_CONTROL_RESET_N (1 << 3)
+#define DFII_CONTROL_RESET (1 << 3)
 
 #define DFII_COMMAND_CS (1 << 0)
 #define DFII_COMMAND_WE (1 << 1)