From 0c2993866c6d8fb424bd072d271330e39e669bb5 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 1 Oct 2019 21:04:49 +0200 Subject: [PATCH] soc/cores/icap: rename ICAP to ICAPBistream and revert old ICAP --- litex/soc/cores/icap.py | 65 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/litex/soc/cores/icap.py b/litex/soc/cores/icap.py index e841e7c72..2de335c4c 100644 --- a/litex/soc/cores/icap.py +++ b/litex/soc/cores/icap.py @@ -14,6 +14,71 @@ from litex.soc.interconnect import stream class ICAP(Module, AutoCSR): """ICAP + Allow sending commands to ICAPE2 of Xilinx 7-Series FPGAs, the bistream can for example be + reloaded from SPI Flash by writing 0x00000000 at address @0x4. + """ + def __init__(self, simulation=False): + self.addr = CSRStorage(5) + self.data = CSRStorage(32) + self.send = CSR() + self.done = CSRStatus(reset=1) + + # # # + + # Create slow icap clk (sys_clk/2) --------------------------------------------------------- + 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[3]) + + # Resychronize send pulse to icap domain --------------------------------------------------- + ps_send = PulseSynchronizer("sys", "icap") + self.submodules += ps_send + self.comb += [ps_send.i.eq(self.send.re)] + + # generate icap bitstream write sequence + _csib = Signal(reset=1) + _i = Signal(32) + _addr = self.addr.storage << 13 + _data = self.data.storage + self.sync.icap += [ + _i.eq(0xffffffff), # dummy + timeline(ps_send.o, [ + (1, [_csib.eq(1), self.done.status.eq(0)]), + (2, [_csib.eq(0), _i.eq(0x20000000)]), # noop + (3, [_csib.eq(0), _i.eq(0xaa995566)]), # sync word + (4, [_csib.eq(0), _i.eq(0x20000000)]), # noop + (5, [_csib.eq(0), _i.eq(0x20000000)]), # noop + (6, [_csib.eq(0), _i.eq(0x30000001 | _addr)]), # write command + (7, [_csib.eq(0), _i.eq(_data)]), # write value + (8, [_csib.eq(0), _i.eq(0x20000000)]), # noop + (9, [_csib.eq(0), _i.eq(0x20000000)]), # noop + (10, [_csib.eq(0), _i.eq(0x30008001)]), # write to cmd register + (11, [_csib.eq(0), _i.eq(0x0000000d)]), # desync command + (12, [_csib.eq(0), _i.eq(0x20000000)]), # noop + (13, [_csib.eq(0), _i.eq(0x20000000)]), # noop + (14, [_csib.eq(1), self.done.status.eq(1)]), + ]) + ] + + self._csib = _csib + self._i = _i + + # icap instance + if not simulation: + self.specials += [ + Instance("ICAPE2", + p_ICAP_WIDTH="X32", + i_CLK=ClockSignal("icap"), + i_CSIB=_csib, + i_RDWRB=0, + i_I=Cat(*[_i[8*i:8*(i+1)][::-1] for i in range(4)]), + ) + ] + +class ICAPBitstream(Module, AutoCSR): + """ICAP + Allow sending bitstreams to ICAPE2 of Xilinx 7-Series FPGAs. """ def __init__(self, simulation=False):