top level signals not showing up yet
authorAndrey Miroshnikov <andrey@technepisteme.xyz>
Thu, 10 Mar 2022 23:37:32 +0000 (23:37 +0000)
committerAndrey Miroshnikov <andrey@technepisteme.xyz>
Thu, 10 Mar 2022 23:37:32 +0000 (23:37 +0000)
src/spec/pinmux.py

index 992eec6ee92329b6fcf85dcb22ea979da10e2d48..fda23c6a7fef6b7b78f2d0b8d8edf63dfca79f0b 100644 (file)
@@ -8,7 +8,7 @@ from nmigen import Elaboratable, Module, Signal, Record, Array, Cat
 from nmigen.hdl.rec import Layout
 from nmigen.utils import log2_int
 from nmigen.cli import rtlil
-#from soc.minerva.wishbone import make_wb_layout
+from soc.minerva.wishbone import make_wb_layout
 from nmutil.util import wrap
 #from soc.bus.test.wb_rw import wb_read, wb_write
 
@@ -21,16 +21,24 @@ else:
     from nmigen.sim import Simulator, Settle, Delay
 
 from iomux import IOMuxBlockSingle, io_layout
-from simple_gpio import SimpleGPIO
+from simple_gpio import SimpleGPIO, GPIOManager, csrbus_layout
 
 class PinMuxBlockSingle(Elaboratable):
 
-    def __init__(self):
+    def __init__(self, wb_wordsize):
         print("1-bit Pin Mux Block with JTAG")
         self.n_banks = 4
         self.bank = Signal(log2_int(self.n_banks))
         self.n_gpios = 1
-        self.wb_wordsize = 4 # 4 Bytes, 32-bits
+        self.wb_wordsize = wb_wordsize # 4 Bytes, 32-bits
+
+        # Create WB bus for the GPIO block
+        class Spec: pass
+        spec = Spec()
+        spec.addr_wid = 30
+        spec.mask_wid = 4
+        spec.reg_wid = self.wb_wordsize*8
+        self.bus = Record(make_wb_layout(spec), name="gpio_wb")
 
         temp = []
         for i in range(1, self.n_banks):
@@ -38,43 +46,66 @@ class PinMuxBlockSingle(Elaboratable):
             temp.append(Record(name=temp_str, layout=io_layout))
         self.periph_ports = Array(temp)
 
-        self.out_port = Record(name="IO", layout=io_layout)
+        self.pad_port = Record(name="IOPad", layout=io_layout)
+
+        self.iomux = IOMuxBlockSingle()
+        self.gpio = SimpleGPIO(self.wb_wordsize, self.n_gpios)
 
     def elaborate(self, platform):
         m = Module()
         comb, sync = m.d.comb, m.d.sync
-        iomux = IOMuxBlockSingle()
-        gpio = SimpleGPIO(self.wb_wordsize, self.n_gpios)
-        m.submodules.iomux += iomux
-        m.submodules.gpio += gpio
-
+        iomux = self.iomux
+        gpio = self.gpio
+        bus = self.bus
         bank = self.bank
         periph_ports = self.periph_ports
-        out_port = self.out_port
+        pad_port = self.pad_port
+
+        # Add blocks to submodules
+        m.submodules.iomux = iomux
+        m.submodules.gpio = gpio
 
         # Connect up modules and signals
+        # WB bus connection
+        gpio.bus.adr.eq(bus.adr)
+        gpio.bus.dat_w.eq(bus.dat_w)
+        bus.dat_r.eq(gpio.bus.dat_r)
+        gpio.bus.sel.eq(bus.sel)
+        gpio.bus.cyc.eq(bus.cyc)
+        gpio.bus.stb.eq(bus.stb)
+        bus.ack.eq(gpio.bus.ack)
+        gpio.bus.we.eq(bus.we)
+        bus.err.eq(gpio.bus.err)
+        gpio.bus.cti.eq(bus.cti) # Cycle Type Identifier
+        gpio.bus.bte.eq(bus.bte) # Burst Type Extension
+
         iomux.bank.eq(gpio.gpio_ports[0].bank)
 
         # WB GPIO always bank0
-        gpio.gpio_ports[0].o.eq(iomux.bank_ports[0].o)
-        gpio.gpio_ports[0].oe.eq(iomux.bank_ports[0].oe)
-        iomux.bank_ports[0].i.eq(gpio.gpio_ports[0].i)
+        iomux.bank_ports[0].o.eq(gpio.gpio_ports[0].o)
+        iomux.bank_ports[0].oe.eq(gpio.gpio_ports[0].oe)
+        gpio.gpio_ports[0].i.eq(iomux.bank_ports[0].i)
 
         # banks1-3 external
-        for bank in range(0, self.n_banks-1):
-            periph_ports[bank].o.eq(iomux.bank_ports[bank+1].o)
-            periph_ports[bank].oe.eq(iomux.bank_ports[bank+1].oe)
-            iomux.bank_ports[bank+1].i.eq(periph_ports[bank].i)
-
-        out_port.o.eq(iomux.out_port.o)
-        out_port.oe.eq(iomux.out_port.oe)
-        iomux.out_port.i.eq(out_port.i)
+        iomux.bank_ports[1].o.eq(periph_ports[0].o)
+        iomux.bank_ports[1].oe.eq(periph_ports[0].oe)
+        periph_ports[0].i.eq(iomux.bank_ports[1].i)
+        #for bank in range(0, self.n_banks-1):
+        #    iomux.bank_ports[bank+1].o.eq(periph_ports[bank].o)
+        #    iomux.bank_ports[bank+1].oe.eq(periph_ports[bank].oe)
+        #    periph_ports[bank].i.eq(iomux.bank_ports[bank+1].i)
+
+        pad_port.o.eq(iomux.out_port.o)
+        pad_port.oe.eq(iomux.out_port.oe)
+        iomux.out_port.i.eq(pad_port.i)
 
         return m
 
     def __iter__(self):
         """ Get member signals for Verilog form. """
-        for field in self.out_port.fields.values():
+        for field in self.pad_port.fields.values():
+            yield field
+        for field in self.gpio.bus.fields.values():
             yield field
         for bank in range(len(self.periph_ports)):
             for field in self.periph_ports[bank].fields.values():
@@ -84,7 +115,7 @@ class PinMuxBlockSingle(Elaboratable):
     def ports(self):
         return list(self)
 
-def gen_gtkw_doc(module_name, n_banks, filename):
+def gen_gtkw_doc(module_name, wordsize, n_banks, filename):
     # GTKWave doc generation
     style = {
         '': {'base': 'hex'},
@@ -95,6 +126,18 @@ def gen_gtkw_doc(module_name, n_banks, filename):
 
     # Create a trace list, each block expected to be a tuple()
     traces = []
+    wb_data_width = wordsize*8
+    wb_traces = ('Wishbone Bus', [
+                        ('gpio_wb__cyc', 'in'),
+                        ('gpio_wb__stb', 'in'),
+                        ('gpio_wb__we', 'in'),
+                        ('gpio_wb__adr[27:0]', 'in'),
+                        ('gpio_wb__dat_w[{}:0]'.format(wb_data_width-1), 'in'),
+                        ('gpio_wb__dat_r[{}:0]'.format(wb_data_width-1), 'out'),
+                        ('gpio_wb__ack', 'out'),
+                ])
+    traces.append(wb_traces)
+
     for bank in range(0, n_banks):
         temp_traces = ('Bank{}'.format(bank), [
                         ('bank{}__i'.format(bank), 'in'),
@@ -119,34 +162,52 @@ def gen_gtkw_doc(module_name, n_banks, filename):
                module=module_name)
 
 def sim_iomux():
-    filename = "test_pinmux" # Doesn't include extension
-    dut = PinMuxBlockSingle()
+    filename = "test_gpio_pinmux" # Doesn't include extension
+    wb_wordsize = 4
+    dut = PinMuxBlockSingle(wb_wordsize)
     vl = rtlil.convert(dut, ports=dut.ports())
     with open(filename+".il", "w") as f:
         f.write(vl)
 
-    #m = Module()
-    #m.submodules.pinmux = dut
+    print("Bus dir:")
+    print(dut.gpio.bus.adr)
+    print(dut.gpio.bus.fields)
+
+    m = Module()
+    m.submodules.pinmux = dut
 
-    #sim = Simulator(m)
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
 
-    #sim.add_process(wrap(test_iomux(dut)))
-    #sim_writer = sim.write_vcd(filename+".vcd")
-    #with sim_writer:
-    #    sim.run()
+    sim.add_sync_process(wrap(test_gpio_pinmux(dut)))
+    sim_writer = sim.write_vcd(filename+".vcd")
+    with sim_writer:
+        sim.run()
 
-    #gen_gtkw_doc("top.pinmux", dut.n_banks, filename)
+    gen_gtkw_doc("top.pinmux", wb_wordsize, dut.n_banks, filename)
 
-def test_iomux(dut):
+def test_gpio_pinmux(dut):
     print("------START----------------------")
     #print(dir(dut.bank_ports[0]))
     #print(dut.bank_ports[0].fields)
 
-    # TODO: turn into methods
-    yield from test_single_bank(dut, 0)
-    yield from test_single_bank(dut, 1)
-    yield from test_single_bank(dut, 2)
-    yield from test_single_bank(dut, 3)
+    gpios = GPIOManager(dut.gpio, csrbus_layout, dut.bus)
+
+    oe = 1
+    ie = 0
+    puen = 0
+    pden = 1
+    outval = 0
+    bank = 0
+    #yield from gpios.config("0", oe=1, ie=0, puen=0, pden=1, outval=0, bank=2)
+    yield dut.bus.adr.eq(0x1)
+    yield dut.bus.dat_w.eq(0xA5A5)
+
+    yield
+    yield dut.periph_ports[0].o.eq(1)
+    yield dut.periph_ports[0].oe.eq(1)
+    yield dut.pad_port.i.eq(1)
+
 
     print("Finished the 1-bit IO mux block test!")