soc/cores/icap: simplify ICAPBitstream (untested)
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 1 Oct 2019 19:30:14 +0000 (21:30 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 1 Oct 2019 19:30:14 +0000 (21:30 +0200)
litex/soc/cores/icap.py
test/test_icap.py

index 2de335c4cb6268741571fe59919c29cce077d8c6..61e8357c338afcc915a3222c002af2d2518bd918 100644 (file)
@@ -25,7 +25,7 @@ class ICAP(Module, AutoCSR):
 
         # # #
 
-        # Create slow icap clk (sys_clk/2) ---------------------------------------------------------
+        # Create slow icap clk (sys_clk/16) ---------------------------------------------------------
         self.clock_domains.cd_icap = ClockDomain()
         icap_clk_counter = Signal(4)
         self.sync += icap_clk_counter.eq(icap_clk_counter + 1)
@@ -36,7 +36,7 @@ class ICAP(Module, AutoCSR):
         self.submodules += ps_send
         self.comb += [ps_send.i.eq(self.send.re)]
 
-        # generate icap bitstream write sequence
+        # Generate icap bitstream write sequenceenerate icap bitstream write sequence
         _csib = Signal(reset=1)
         _i = Signal(32)
         _addr = self.addr.storage << 13
@@ -62,9 +62,9 @@ class ICAP(Module, AutoCSR):
         ]
 
         self._csib = _csib
-        self._i = _i
+        self._i    = _i
 
-        # icap instance
+        # ICAP instance
         if not simulation:
             self.specials += [
                 Instance("ICAPE2",
@@ -76,64 +76,61 @@ class ICAP(Module, AutoCSR):
                 )
             ]
 
+
 class ICAPBitstream(Module, AutoCSR):
     """ICAP
 
     Allow sending bitstreams to ICAPE2 of Xilinx 7-Series FPGAs.
     """
-    def __init__(self, simulation=False):
-        self.data = CSRStorage(32, reset=0xffffffff)
-        self.icap_en = CSRStorage(reset=0)
-        self.fifofull = CSRStatus()
-        self.done = CSRStatus(reset=1)
+    def __init__(self, fifo_depth=8, simulation=False):
+        self.sink_data  = CSRStorage(32)
+        self.sink_ready = CSRStatus()
+        self.start      = CSR()
+        self.done       = CSRStatus()
 
         # # #
 
+        _run  = Signal()
+        _csib = Signal(reset=1)
+        _i    = Signal(32, reset=0xffffffff)
+
         # Create slow icap clk (sys_clk/4) ---------------------------------------------------------
         self.clock_domains.cd_icap = ClockDomain()
         icap_clk_counter = Signal(4)
         self.sync += icap_clk_counter.eq(icap_clk_counter + 1)
         self.sync += self.cd_icap.clk.eq(icap_clk_counter[1])
 
-        # Helper signals
-        _csib = Signal(reset=1)
-        _i = Signal(32, reset=0xffffffff)
-        acknext = Signal(reset=0)
-        syncdata = Signal(32, reset=0xffffffff)
-
         # FIFO
-        fifo = stream.AsyncFIFO([("data", 32)], 8)
-        icapfifo = ClockDomainsRenamer({"write": "sys", "read": "icap"})(fifo)
-
-        # Connect to FIFO
+        fifo = stream.AsyncFIFO([("data", 32)], fifo_depth)
+        fifo = ClockDomainsRenamer({"write": "sys", "read": "icap"})(fifo)
+        self.submodules += fifo
         self.comb += [
-            icapfifo.sink.valid.eq(self.data.re),
-            icapfifo.sink.data.eq(self.data.storage),
-            self.fifofull.status.eq(~icapfifo.sink.ready),
-            syncdata.eq(icapfifo.source.data),
-            icapfifo.source.ready.eq(acknext),
+            fifo.sink.valid.eq(self.sink_data.re),
+            fifo.sink.data.eq(self.sink_data.storage),
+            self.sink_ready.status.eq(fifo.sink.ready),
         ]
-        self.submodules += icapfifo
 
+        # Generate ICAP commands
         self.sync.icap += [
-            If(self.icap_en.storage & icapfifo.source.valid & ~acknext,
-                acknext.eq(1),
-                self.done.status.eq(0)
-            ).Elif(self.icap_en.storage & icapfifo.source.valid & acknext,
-                _i.eq(syncdata),
-                _csib.eq(0)
-            ).Else(
-                _i.eq(0xffffffff),
-                _csib.eq(1),
-                acknext.eq(0),
-                self.done.status.eq(1)
-            ),
+            If(self.start.re,
+                _run.eq(1),
+            ).Elif(~fifo.source.valid,
+                _run.eq(0)
+            )
+        ]
+        self.comb += [
+            self.done.status.eq(~_run),
+            If(_run,
+                _i.eq(fifo.source.data),
+                _csib.eq(0),
+                fifo.source.ready.eq(1)
+            )
         ]
 
         self._csib = _csib
-        self._i = _i
+        self._i    = _i
 
-        # icap instance
+        # ICAP instance
         if not simulation:
             self.specials += [
                 Instance("ICAPE2",
index 444451764eb6682ac7af6b1a6d57765e196cff88..662d31ea66bb7bf26a276c09884440b227a545b7 100644 (file)
@@ -5,11 +5,11 @@ import unittest
 
 from migen import *
 
-from litex.soc.cores.icap import ICAP
+from litex.soc.cores.icap import ICAP, ICAPBitstream
 
 
 class TestICAP(unittest.TestCase):
-    def test_reload(self):
+    def test_icap_command_reload(self):
         def generator(dut):
             yield dut.addr.storage.eq(0x4)
             yield dut.data.storage.eq(0xf)
@@ -25,3 +25,6 @@ class TestICAP(unittest.TestCase):
         clocks = {"sys": 10,
                   "icap":20}
         run_simulation(dut, generator(dut), clocks, vcd_name="icap.vcd")
+
+    def test_icap_bitstream_syntax(self):
+        dut = ICAPBitstream(simulation=True)