add dma rules
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 26 Jul 2018 04:59:52 +0000 (05:59 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 26 Jul 2018 04:59:52 +0000 (05:59 +0100)
src/bsv/bsv_lib/soc_template.bsv
src/bsv/peripheral_gen/base.py
src/bsv/peripheral_gen/nspi.py
src/bsv/peripheral_gen/quart.py
src/bsv/peripheral_gen/twi.py
src/bsv/pinmux_generator.py

index 7a7b0ce8e2d1c32ad6a909958fd15abbc1a60fdc..6b2cc8ed2bbc46efffe7d273f5e25e4b3980db80 100644 (file)
@@ -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
 
 
index 23adfb687cc295e2e9cd677a7e633a2aeb7a38cd..20945481355699d26267117526d0c2b97f2aee67 100644 (file)
@@ -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:
index dadd7ca3978529375cc2b96c90a51c4ff16ac9b1..16526e123a1f3d63657c4425f3e7b3603d3aa1be 100644 (file)
@@ -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
index a6646db1899ff0ad2bd498b027ec8fa38c3b9823..75778a35cb23a98adad32dbc596e82e7bc96a0d8 100644 (file)
@@ -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);"
 
index b77724f932556cf19f7fa2eb25e7426b07a4fba0..7aaf2911bd736131108bdf4cdbe072db149eded4 100644 (file)
@@ -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
index b74fd47e6ed2bd0c4971d893680c878d86fb761f..0011dd006397b554950d9b6678066e7d52a58b6e 100644 (file)
@@ -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,