tidyup on gramWishbone class, add comments
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 10 Mar 2022 12:33:15 +0000 (12:33 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 10 Mar 2022 12:33:15 +0000 (12:33 +0000)
gram/core/multiplexer.py
gram/frontend/wishbone.py
gram/phy/ecp5ddrphy.py
gram/simulation/icarusecpix5platform.py
gram/simulation/simsoctb.v

index 69d9fb4fc627803f481f5232c0cb1a488e3f1668..9e9b40d26b8bbdc72f0b1a38a4b8b061494f4ba9 100644 (file)
@@ -173,9 +173,9 @@ class _Steerer(Elaboratable):
                     with m.If(sel == STEER_REFRESH):
                         m.d.sync += phase.cs_n.eq(0)
                     with m.Else():
-                        m.d.sync += phase.cs_n.eq(rank_decoder.o)
+                        m.d.sync += phase.cs_n.eq(~rank_decoder.o)
                 else:
-                    m.d.sync += phase.cs_n.eq(rank_decoder.o)
+                    m.d.sync += phase.cs_n.eq(~rank_decoder.o)
                 m.d.sync += phase.bank.eq(Array(cmd.ba[:-rankbits] for cmd in self.commands)[sel])
             else:
                 m.d.sync += [
index 0b04444e45d52c2158d54087bae9b8ce3e8475a1..984eb71aa11967bac10cb669983eb0e20f2545ca 100644 (file)
@@ -48,61 +48,71 @@ class gramWishbone(Peripheral, Elaboratable):
 
     def elaborate(self, platform):
         m = Module()
+        comb = m.d.comb
         cmd = self.native_port.cmd
         wdata = self.native_port.wdata
         rdata = self.native_port.rdata
+        bus = self.bus
 
         # Write datapath
-        m.d.comb += wdata.valid.eq(self.bus.cyc & self.bus.stb & self.bus.we)
+        comb += wdata.valid.eq(bus.cyc & bus.stb & bus.we)
 
         ratio_bitmask = Repl(1, log2_int(self.ratio))
 
-        sel = Signal.like(self.bus.sel)
-        with m.If(self.bus.sel == 0):
-            m.d.comb += sel.eq(Repl(1, sel.width))
+        # XXX? sel is zero being compensated-for as all 1s does not seem right
+        sel = Signal.like(bus.sel)
+        with m.If(bus.sel == 0):
+            comb += sel.eq(-1) # all 1s
         with m.Else():
-            m.d.comb += sel.eq(self.bus.sel)
+            comb += sel.eq(bus.sel)
 
-        with m.Switch(self.bus.adr & ratio_bitmask):
+        with m.Switch(bus.adr & ratio_bitmask): # XXX adr changes (WB4-pipe)
             for i in range(self.ratio):
                 with m.Case(i):
-                    m.d.comb += wdata.we.eq(Repl(sel, self.bus.granularity//8) << (self.ratio*i))
-
-        with m.Switch(self.bus.adr & ratio_bitmask):
-            for i in range(self.ratio):
-                with m.Case(i):
-                    m.d.comb += wdata.data.eq(self.bus.dat_w << (self.bus.data_width*i))
+                    # write-enable
+                    we = Repl(sel, bus.granularity//8) << (self.ratio*i)
+                    comb += wdata.we.eq(we)
+                    # write-data
+                    data = bus.dat_w << (bus.data_width*i)
+                    comb += wdata.data.eq(data)
 
         # Read datapath
-        m.d.comb += rdata.ready.eq(1)
+        comb += rdata.ready.eq(1)
 
-        with m.Switch(self.bus.adr & ratio_bitmask):
+        with m.Switch(bus.adr & ratio_bitmask): # XXX adr changes (WB4-pipe)
             for i in range(self.ratio):
                 with m.Case(i):
-                    m.d.comb += self.bus.dat_r.eq(rdata.data >> (self.bus.data_width*i))
+                    data = rdata.data >> (bus.data_width*i)
+                    comb += bus.dat_r.eq(data)
 
+        # Command FSM
         with m.FSM():
+            # raise a command when WB has a request
             with m.State("Send-Cmd"):
-                m.d.comb += [
-                    cmd.valid.eq(self.bus.cyc & self.bus.stb),
-                    cmd.we.eq(self.bus.we),
-                    cmd.addr.eq(self.bus.adr >> log2_int(self.bus.data_width//self.bus.granularity)),
+                # XXX this logic is only WB 3.0 classic compatible!
+                comb += [
+                    cmd.valid.eq(bus.cyc & bus.stb),
+                    cmd.we.eq(bus.we),
+                    cmd.addr.eq(bus.adr >> self.dsize),
                 ]
 
+                # when cmd is accepted, move to either read or write FSM
                 with m.If(cmd.valid & cmd.ready):
-                    with m.If(self.bus.we):
+                    with m.If(bus.we):
                         m.next = "Wait-Write"
                     with m.Else():
                         m.next = "Wait-Read"
 
+            # read-wait: when read valid, ack the WB bus, return idle
             with m.State("Wait-Read"):
                 with m.If(rdata.valid):
-                    m.d.comb += self.bus.ack.eq(1)
+                    comb += bus.ack.eq(1)
                     m.next = "Send-Cmd"
 
+            # write-wait: when write valid, ack the WB bus, return idle
             with m.State("Wait-Write"):
                 with m.If(wdata.ready):
-                    m.d.comb += self.bus.ack.eq(1)
+                    comb += bus.ack.eq(1)
                     m.next = "Send-Cmd"
 
         return m
index ce13c99d8d76a1f242dc40c1a482fc8a3dc90f81..a31dfb373b521ca0365f6bb79017d4ce4e8f0f9a 100644 (file)
@@ -174,6 +174,7 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
 
     def elaborate(self, platform):
         m = Module()
+        comb, sync = m.d.comb, m.d.sync
 
         m.submodules.bridge = self._bridge
 
@@ -405,12 +406,12 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
             ]
 
             for j in range(8*i, 8*(i+1)):
-                dq_o = Signal()
-                dq_i = Signal()
-                dq_oe_n = Signal()
-                dq_i_delayed = Signal()
-                dq_i_data = Signal(4)
-                dq_o_data = Signal(8)
+                dq_o = Signal(name="dq_o_%d" % j)
+                dq_i = Signal(name="dq_i_%d" % j)
+                dq_oe_n = Signal(name="dq_oe_n_%d" % j)
+                dq_i_delayed = Signal(name="dq_i_delayed_%d" % j)
+                dq_i_data = Signal(4, name="dq_i_data_%d" % j)
+                dq_o_data = Signal(8, name="dq_o_data_%d" % j)
                 dq_o_data_d = Signal(8, reset_less=True)
                 dq_o_data_muxed = Signal(4, reset_less=True)
                 m.d.comb += dq_o_data.eq(Cat(
@@ -478,20 +479,28 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                         o_O=dq_i,
                         io_B=self.pads.dq.io[j])
                 ]
-                with m.If(~datavalid_prev & datavalid):
-                    m.d.sync += [
-                        dfi.phases[0].rddata[0*databits+j].eq(dq_i_data[0]),
-                        dfi.phases[0].rddata[1*databits+j].eq(dq_i_data[1]),
-                        dfi.phases[0].rddata[2*databits+j].eq(dq_i_data[2]),
-                        dfi.phases[0].rddata[3*databits+j].eq(dq_i_data[3]),
-                    ]
-                with m.Elif(datavalid):
-                    m.d.sync += [
-                        dfi.phases[1].rddata[0*databits+j].eq(dq_i_data[0]),
-                        dfi.phases[1].rddata[1*databits+j].eq(dq_i_data[1]),
-                        dfi.phases[1].rddata[2*databits+j].eq(dq_i_data[2]),
-                        dfi.phases[1].rddata[3*databits+j].eq(dq_i_data[3]),
-                    ]
+                # shift-register delay on the incoming read data
+                dq_i_bs = BitSlip(4, Const(0), Const(0), cycles=1)
+                m.submodules['dq_i_bitslip_%d' % j] = dq_i_bs
+                dq_i_bs_o = Signal(4, name="dq_i_bs_o_%d" % j)
+                dq_i_bs_o_d = Signal(4, name="dq_i_bs_o_d_%d" % j)
+                comb += dq_i_bs.i.eq(dq_i_data)
+                comb += dq_i_bs_o.eq(dq_i_bs.o)
+                sync += dq_i_bs_o_d.eq(dq_i_bs_o) # delay by 1 clock
+                #with m.If(~datavalid_prev & datavalid):
+                comb += [
+                    dfi.phases[0].rddata[0*databits+j].eq(dq_i_bs_o_d[0]),
+                    dfi.phases[0].rddata[1*databits+j].eq(dq_i_bs_o_d[1]),
+                    dfi.phases[0].rddata[2*databits+j].eq(dq_i_bs_o_d[2]),
+                    dfi.phases[0].rddata[3*databits+j].eq(dq_i_bs_o_d[3]),
+                ]
+                #with m.Elif(datavalid):
+                comb += [
+                    dfi.phases[1].rddata[0*databits+j].eq(dq_i_bs_o[0]),
+                    dfi.phases[1].rddata[1*databits+j].eq(dq_i_bs_o[1]),
+                    dfi.phases[1].rddata[2*databits+j].eq(dq_i_bs_o[2]),
+                    dfi.phases[1].rddata[3*databits+j].eq(dq_i_bs_o[3]),
+                ]
 
         # Read Control Path ------------------------------------------------------------------------
         # Creates a shift register of read commands coming from the DFI interface. This shift register
@@ -507,12 +516,10 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
         rddata_en_last = Signal.like(rddata_en)
         m.d.comb += rddata_en.eq(Cat(dfi.phases[self.settings.rdphase].rddata_en, rddata_en_last))
         m.d.sync += rddata_en_last.eq(rddata_en)
+        for phase in dfi.phases:
+            m.d.sync += phase.rddata_valid.eq(rddata_en[-1])
         m.d.comb += dqs_re.eq(rddata_en[cl_sys_latency + 1] | rddata_en[cl_sys_latency + 2])
 
-        rddata_valid = Signal()
-        m.d.sync += rddata_valid.eq(datavalid_prev & ~datavalid)
-        for phase in dfi.phases:
-            m.d.comb += phase.rddata_valid.eq(rddata_valid)
 
         # Write Control Path -----------------------------------------------------------------------
         # Creates a shift register of write commands coming from the DFI interface. This shift register
index b3b5a1b3bf5c61314624819f7bb151fd2ffeacbc..7b4b6018574860d2bd49e322362ac78419a8a99a 100644 (file)
@@ -27,7 +27,7 @@ class IcarusECPIX5Platform(LatticeECP5Platform):
                      ),
 
         Resource("ddr3", 0,
-                 Subsignal("rst", Pins("fake", dir="o")), # for sim
+                 Subsignal("rst", PinsN("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 54c76e4bc2f974ebad6e0ba3d255db641b817614..5afa17f3c72d62583030195d6730606972ba95a5 100644 (file)
@@ -43,10 +43,12 @@ module simsoctb;
   wire [1:0] dram_tdqs_n;
   wire dram_rst;
 
+  // anything here with "_n" has to be inverted.  nmigen platforms
+  // sort that out by inverting (with PinsN)
   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),
@@ -82,7 +84,7 @@ module simsoctb;
     .ddr3_0__rst__io(dram_rst),
     .ddr3_0__dq__io(dram_dq),
     .ddr3_0__dqs__p(dram_dqs),
-    .ddr3_0__clk__io(dram_ck),
+    .ddr3_0__clk__p(dram_ck),
     .ddr3_0__clk_en__io(dram_cke),
     .ddr3_0__we__io(dram_we_n),
     .ddr3_0__cs__io(dram_cs_n),