From a45f5ed4b3ff2b6bb828eac7e3412e5fd4433be4 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 26 Jul 2018 05:59:52 +0100 Subject: [PATCH] add dma rules --- src/bsv/bsv_lib/soc_template.bsv | 1 + src/bsv/peripheral_gen/base.py | 73 ++++++++++++++++++++++++++++++++ src/bsv/peripheral_gen/nspi.py | 5 ++- src/bsv/peripheral_gen/quart.py | 11 ++++- src/bsv/peripheral_gen/twi.py | 5 ++- src/bsv/pinmux_generator.py | 3 +- 6 files changed, 93 insertions(+), 5 deletions(-) diff --git a/src/bsv/bsv_lib/soc_template.bsv b/src/bsv/bsv_lib/soc_template.bsv index 7a7b0ce..6b2cc8e 100644 --- a/src/bsv/bsv_lib/soc_template.bsv +++ b/src/bsv/bsv_lib/soc_template.bsv @@ -211,6 +211,7 @@ package Soc; `ifdef UART0 uart0_interrupt.read `else 1'b1 `endif }}; dma.interrupt_from_peripherals(lv_interrupt_to_DMA); endrule +{7} `endif diff --git a/src/bsv/peripheral_gen/base.py b/src/bsv/peripheral_gen/base.py index 23adfb6..2094548 100644 --- a/src/bsv/peripheral_gen/base.py +++ b/src/bsv/peripheral_gen/base.py @@ -12,6 +12,39 @@ class PBase(object): def has_axi_master(self): return False + def irq_name(self): + return "" + + def mk_dma_irq(self, name, count): + if not self.irq_name(): + return '' + sname = self.get_iname(count) + return "{0}_interrupt".format(sname) + + def mk_dma_rule(self, name, count): + irqname = self.mk_dma_irq(name, count) + if not irqname: + return '' + pirqname = self.irq_name().format(count) + template = " {0}_interrupt.send(\n" + \ + " slow_peripherals.{1});" + return template.format(irqname, pirqname) + + def get_clock_reset(self, name, count): + return "slow_clock,slow_reset" + + def mk_dma_sync(self, name, count): + irqname = self.mk_dma_irq(name, count) + if not irqname: + return '' + sname = self.peripheral.iname().format(count) + template = " SyncBitIfc#(Bit#(1)) {0} <-\n" + \ + " <-mkSyncBitToCC({1});" + return template.format(irqname, self.get_clock_reset(name, count)) + + def mk_dma_connect(self, name, count): + return '' + def fastifdecl(self, name, count): return '' @@ -301,6 +334,7 @@ class PeripheralIface(object): 'slowifdecl', 'slowifdeclmux', 'fastifdecl', 'mkslow_peripheral', + 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule', 'mkfast_peripheral', 'mk_plic', 'mk_ext_ifacedef', 'mk_connection', 'mk_cellconn', 'mk_pincon']: @@ -537,6 +571,45 @@ class PeripheralInterfaces(object): ret.append(txt) return '\n'.join(list(filter(None, ret))) + def mk_dma_irq(self): + ret = [] + sync = [] + rules = [] + cnct = [] + + self.dma_count = 0 + + for (name, count) in self.ifacecount: + ifacerules = [] + for i in range(count): + if not self.is_on_fastbus(name, i): + continue + txt = self.data[name].mk_dma_sync(name, i) + if txt: + self.dma_count += 1 + sync.append(txt) + txt = self.data[name].mk_dma_rule(name, i) + ifacerules.append(txt) + txt = self.data[name].mk_dma_connect(name, i) + cnct.append(txt) + ifacerules = list(filter(None, ifacerules)) + if ifacerules: + txt = " rule synchronize_%s_interrupts;" % name + rules.append(txt) + rules += ifacerules + rules.append(" endrule") + + ct = self.dma_count + _cnct = [" rule rl_connect_interrupt_to_DMA;", + " Bit #(%d) lv_interrupt_to_DMA={" % ct] + cnct = _cnct + cnct + cnct.append(" };") + cnct.append(" dma.interrupt_from_peripherals(\n" + \ + " lv_interrupt_to_DMA);") + cnct.append(" endrule;") + + return '\n'.join(list(filter(None, sync + rules + cnct))) + def mk_ext_ifacedef(self): ret = [] for (name, count) in self.ifacecount: diff --git a/src/bsv/peripheral_gen/nspi.py b/src/bsv/peripheral_gen/nspi.py index dadd7ca..16526e1 100644 --- a/src/bsv/peripheral_gen/nspi.py +++ b/src/bsv/peripheral_gen/nspi.py @@ -12,9 +12,12 @@ class nspi(PBase): def slowimport(self): return " import %(n)s :: *;" % self.ifndict + def irq_name(self): + return "%(n)s{0}_isint" % self.ifndict + def slowifdecl(self): return " interface %(N)s_out %(n)s{0}_out;\n" + \ - " method Bit#(1) %(n)s{0}_isint;" % self.ifndict + " method Bit#(1) %s;" % self.irq_name def num_axi_regs32(self): return 13 diff --git a/src/bsv/peripheral_gen/quart.py b/src/bsv/peripheral_gen/quart.py index a6646db..75778a3 100644 --- a/src/bsv/peripheral_gen/quart.py +++ b/src/bsv/peripheral_gen/quart.py @@ -6,15 +6,22 @@ class quart(PBase): def slowimport(self): return " import Uart16550 :: *;" + def irq_name(self): + return "quart{0}_intr" + def slowifdecl(self): return " interface RS232_PHY_Ifc quart{0}_coe;\n" + \ - " method Bit#(1) quart{0}_intr;" + " method Bit#(1) %s;" % self.irq_name() + + def get_clock_reset(self, name, count): + return "slow_clock,slow_reset" # XXX TODO: change to uart_clock/reset def num_axi_regs32(self): return 8 def mkslow_peripheral(self, size=0): - return " Uart16550_AXI4_Lite_Ifc quart{0} <- \n" + \ + return " // XXX XXX TODO: change to uart_clock/reset" + \ + " Uart16550_AXI4_Lite_Ifc quart{0} <- \n" + \ " mkUart16550(clocked_by sp_clock,\n" + \ " reset_by sp_reset, sp_clock, sp_reset);" diff --git a/src/bsv/peripheral_gen/twi.py b/src/bsv/peripheral_gen/twi.py index b77724f..7aaf291 100644 --- a/src/bsv/peripheral_gen/twi.py +++ b/src/bsv/peripheral_gen/twi.py @@ -6,9 +6,12 @@ class twi(PBase): def slowimport(self): return " import I2C_top :: *;" + def irq_name(self): + return "twi{0}_isint" + def slowifdecl(self): return " interface I2C_out twi{0}_out;\n" + \ - " method Bit#(1) twi{0}_isint;" + " method Bit#(1) %s;" % self.irq_name() def num_axi_regs32(self): return 8 diff --git a/src/bsv/pinmux_generator.py b/src/bsv/pinmux_generator.py index b74fd47..0011dd0 100644 --- a/src/bsv/pinmux_generator.py +++ b/src/bsv/pinmux_generator.py @@ -146,10 +146,11 @@ def write_soc(soc, soct, p, ifaces, iocells): mkplic = ifaces.mk_plic() numsloirqs = ifaces.mk_sloirqsdef() ifacedef = ifaces.mk_ext_ifacedef() + dma = ifaces.mk_dma_irq() with open(soc, "w") as bsv_file: bsv_file.write(soct.format(imports, ifdecl, mkfast, slavedecl, mastdecl, mkcon, - inst, + inst, dma, #'', '' #regdef, slavedecl, #'', mkslow, #fnaddrmap, mkslow, mkcon, mkcellcon, #pincon, inst, mkplic, -- 2.30.2