From befdfb6b5be9bfcffd9ef0b033d23e639afcace7 Mon Sep 17 00:00:00 2001 From: Andrey Miroshnikov Date: Tue, 11 Jan 2022 23:33:47 +0000 Subject: [PATCH] GPIO extension almost working, input still needs fix to the set function --- src/spec/simple_gpio.py | 98 +++++++++++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/src/spec/simple_gpio.py b/src/spec/simple_gpio.py index c6196bc..8891e16 100644 --- a/src/spec/simple_gpio.py +++ b/src/spec/simple_gpio.py @@ -17,8 +17,17 @@ cxxsim = False if cxxsim: from nmigen.sim.cxxsim import Simulator, Settle else: - from nmigen.back.pysim import Simulator, Settle - + from nmigen.sim import Simulator, Settle + +# Bit shift position for CSR word used in WB transactions +IADDRSHIFT = 8 # offset needed to tell WB to return input ONLY +# Layout of 16-bit configuration word (? is unused): +# ? ? ? i | bank_select[3:0] |? pden puen opendrain |? ien oe o +ISHIFT = 12 +BANKSHIFT = 8 +# Pull-up/down, open-drain, ien have been skipped for now +OESHIFT = 1 +OSHIFT = 0 class SimpleGPIO(Elaboratable): @@ -30,7 +39,8 @@ 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)]) + # ONLY ONE BANK FOR ALL GPIOs atm... + self.bank_sel = Signal(4) # set maximum number of banks to 16 self.gpio_o = Signal(n_gpio) self.gpio_oe = Signal(n_gpio) self.gpio_i = Signal(n_gpio) @@ -52,12 +62,10 @@ class SimpleGPIO(Elaboratable): 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)) + gpio_o_list = Array(list(gpio_o)) print(bank_sel) - print(bank_sel_list) - print(gpio_a) - gpio_oe_list = Array(list(gpio_o)) + print(gpio_o_list) + gpio_oe_list = Array(list(gpio_oe)) gpio_i_list = Array(list(gpio_i)) # Address first byte for GPIO (max would be 256 GPIOs) @@ -66,19 +74,19 @@ class SimpleGPIO(Elaboratable): comb += wb_ack.eq(1) # always ack 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]) + # Write to CSR + sync += gpio_o_list[gpio_addr].eq(wb_wr_data[OSHIFT]) + sync += gpio_oe_list[gpio_addr].eq(wb_wr_data[OESHIFT]) + sync += bank_sel.eq(wb_wr_data[BANKSHIFT:BANKSHIFT+4]) with m.Else(): # read # 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_o_list[gpio_addr] << OSHIFT) + + (gpio_oe_list[gpio_addr] << OESHIFT) + + (bank_sel << BANKSHIFT)) #comb += wb_rd_data.eq(gpio_a[gpio_addr]) return m @@ -93,20 +101,64 @@ class SimpleGPIO(Elaboratable): -def read_gpio(gpio, addr): - data = yield from wb_read(gpio.bus, addr) - print ("gpio%d" % addr, hex(data), bin(data)) +def gpio_configure(dut, gpio, oe, output=0, bank_sel=0): + csr_val = ( (bank_sel << BANKSHIFT) + | (oe << OESHIFT) + | (output << OSHIFT) ) + # | (PUEN, PDUN, Open-drain etc...) + print("Configuring CSR to {0:x}".format(csr_val)) + yield from wb_write(dut.bus, gpio, csr_val) + +def gpio_rd_csr(dut, gpio): + csr_val = yield from wb_read(dut.bus, gpio) + print("GPIO{0} | CSR: {1:x}".format(gpio, csr_val)) + # gpio_parse_csr(csr_val) + return data + +def gpio_rd_input(dut, gpio): + in_val = yield from wb_read(dut.bus, gpio | (1<