From 072bcec12dc08f9e41f61c9deecd981afc6d9629 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 22 Jul 2018 10:22:20 +0100 Subject: [PATCH] refactor peripheral_gen, split out interface classes --- src/bsv/peripheral_gen/__init__.py | 9 +- src/bsv/peripheral_gen/base.py | 558 +---------------------------- src/bsv/peripheral_gen/eint.py | 56 +++ src/bsv/peripheral_gen/gpio.py | 86 +++++ src/bsv/peripheral_gen/jtag.py | 34 ++ src/bsv/peripheral_gen/pwm.py | 21 ++ src/bsv/peripheral_gen/qspi.py | 74 ++++ src/bsv/peripheral_gen/quart.py | 75 ++++ src/bsv/peripheral_gen/rs232.py | 30 ++ src/bsv/peripheral_gen/sdmmc.py | 31 ++ src/bsv/peripheral_gen/spi.py | 60 ++++ src/bsv/peripheral_gen/twi.py | 54 +++ src/bsv/peripheral_gen/uart.py | 28 ++ 13 files changed, 570 insertions(+), 546 deletions(-) create mode 100644 src/bsv/peripheral_gen/eint.py create mode 100644 src/bsv/peripheral_gen/gpio.py create mode 100644 src/bsv/peripheral_gen/jtag.py create mode 100644 src/bsv/peripheral_gen/pwm.py create mode 100644 src/bsv/peripheral_gen/qspi.py create mode 100644 src/bsv/peripheral_gen/quart.py create mode 100644 src/bsv/peripheral_gen/rs232.py create mode 100644 src/bsv/peripheral_gen/sdmmc.py create mode 100644 src/bsv/peripheral_gen/spi.py create mode 100644 src/bsv/peripheral_gen/twi.py create mode 100644 src/bsv/peripheral_gen/uart.py diff --git a/src/bsv/peripheral_gen/__init__.py b/src/bsv/peripheral_gen/__init__.py index 0e1bfdb..42cac84 100644 --- a/src/bsv/peripheral_gen/__init__.py +++ b/src/bsv/peripheral_gen/__init__.py @@ -1,6 +1,13 @@ -from base import PeripheralInterfaces +from bsv.peripheral_gen.base import PeripheralInterfaces, PeripheralIface from uart import uart from quart import quart from sdmmc import sdmmc from pwm import pwm from eint import eint +from rs232 import rs232 +from twi import twi +from eint import eint +from jtag import jtag +from spi import spi +from qspi import qspi +from gpio import gpio diff --git a/src/bsv/peripheral_gen/base.py b/src/bsv/peripheral_gen/base.py index 15d0295..c77e1cf 100644 --- a/src/bsv/peripheral_gen/base.py +++ b/src/bsv/peripheral_gen/base.py @@ -1,6 +1,4 @@ import types -from copy import deepcopy - class PBase(object): def __init__(self, name): @@ -193,548 +191,6 @@ mkplic_rule = """\ endrule """ -class uart(PBase): - - def slowimport(self): - return " import Uart_bs :: *;\n" + \ - " import RS232_modified::*;" - - def slowifdecl(self): - return " interface RS232 uart{0}_coe;\n" + \ - " method Bit#(1) uart{0}_intr;" - - def num_axi_regs32(self): - return 8 - - def mkslow_peripheral(self, size=0): - return " Ifc_Uart_bs uart{0} <- \n" + \ - " mkUart_bs(clocked_by sp_clock,\n" + \ - " reset_by uart_reset, sp_clock, sp_reset);" - - def _mk_connection(self, name=None, count=0): - return "uart{0}.slave_axi_uart" - - def pinname_out(self, pname): - return {'tx': 'coe_rs232.sout'}.get(pname, '') - - def pinname_in(self, pname): - return {'rx': 'coe_rs232.sin'}.get(pname, '') - - -class quart(PBase): - - def slowimport(self): - return " import Uart16550 :: *;" - - def slowifdecl(self): - return " interface RS232_PHY_Ifc quart{0}_coe;\n" + \ - " method Bit#(1) quart{0}_intr;" - - def num_axi_regs32(self): - return 8 - - def mkslow_peripheral(self, size=0): - return " Uart16550_AXI4_Lite_Ifc quart{0} <- \n" + \ - " mkUart16550(clocked_by sp_clock,\n" + \ - " reset_by uart_reset, sp_clock, sp_reset);" - - def _mk_connection(self, name=None, count=0): - return "quart{0}.slave_axi_uart" - - def pinname_out(self, pname): - return {'tx' : 'coe_rs232.modem_output_stx', - 'rts': 'coe_rs232.modem_output_rts', - }.get(pname, '') - - def _pinname_in(self, pname): - return {'rx': 'coe_rs232.modem_input.srx', - 'cts': 'coe_rs232.modem_input.cts' - }.get(pname, '') - - def mk_pincon(self, name, count): - ret = [PBase.mk_pincon(self, name, count)] - ret.append(" rule con_%s%d_io_in;" % (name, count)) - ret.append(" {0}{1}.coe_rs232.modem_input(".format(name, count)) - for idx, pname in enumerate(['rx', 'cts']): - sname = self.peripheral.pname(pname).format(count) - ps = "pinmux.peripheral_side.%s" % sname - ret.append(" {0},".format(ps)) - ret.append(" 1'b1,1'b0,1'b1") - ret.append(" );") - ret.append(" endrule") - - return '\n'.join(ret) - - def num_irqs(self): - return 1 - - def plic_object(self, pname, idx): - return "{0}_interrupt.read".format(pname) - - def mk_plic(self, inum, irq_offs): - name = self.get_iname(inum) - ret = [uart_plic_template.format(name, irq_offs)] - (ret2, irq_offs) = PBase.mk_plic(self, inum, irq_offs) - ret.append(ret2) - return ('\n'.join(ret), irq_offs) - - def mk_ext_ifacedef(self, iname, inum): - name = self.get_iname(inum) - return " method {0}_intr = {0}.irq;".format(name) - - def slowifdeclmux(self): - return " method Bit#(1) {1}{0}_intr;" - -uart_plic_template = """\ - // PLIC {0} synchronisation with irq {1} - SyncBitIfc#(Bit#(1)) {0}_interrupt <- - mkSyncBitToCC(sp_clock, uart_reset); - rule plic_synchronize_{0}_interrupt_{1}; - {0}_interrupt.send({0}.irq); - endrule -""" - -class rs232(PBase): - - def slowimport(self): - return " import Uart_bs::*;\n" + \ - " import RS232_modified::*;" - - def slowifdecl(self): - return " interface RS232 uart{0}_coe;" - - def num_axi_regs32(self): - return 2 - - def mkslow_peripheral(self, size=0): - return " //Ifc_Uart_bs uart{0} <-" + \ - " // mkUart_bs(clocked_by uart_clock,\n" + \ - " // reset_by uart_reset,sp_clock, sp_reset);" +\ - " Ifc_Uart_bs uart{0} <-" + \ - " mkUart_bs(clocked_by sp_clock,\n" + \ - " reset_by sp_reset, sp_clock, sp_reset);" - - def _mk_connection(self, name=None, count=0): - return "uart{0}.slave_axi_uart" - - def pinname_out(self, pname): - return {'tx': 'coe_rs232.sout'}.get(pname, '') - - def pinname_in(self, pname): - return {'rx': 'coe_rs232.sin'}.get(pname, '') - - -class twi(PBase): - - def slowimport(self): - return " import I2C_top :: *;" - - def slowifdecl(self): - return " interface I2C_out twi{0}_out;\n" + \ - " method Bit#(1) twi{0}_isint;" - - def num_axi_regs32(self): - return 8 - - def mkslow_peripheral(self, size=0): - return " I2C_IFC twi{0} <- mkI2CController();" - - def _mk_connection(self, name=None, count=0): - return "twi{0}.slave_i2c_axi" - - def pinname_out(self, pname): - return {'sda': 'out.sda_out', - 'scl': 'out.scl_out'}.get(pname, '') - - def pinname_in(self, pname): - return {'sda': 'out.sda_in', - 'scl': 'out.scl_in'}.get(pname, '') - - def pinname_outen(self, pname): - return {'sda': 'out.sda_out_en', - 'scl': 'out.scl_out_en'}.get(pname, '') - - def pinname_tweak(self, pname, typ, txt): - if typ == 'outen': - return "pack({0})".format(txt) - return txt - - def num_irqs(self): - return 3 - - def plic_object(self, pname, idx): - return ["{0}.isint()", - "{0}.timerint()", - "{0}.isber()" - ][idx].format(pname) - - def mk_ext_ifacedef(self, iname, inum): - name = self.get_iname(inum) - return " method {0}_isint = {0}.isint;".format(name) - - def slowifdeclmux(self): - return " method Bit#(1) {1}{0}_isint;" - - -class eint(PBase): - - def slowimport(self): - size = len(self.peripheral.pinspecs) - return " `define NUM_EINTS %d" % size - - def mkslow_peripheral(self, size=0): - size = len(self.peripheral.pinspecs) - return " Wire#(Bit#(%d)) wr_interrupt <- mkWire();" % size - - def axi_slave_name(self, name, ifacenum): - return '' - - def axi_slave_idx(self, idx, name, ifacenum): - return ('', 0) - - def axi_addr_map(self, name, ifacenum): - return '' - - def ifname_tweak(self, pname, typ, txt): - if typ != 'in': - return txt - print "ifnameweak", pname, typ, txt - return "wr_interrupt[{0}] <= ".format(pname) - - def mk_pincon(self, name, count): - ret = [PBase.mk_pincon(self, name, count)] - size = len(self.peripheral.pinspecs) - ret.append(eint_pincon_template.format(size)) - ret.append(" rule con_%s%d_io_in;" % (name, count)) - ret.append(" wr_interrupt <= ({") - for idx, p in enumerate(self.peripheral.pinspecs): - pname = p['name'] - sname = self.peripheral.pname(pname).format(count) - ps = "pinmux.peripheral_side.%s" % sname - comma = '' if idx == size - 1 else ',' - ret.append(" {0}{1}".format(ps, comma)) - ret.append(" });") - ret.append(" endrule") - - return '\n'.join(ret) - - -eint_pincon_template = '''\ - // EINT is offset at end of other peripheral interrupts -`ifdef PLIC - for(Integer i=0;i<{0};i=i+ 1)begin - rule connect_int_to_plic(wr_interrupt[i]==1); - ff_gateway_queue[i+`NUM_SLOW_IRQS].enq(1); - plic.ifc_external_irq[i+`NUM_SLOW_IRQS].irq_frm_gateway(True); - endrule - end -`endif -''' - - -class jtag(PBase): - - def axi_slave_name(self, name, ifacenum): - return '' - - def axi_slave_idx(self, idx, name, ifacenum): - return ('', 0) - - def axi_addr_map(self, name, ifacenum): - return '' - - def slowifdeclmux(self): - return " method Action jtag_ms (Bit#(1) in);\n" + \ - " method Bit#(1) jtag_di;\n" + \ - " method Action jtag_do (Bit#(1) in);\n" + \ - " method Action jtag_ck (Bit#(1) in);" - - def slowifinstance(self): - return jtag_method_template # bit of a lazy hack this... - -jtag_method_template = """\ - method Action jtag_ms (Bit#(1) in); - pinmux.peripheral_side.jtag_ms(in); - endmethod - method Bit#(1) jtag_di=pinmux.peripheral_side.jtag_di; - method Action jtag_do (Bit#(1) in); - pinmux.peripheral_side.jtag_do(in); - endmethod - method Action jtag_ck (Bit#(1) in); - pinmux.peripheral_side.jtag_ck(in); - endmethod -""" - -class sdmmc(PBase): - - def slowimport(self): - return " import sdcard_dummy :: *;" - - def slowifdecl(self): - return " interface QSPI_out sd{0}_out;\n" + \ - " method Bit#(1) sd{0}_isint;" - - def num_axi_regs32(self): - return 13 - - def mkslow_peripheral(self): - return " Ifc_sdcard_dummy sd{0} <- mksdcard_dummy();" - - def _mk_connection(self, name=None, count=0): - return "sd{0}.slave" - - def pinname_in(self, pname): - return "%s_in" % pname - - def pinname_out(self, pname): - if pname.startswith('d'): - return "%s_out" % pname - return pname - - def pinname_outen(self, pname): - if pname.startswith('d'): - return "%s_outen" % pname - - -class spi(PBase): - - def slowimport(self): - return " import qspi :: *;" - - def slowifdecl(self): - return " interface QSPI_out spi{0}_out;\n" + \ - " method Bit#(1) spi{0}_isint;" - - def num_axi_regs32(self): - return 13 - - def mkslow_peripheral(self): - return " Ifc_qspi spi{0} <- mkqspi();" - - def _mk_connection(self, name=None, count=0): - return "spi{0}.slave" - - def pinname_out(self, pname): - return {'clk': 'out.clk_o', - 'nss': 'out.ncs_o', - 'mosi': 'out.io_o[0]', - 'miso': 'out.io_o[1]', - }.get(pname, '') - - def pinname_outen(self, pname): - return {'clk': 1, - 'nss': 1, - 'mosi': 'out.io_enable[0]', - 'miso': 'out.io_enable[1]', - }.get(pname, '') - - def mk_pincon(self, name, count): - ret = [PBase.mk_pincon(self, name, count)] - # special-case for gpio in, store in a temporary vector - plen = len(self.peripheral.pinspecs) - ret.append(" // XXX NSS and CLK are hard-coded master") - ret.append(" // TODO: must add spi slave-mode") - ret.append(" // all ins done in one rule from 4-bitfield") - ret.append(" rule con_%s%d_io_in;" % (name, count)) - ret.append(" {0}{1}.out.io_i({{".format(name, count)) - for idx, pname in enumerate(['mosi', 'miso']): - sname = self.peripheral.pname(pname).format(count) - ps = "pinmux.peripheral_side.%s_in" % sname - ret.append(" {0},".format(ps)) - ret.append(" 1'b0,1'b0") - ret.append(" });") - ret.append(" endrule") - return '\n'.join(ret) - - def mk_ext_ifacedef(self, iname, inum): - name = self.get_iname(inum) - return " method {0}_isint = {0}.interrupts[5];".format(name) - - def slowifdeclmux(self): - return " method Bit#(1) {1}{0}_isint;" - - -class qspi(PBase): - - def slowimport(self): - return " import qspi :: *;" - - def slowifdecl(self): - return " interface QSPI_out qspi{0}_out;\n" + \ - " method Bit#(1) qspi{0}_isint;" - - def num_axi_regs32(self): - return 13 - - def mkslow_peripheral(self, size=0): - return " Ifc_qspi qspi{0} <- mkqspi();" - - def _mk_connection(self, name=None, count=0): - return "qspi{0}.slave" - - def pinname_out(self, pname): - return {'ck': 'out.clk_o', - 'nss': 'out.ncs_o', - 'io0': 'out.io_o[0]', - 'io1': 'out.io_o[1]', - 'io2': 'out.io_o[2]', - 'io3': 'out.io_o[3]', - }.get(pname, '') - - def pinname_outen(self, pname): - return {'ck': 1, - 'nss': 1, - 'io0': 'out.io_enable[0]', - 'io1': 'out.io_enable[1]', - 'io2': 'out.io_enable[2]', - 'io3': 'out.io_enable[3]', - }.get(pname, '') - - def mk_pincon(self, name, count): - ret = [PBase.mk_pincon(self, name, count)] - # special-case for gpio in, store in a temporary vector - plen = len(self.peripheral.pinspecs) - ret.append(" // XXX NSS and CLK are hard-coded master") - ret.append(" // TODO: must add qspi slave-mode") - ret.append(" // all ins done in one rule from 4-bitfield") - ret.append(" rule con_%s%d_io_in;" % (name, count)) - ret.append(" {0}{1}.out.io_i({{".format(name, count)) - for i, p in enumerate(self.peripheral.pinspecs): - typ = p['type'] - pname = p['name'] - if not pname.startswith('io'): - continue - idx = pname[1:] - n = name - sname = self.peripheral.pname(pname).format(count) - ps = "pinmux.peripheral_side.%s_in" % sname - comma = '' if i == 5 else ',' - ret.append(" {0}{1}".format(ps, comma)) - ret.append(" });") - ret.append(" endrule") - return '\n'.join(ret) - - def num_irqs(self): - return 6 - - def plic_object(self, pname, idx): - return "{0}.interrupts()[{1}]".format(pname, idx) - - def mk_ext_ifacedef(self, iname, inum): - name = self.get_iname(inum) - return " method {0}_isint = {0}.interrupts[5];".format(name) - - def slowifdeclmux(self): - return " method Bit#(1) {1}{0}_isint;" - - - -class pwm(PBase): - - def slowimport(self): - return " import pwm::*;" - - def slowifdecl(self): - return " interface PWMIO pwm{0}_io;" - - def num_axi_regs32(self): - return 4 - - def mkslow_peripheral(self, size=0): - return " Ifc_PWM_bus pwm{0} <- mkPWM_bus(sp_clock);" - - def _mk_connection(self, name=None, count=0): - return "pwm{0}.axi4_slave" - - def pinname_out(self, pname): - return {'out': 'pwm_io.pwm_o'}.get(pname, '') - - -class gpio(PBase): - - def slowimport(self): - return " import pinmux::*;\n" + \ - " import mux::*;\n" + \ - " import gpio::*;\n" - - def slowifdeclmux(self): - size = len(self.peripheral.pinspecs) - return " interface GPIO_config#(%d) pad_config{0};" % size - - def num_axi_regs32(self): - return 2 - - def axi_slave_idx(self, idx, name, ifacenum): - """ generates AXI slave number definition, except - GPIO also has a muxer per bank - """ - name = name.upper() - mname = 'mux' + name[4:] - mname = mname.upper() - print "AXIslavenum", name, mname - (ret, x) = PBase.axi_slave_idx(self, idx, name, ifacenum) - (ret2, x) = PBase.axi_slave_idx(self, idx + 1, mname, ifacenum) - return ("%s\n%s" % (ret, ret2), 2) - - def mkslow_peripheral(self, size=0): - print "gpioslow", self.peripheral, dir(self.peripheral) - size = len(self.peripheral.pinspecs) - return " MUX#(%d) mux{0} <- mkmux();\n" % size + \ - " GPIO#(%d) gpio{0} <- mkgpio();" % size - - def mk_connection(self, count): - print "GPIO mk_conn", self.name, count - res = [] - dname = self.mksuffix(self.name, count) - for i, n in enumerate(['gpio' + dname, 'mux' + dname]): - res.append(PBase.mk_connection(self, count, n)) - return '\n'.join(res) - - def _mk_connection(self, name=None, count=0): - n = self.mksuffix(name, count) - if name.startswith('gpio'): - return "gpio{0}.axi_slave".format(n) - if name.startswith('mux'): - return "mux{0}.axi_slave".format(n) - - def mksuffix(self, name, i): - if name.startswith('mux'): - return name[3:] - return name[4:] - - def mk_cellconn(self, cellnum, name, count): - ret = [] - bank = self.mksuffix(name, count) - txt = " pinmux.mux_lines.cell{0}_mux(mux{1}.mux_config.mux[{2}]);" - for p in self.peripheral.pinspecs: - ret.append(txt.format(cellnum, bank, p['name'][1:])) - cellnum += 1 - return ("\n".join(ret), cellnum) - - def pinname_out(self, pname): - return "func.gpio_out[{0}]".format(pname[1:]) - - def pinname_outen(self, pname): - return "func.gpio_out_en[{0}]".format(pname[1:]) - - def mk_pincon(self, name, count): - ret = [PBase.mk_pincon(self, name, count)] - # special-case for gpio in, store in a temporary vector - plen = len(self.peripheral.pinspecs) - ret.append(" rule con_%s%d_in;" % (name, count)) - ret.append(" Vector#({0},Bit#(1)) temp;".format(plen)) - for p in self.peripheral.pinspecs: - typ = p['type'] - pname = p['name'] - idx = pname[1:] - n = name - sname = self.peripheral.pname(pname).format(count) - ps = "pinmux.peripheral_side.%s_in" % sname - ret.append(" temp[{0}]={1};".format(idx, ps)) - ret.append(" {0}.func.gpio_in(temp);".format(name)) - ret.append(" endrule") - return '\n'.join(ret) - axi_slave_declarations = """\ typedef 0 SlowMaster; @@ -942,6 +398,19 @@ class PeripheralInterfaces(object): class PFactory(object): def getcls(self, name): + from uart import uart + from quart import quart + from sdmmc import sdmmc + from pwm import pwm + from eint import eint + from rs232 import rs232 + from twi import twi + from eint import eint + from jtag import jtag + from spi import spi + from qspi import qspi + from gpio import gpio + for k, v in {'uart': uart, 'rs232': rs232, 'twi': twi, @@ -958,7 +427,6 @@ class PFactory(object): return v return None - slowfactory = PFactory() if __name__ == '__main__': diff --git a/src/bsv/peripheral_gen/eint.py b/src/bsv/peripheral_gen/eint.py new file mode 100644 index 0000000..cd3be2c --- /dev/null +++ b/src/bsv/peripheral_gen/eint.py @@ -0,0 +1,56 @@ +from bsv.peripheral_gen.base import PBase + +class eint(PBase): + + def slowimport(self): + size = len(self.peripheral.pinspecs) + return " `define NUM_EINTS %d" % size + + def mkslow_peripheral(self, size=0): + size = len(self.peripheral.pinspecs) + return " Wire#(Bit#(%d)) wr_interrupt <- mkWire();" % size + + def axi_slave_name(self, name, ifacenum): + return '' + + def axi_slave_idx(self, idx, name, ifacenum): + return ('', 0) + + def axi_addr_map(self, name, ifacenum): + return '' + + def ifname_tweak(self, pname, typ, txt): + if typ != 'in': + return txt + print "ifnameweak", pname, typ, txt + return "wr_interrupt[{0}] <= ".format(pname) + + def mk_pincon(self, name, count): + ret = [PBase.mk_pincon(self, name, count)] + size = len(self.peripheral.pinspecs) + ret.append(eint_pincon_template.format(size)) + ret.append(" rule con_%s%d_io_in;" % (name, count)) + ret.append(" wr_interrupt <= ({") + for idx, p in enumerate(self.peripheral.pinspecs): + pname = p['name'] + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s" % sname + comma = '' if idx == size - 1 else ',' + ret.append(" {0}{1}".format(ps, comma)) + ret.append(" });") + ret.append(" endrule") + + return '\n'.join(ret) + + +eint_pincon_template = '''\ + // EINT is offset at end of other peripheral interrupts +`ifdef PLIC + for(Integer i=0;i<{0};i=i+ 1)begin + rule connect_int_to_plic(wr_interrupt[i]==1); + ff_gateway_queue[i+`NUM_SLOW_IRQS].enq(1); + plic.ifc_external_irq[i+`NUM_SLOW_IRQS].irq_frm_gateway(True); + endrule + end +`endif +''' diff --git a/src/bsv/peripheral_gen/gpio.py b/src/bsv/peripheral_gen/gpio.py new file mode 100644 index 0000000..93dcd3b --- /dev/null +++ b/src/bsv/peripheral_gen/gpio.py @@ -0,0 +1,86 @@ +from bsv.peripheral_gen.base import PBase + +class gpio(PBase): + + def slowimport(self): + return " import pinmux::*;\n" + \ + " import mux::*;\n" + \ + " import gpio::*;\n" + + def slowifdeclmux(self): + size = len(self.peripheral.pinspecs) + return " interface GPIO_config#(%d) pad_config{0};" % size + + def num_axi_regs32(self): + return 2 + + def axi_slave_idx(self, idx, name, ifacenum): + """ generates AXI slave number definition, except + GPIO also has a muxer per bank + """ + name = name.upper() + mname = 'mux' + name[4:] + mname = mname.upper() + print "AXIslavenum", name, mname + (ret, x) = PBase.axi_slave_idx(self, idx, name, ifacenum) + (ret2, x) = PBase.axi_slave_idx(self, idx + 1, mname, ifacenum) + return ("%s\n%s" % (ret, ret2), 2) + + def mkslow_peripheral(self, size=0): + print "gpioslow", self.peripheral, dir(self.peripheral) + size = len(self.peripheral.pinspecs) + return " MUX#(%d) mux{0} <- mkmux();\n" % size + \ + " GPIO#(%d) gpio{0} <- mkgpio();" % size + + def mk_connection(self, count): + print "GPIO mk_conn", self.name, count + res = [] + dname = self.mksuffix(self.name, count) + for i, n in enumerate(['gpio' + dname, 'mux' + dname]): + res.append(PBase.mk_connection(self, count, n)) + return '\n'.join(res) + + def _mk_connection(self, name=None, count=0): + n = self.mksuffix(name, count) + if name.startswith('gpio'): + return "gpio{0}.axi_slave".format(n) + if name.startswith('mux'): + return "mux{0}.axi_slave".format(n) + + def mksuffix(self, name, i): + if name.startswith('mux'): + return name[3:] + return name[4:] + + def mk_cellconn(self, cellnum, name, count): + ret = [] + bank = self.mksuffix(name, count) + txt = " pinmux.mux_lines.cell{0}_mux(mux{1}.mux_config.mux[{2}]);" + for p in self.peripheral.pinspecs: + ret.append(txt.format(cellnum, bank, p['name'][1:])) + cellnum += 1 + return ("\n".join(ret), cellnum) + + def pinname_out(self, pname): + return "func.gpio_out[{0}]".format(pname[1:]) + + def pinname_outen(self, pname): + return "func.gpio_out_en[{0}]".format(pname[1:]) + + def mk_pincon(self, name, count): + ret = [PBase.mk_pincon(self, name, count)] + # special-case for gpio in, store in a temporary vector + plen = len(self.peripheral.pinspecs) + ret.append(" rule con_%s%d_in;" % (name, count)) + ret.append(" Vector#({0},Bit#(1)) temp;".format(plen)) + for p in self.peripheral.pinspecs: + typ = p['type'] + pname = p['name'] + idx = pname[1:] + n = name + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s_in" % sname + ret.append(" temp[{0}]={1};".format(idx, ps)) + ret.append(" {0}.func.gpio_in(temp);".format(name)) + ret.append(" endrule") + return '\n'.join(ret) diff --git a/src/bsv/peripheral_gen/jtag.py b/src/bsv/peripheral_gen/jtag.py new file mode 100644 index 0000000..09c049d --- /dev/null +++ b/src/bsv/peripheral_gen/jtag.py @@ -0,0 +1,34 @@ +from bsv.peripheral_gen.base import PBase + +class jtag(PBase): + + def axi_slave_name(self, name, ifacenum): + return '' + + def axi_slave_idx(self, idx, name, ifacenum): + return ('', 0) + + def axi_addr_map(self, name, ifacenum): + return '' + + def slowifdeclmux(self): + return " method Action jtag_ms (Bit#(1) in);\n" + \ + " method Bit#(1) jtag_di;\n" + \ + " method Action jtag_do (Bit#(1) in);\n" + \ + " method Action jtag_ck (Bit#(1) in);" + + def slowifinstance(self): + return jtag_method_template # bit of a lazy hack this... + +jtag_method_template = """\ + method Action jtag_ms (Bit#(1) in); + pinmux.peripheral_side.jtag_ms(in); + endmethod + method Bit#(1) jtag_di=pinmux.peripheral_side.jtag_di; + method Action jtag_do (Bit#(1) in); + pinmux.peripheral_side.jtag_do(in); + endmethod + method Action jtag_ck (Bit#(1) in); + pinmux.peripheral_side.jtag_ck(in); + endmethod +""" diff --git a/src/bsv/peripheral_gen/pwm.py b/src/bsv/peripheral_gen/pwm.py new file mode 100644 index 0000000..1a43c13 --- /dev/null +++ b/src/bsv/peripheral_gen/pwm.py @@ -0,0 +1,21 @@ +from bsv.peripheral_gen.base import PBase + +class pwm(PBase): + + def slowimport(self): + return " import pwm::*;" + + def slowifdecl(self): + return " interface PWMIO pwm{0}_io;" + + def num_axi_regs32(self): + return 4 + + def mkslow_peripheral(self, size=0): + return " Ifc_PWM_bus pwm{0} <- mkPWM_bus(sp_clock);" + + def _mk_connection(self, name=None, count=0): + return "pwm{0}.axi4_slave" + + def pinname_out(self, pname): + return {'out': 'pwm_io.pwm_o'}.get(pname, '') diff --git a/src/bsv/peripheral_gen/qspi.py b/src/bsv/peripheral_gen/qspi.py new file mode 100644 index 0000000..0ed26b3 --- /dev/null +++ b/src/bsv/peripheral_gen/qspi.py @@ -0,0 +1,74 @@ +from bsv.peripheral_gen.base import PBase + +class qspi(PBase): + + def slowimport(self): + return " import qspi :: *;" + + def slowifdecl(self): + return " interface QSPI_out qspi{0}_out;\n" + \ + " method Bit#(1) qspi{0}_isint;" + + def num_axi_regs32(self): + return 13 + + def mkslow_peripheral(self, size=0): + return " Ifc_qspi qspi{0} <- mkqspi();" + + def _mk_connection(self, name=None, count=0): + return "qspi{0}.slave" + + def pinname_out(self, pname): + return {'ck': 'out.clk_o', + 'nss': 'out.ncs_o', + 'io0': 'out.io_o[0]', + 'io1': 'out.io_o[1]', + 'io2': 'out.io_o[2]', + 'io3': 'out.io_o[3]', + }.get(pname, '') + + def pinname_outen(self, pname): + return {'ck': 1, + 'nss': 1, + 'io0': 'out.io_enable[0]', + 'io1': 'out.io_enable[1]', + 'io2': 'out.io_enable[2]', + 'io3': 'out.io_enable[3]', + }.get(pname, '') + + def mk_pincon(self, name, count): + ret = [PBase.mk_pincon(self, name, count)] + # special-case for gpio in, store in a temporary vector + plen = len(self.peripheral.pinspecs) + ret.append(" // XXX NSS and CLK are hard-coded master") + ret.append(" // TODO: must add qspi slave-mode") + ret.append(" // all ins done in one rule from 4-bitfield") + ret.append(" rule con_%s%d_io_in;" % (name, count)) + ret.append(" {0}{1}.out.io_i({{".format(name, count)) + for i, p in enumerate(self.peripheral.pinspecs): + typ = p['type'] + pname = p['name'] + if not pname.startswith('io'): + continue + idx = pname[1:] + n = name + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s_in" % sname + comma = '' if i == 5 else ',' + ret.append(" {0}{1}".format(ps, comma)) + ret.append(" });") + ret.append(" endrule") + return '\n'.join(ret) + + def num_irqs(self): + return 6 + + def plic_object(self, pname, idx): + return "{0}.interrupts()[{1}]".format(pname, idx) + + def mk_ext_ifacedef(self, iname, inum): + name = self.get_iname(inum) + return " method {0}_isint = {0}.interrupts[5];".format(name) + + def slowifdeclmux(self): + return " method Bit#(1) {1}{0}_isint;" diff --git a/src/bsv/peripheral_gen/quart.py b/src/bsv/peripheral_gen/quart.py new file mode 100644 index 0000000..0d314dd --- /dev/null +++ b/src/bsv/peripheral_gen/quart.py @@ -0,0 +1,75 @@ +from bsv.peripheral_gen.base import PBase + +class quart(PBase): + + def slowimport(self): + return " import Uart16550 :: *;" + + def slowifdecl(self): + return " interface RS232_PHY_Ifc quart{0}_coe;\n" + \ + " method Bit#(1) quart{0}_intr;" + + def num_axi_regs32(self): + return 8 + + def mkslow_peripheral(self, size=0): + return " Uart16550_AXI4_Lite_Ifc quart{0} <- \n" + \ + " mkUart16550(clocked_by sp_clock,\n" + \ + " reset_by uart_reset, sp_clock, sp_reset);" + + def _mk_connection(self, name=None, count=0): + return "quart{0}.slave_axi_uart" + + def pinname_out(self, pname): + return {'tx' : 'coe_rs232.modem_output_stx', + 'rts': 'coe_rs232.modem_output_rts', + }.get(pname, '') + + def _pinname_in(self, pname): + return {'rx': 'coe_rs232.modem_input.srx', + 'cts': 'coe_rs232.modem_input.cts' + }.get(pname, '') + + def mk_pincon(self, name, count): + ret = [PBase.mk_pincon(self, name, count)] + ret.append(" rule con_%s%d_io_in;" % (name, count)) + ret.append(" {0}{1}.coe_rs232.modem_input(".format(name, count)) + for idx, pname in enumerate(['rx', 'cts']): + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s" % sname + ret.append(" {0},".format(ps)) + ret.append(" 1'b1,1'b0,1'b1") + ret.append(" );") + ret.append(" endrule") + + return '\n'.join(ret) + + def num_irqs(self): + return 1 + + def plic_object(self, pname, idx): + return "{0}_interrupt.read".format(pname) + + def mk_plic(self, inum, irq_offs): + name = self.get_iname(inum) + ret = [uart_plic_template.format(name, irq_offs)] + (ret2, irq_offs) = PBase.mk_plic(self, inum, irq_offs) + ret.append(ret2) + return ('\n'.join(ret), irq_offs) + + def mk_ext_ifacedef(self, iname, inum): + name = self.get_iname(inum) + return " method {0}_intr = {0}.irq;".format(name) + + def slowifdeclmux(self): + return " method Bit#(1) {1}{0}_intr;" + +uart_plic_template = """\ + // PLIC {0} synchronisation with irq {1} + SyncBitIfc#(Bit#(1)) {0}_interrupt <- + mkSyncBitToCC(sp_clock, uart_reset); + rule plic_synchronize_{0}_interrupt_{1}; + {0}_interrupt.send({0}.irq); + endrule +""" + diff --git a/src/bsv/peripheral_gen/rs232.py b/src/bsv/peripheral_gen/rs232.py new file mode 100644 index 0000000..597ad3e --- /dev/null +++ b/src/bsv/peripheral_gen/rs232.py @@ -0,0 +1,30 @@ +from bsv.peripheral_gen.base import PBase + +class rs232(PBase): + + def slowimport(self): + return " import Uart_bs::*;\n" + \ + " import RS232_modified::*;" + + def slowifdecl(self): + return " interface RS232 uart{0}_coe;" + + def num_axi_regs32(self): + return 2 + + def mkslow_peripheral(self, size=0): + return " //Ifc_Uart_bs uart{0} <-" + \ + " // mkUart_bs(clocked_by uart_clock,\n" + \ + " // reset_by uart_reset,sp_clock, sp_reset);" +\ + " Ifc_Uart_bs uart{0} <-" + \ + " mkUart_bs(clocked_by sp_clock,\n" + \ + " reset_by sp_reset, sp_clock, sp_reset);" + + def _mk_connection(self, name=None, count=0): + return "uart{0}.slave_axi_uart" + + def pinname_out(self, pname): + return {'tx': 'coe_rs232.sout'}.get(pname, '') + + def pinname_in(self, pname): + return {'rx': 'coe_rs232.sin'}.get(pname, '') diff --git a/src/bsv/peripheral_gen/sdmmc.py b/src/bsv/peripheral_gen/sdmmc.py new file mode 100644 index 0000000..f51b5a9 --- /dev/null +++ b/src/bsv/peripheral_gen/sdmmc.py @@ -0,0 +1,31 @@ +from bsv.peripheral_gen.base import PBase + +class sdmmc(PBase): + + def slowimport(self): + return " import sdcard_dummy :: *;" + + def slowifdecl(self): + return " interface QSPI_out sd{0}_out;\n" + \ + " method Bit#(1) sd{0}_isint;" + + def num_axi_regs32(self): + return 13 + + def mkslow_peripheral(self): + return " Ifc_sdcard_dummy sd{0} <- mksdcard_dummy();" + + def _mk_connection(self, name=None, count=0): + return "sd{0}.slave" + + def pinname_in(self, pname): + return "%s_in" % pname + + def pinname_out(self, pname): + if pname.startswith('d'): + return "%s_out" % pname + return pname + + def pinname_outen(self, pname): + if pname.startswith('d'): + return "%s_outen" % pname diff --git a/src/bsv/peripheral_gen/spi.py b/src/bsv/peripheral_gen/spi.py new file mode 100644 index 0000000..be51297 --- /dev/null +++ b/src/bsv/peripheral_gen/spi.py @@ -0,0 +1,60 @@ +from bsv.peripheral_gen.base import PBase + +class spi(PBase): + + def slowimport(self): + return " import qspi :: *;" + + def slowifdecl(self): + return " interface QSPI_out spi{0}_out;\n" + \ + " method Bit#(1) spi{0}_isint;" + + def num_axi_regs32(self): + return 13 + + def mkslow_peripheral(self): + return " Ifc_qspi spi{0} <- mkqspi();" + + def _mk_connection(self, name=None, count=0): + return "spi{0}.slave" + + def pinname_out(self, pname): + return {'clk': 'out.clk_o', + 'nss': 'out.ncs_o', + 'mosi': 'out.io_o[0]', + 'miso': 'out.io_o[1]', + }.get(pname, '') + + def pinname_outen(self, pname): + return {'clk': 1, + 'nss': 1, + 'mosi': 'out.io_enable[0]', + 'miso': 'out.io_enable[1]', + }.get(pname, '') + + def mk_pincon(self, name, count): + ret = [PBase.mk_pincon(self, name, count)] + # special-case for gpio in, store in a temporary vector + plen = len(self.peripheral.pinspecs) + ret.append(" // XXX NSS and CLK are hard-coded master") + ret.append(" // TODO: must add spi slave-mode") + ret.append(" // all ins done in one rule from 4-bitfield") + ret.append(" rule con_%s%d_io_in;" % (name, count)) + ret.append(" {0}{1}.out.io_i({{".format(name, count)) + for idx, pname in enumerate(['mosi', 'miso']): + sname = self.peripheral.pname(pname).format(count) + ps = "pinmux.peripheral_side.%s_in" % sname + ret.append(" {0},".format(ps)) + ret.append(" 1'b0,1'b0") + ret.append(" });") + ret.append(" endrule") + return '\n'.join(ret) + + def mk_ext_ifacedef(self, iname, inum): + name = self.get_iname(inum) + return " method {0}_isint = {0}.interrupts[5];".format(name) + + def slowifdeclmux(self): + return " method Bit#(1) {1}{0}_isint;" + + diff --git a/src/bsv/peripheral_gen/twi.py b/src/bsv/peripheral_gen/twi.py new file mode 100644 index 0000000..4c0d815 --- /dev/null +++ b/src/bsv/peripheral_gen/twi.py @@ -0,0 +1,54 @@ +from bsv.peripheral_gen.base import PBase + +class twi(PBase): + + def slowimport(self): + return " import I2C_top :: *;" + + def slowifdecl(self): + return " interface I2C_out twi{0}_out;\n" + \ + " method Bit#(1) twi{0}_isint;" + + def num_axi_regs32(self): + return 8 + + def mkslow_peripheral(self, size=0): + return " I2C_IFC twi{0} <- mkI2CController();" + + def _mk_connection(self, name=None, count=0): + return "twi{0}.slave_i2c_axi" + + def pinname_out(self, pname): + return {'sda': 'out.sda_out', + 'scl': 'out.scl_out'}.get(pname, '') + + def pinname_in(self, pname): + return {'sda': 'out.sda_in', + 'scl': 'out.scl_in'}.get(pname, '') + + def pinname_outen(self, pname): + return {'sda': 'out.sda_out_en', + 'scl': 'out.scl_out_en'}.get(pname, '') + + def pinname_tweak(self, pname, typ, txt): + if typ == 'outen': + return "pack({0})".format(txt) + return txt + + def num_irqs(self): + return 3 + + def plic_object(self, pname, idx): + return ["{0}.isint()", + "{0}.timerint()", + "{0}.isber()" + ][idx].format(pname) + + def mk_ext_ifacedef(self, iname, inum): + name = self.get_iname(inum) + return " method {0}_isint = {0}.isint;".format(name) + + def slowifdeclmux(self): + return " method Bit#(1) {1}{0}_isint;" + + diff --git a/src/bsv/peripheral_gen/uart.py b/src/bsv/peripheral_gen/uart.py new file mode 100644 index 0000000..c757c83 --- /dev/null +++ b/src/bsv/peripheral_gen/uart.py @@ -0,0 +1,28 @@ +from bsv.peripheral_gen.base import PBase + +class uart(PBase): + + def slowimport(self): + return " import Uart_bs :: *;\n" + \ + " import RS232_modified::*;" + + def slowifdecl(self): + return " interface RS232 uart{0}_coe;\n" + \ + " method Bit#(1) uart{0}_intr;" + + def num_axi_regs32(self): + return 8 + + def mkslow_peripheral(self, size=0): + return " Ifc_Uart_bs uart{0} <- \n" + \ + " mkUart_bs(clocked_by sp_clock,\n" + \ + " reset_by uart_reset, sp_clock, sp_reset);" + + def _mk_connection(self, name=None, count=0): + return "uart{0}.slave_axi_uart" + + def pinname_out(self, pname): + return {'tx': 'coe_rs232.sout'}.get(pname, '') + + def pinname_in(self, pname): + return {'rx': 'coe_rs232.sin'}.get(pname, '') -- 2.30.2