Started on implementing i/oe/bank_sel
authorAndrey Miroshnikov <andrey@technepisteme.xyz>
Fri, 7 Jan 2022 20:22:00 +0000 (20:22 +0000)
committerAndrey Miroshnikov <andrey@technepisteme.xyz>
Fri, 7 Jan 2022 20:22:00 +0000 (20:22 +0000)
src/spec/simple_gpio.py

index 86afebe3113d914ed60166d202816482632bb210..c6196bc32232cd242293e2e463d3bfdaf0ece870 100644 (file)
@@ -2,6 +2,8 @@
 
 This is an extremely simple GPIO peripheral intended for use in XICS
 testing, however it could also be used as an actual GPIO peripheral
+
+Modified for use with pinmux, will probably change the class name later.
 """
 
 from nmigen import Elaboratable, Module, Signal, Record, Array
@@ -28,7 +30,10 @@ class SimpleGPIO(Elaboratable):
         spec.mask_wid = 4
         spec.reg_wid = 32
         self.bus = Record(make_wb_layout(spec), name="gpio_wb")
+        self.bank_sel = Array([Signal(3) for _ in range(n_gpio)])
         self.gpio_o = Signal(n_gpio)
+        self.gpio_oe = Signal(n_gpio)
+        self.gpio_i = Signal(n_gpio)
 
     def elaborate(self, platform):
         m = Module()
@@ -38,20 +43,43 @@ class SimpleGPIO(Elaboratable):
         wb_rd_data = bus.dat_r
         wb_wr_data = bus.dat_w
         wb_ack = bus.ack
+
+        bank_sel = self.bank_sel
         gpio_o = self.gpio_o
+        gpio_oe = self.gpio_oe
+        gpio_i = self.gpio_i
 
         comb += wb_ack.eq(0)
 
         gpio_addr = Signal(log2_int(self.n_gpio))
         gpio_a = Array(list(gpio_o))
-
+        bank_sel_list = Array(list(bank_sel))
+        print(bank_sel)
+        print(bank_sel_list)
+        print(gpio_a)
+        gpio_oe_list = Array(list(gpio_o))
+        gpio_i_list = Array(list(gpio_i))
+
+        # Address first byte for GPIO (max would be 256 GPIOs)
+        # Address second byte, bit 0 indicates input read 
         with m.If(bus.cyc & bus.stb):
             comb += wb_ack.eq(1) # always ack
-            comb += gpio_addr.eq(bus.adr)
+            comb += gpio_addr.eq(bus.adr[0:8])
             with m.If(bus.we): # write
+                # Write to CSR - direction and bank select
                 sync += gpio_a[gpio_addr].eq(wb_wr_data[0])
+                sync += gpio_oe_list[gpio_addr].eq(wb_wr_data[1])
+                sync += bank_sel_list[gpio_addr].eq(wb_wr_data[5:8])
             with m.Else(): # read
-                comb += wb_rd_data.eq(gpio_a[gpio_addr])
+                # Read the value of the input
+                with m.If(bus.adr[8]):
+                    comb += wb_rd_data.eq(gpio_i_list[gpio_addr])
+                # Read the state of CSR bits
+                with m.Else():
+                    comb += wb_rd_data.eq(gpio_o[gpio_addr] 
+                                          + (gpio_oe[gpio_addr] << 1)
+                                          + (bank_sel_list[gpio_addr] << 5))
+                #comb += wb_rd_data.eq(gpio_a[gpio_addr])
 
         return m
 
@@ -75,31 +103,10 @@ def sim_gpio(gpio):
 
     # GPIO0
     data = yield from read_gpio(gpio, 0) # read gpio addr  0
-    assert data == 0
     
     yield from wb_write(gpio.bus, 0, 1) # write gpio addr 0
 
     data = yield from read_gpio(gpio, 0) # read gpio addr  0
-    assert data == 1
-
-    # GPIO1
-    data = yield from read_gpio(gpio, 1) # read gpio addr  1
-    assert data == 0
-    
-    yield from wb_write(gpio.bus, 1, 1) # write gpio addr 1
-
-    data = yield from read_gpio(gpio, 1) # read gpio addr  1
-    assert data == 1
-
-    # GPIO0
-    data = yield from read_gpio(gpio, 0) # read gpio addr  0
-    assert data == 1
-    
-    yield from wb_write(gpio.bus, 0, 0) # write gpio addr 0
-
-    data = yield from read_gpio(gpio, 0) # read gpio addr  0
-    assert data == 0
-
 
 def test_gpio():