soc/cores/icap/ICAP: add with_csr parameter and add_reload method to allow reloading the FPGA from the logic.
This commit is contained in:
parent
42025dcbfa
commit
ad7671f811
|
@ -20,11 +20,11 @@ class ICAP(Module, AutoCSR):
|
||||||
Allow sending commands to ICAPE2 of Xilinx 7-Series FPGAs, the bistream can for example be
|
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.
|
reloaded from SPI Flash by writing 0x00000000 at address @0x4.
|
||||||
"""
|
"""
|
||||||
def __init__(self, simulation=False):
|
def __init__(self, with_csr=True, simulation=False):
|
||||||
self.addr = CSRStorage(5, reset_less=True, description="ICAP Write Address.")
|
self.addr = Signal(5)
|
||||||
self.data = CSRStorage(32, reset_less=True, description="ICAP Write Data.")
|
self.data = Signal(32)
|
||||||
self.send = CSRStorage(description="ICAP Control.\n\n Write ``1`` send a write command to the ICAP.")
|
self.send = Signal()
|
||||||
self.done = CSRStatus(reset=1, description="ICAP Status.\n\n Write command done when read as ``1``.")
|
self.done = Signal()
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
@ -37,17 +37,17 @@ class ICAP(Module, AutoCSR):
|
||||||
# Resynchronize send pulse to icap domain ---------------------------------------------------
|
# Resynchronize send pulse to icap domain ---------------------------------------------------
|
||||||
ps_send = PulseSynchronizer("sys", "icap")
|
ps_send = PulseSynchronizer("sys", "icap")
|
||||||
self.submodules += ps_send
|
self.submodules += ps_send
|
||||||
self.comb += [ps_send.i.eq(self.send.re)]
|
self.comb += ps_send.i.eq(self.send)
|
||||||
|
|
||||||
# Generate icap bitstream write sequence
|
# Generate icap bitstream write sequence
|
||||||
self._csib = _csib = Signal(reset=1)
|
self._csib = _csib = Signal(reset=1)
|
||||||
self._i = _i = Signal(32)
|
self._i = _i = Signal(32)
|
||||||
_addr = self.addr.storage << 13
|
_addr = self.addr << 13
|
||||||
_data = self.data.storage
|
_data = self.data
|
||||||
self.sync.icap += [
|
self.sync.icap += [
|
||||||
_i.eq(0xffffffff), # dummy
|
_i.eq(0xffffffff), # dummy
|
||||||
timeline(ps_send.o, [
|
timeline(ps_send.o, [
|
||||||
(1, [_csib.eq(1), self.done.status.eq(0)]),
|
(1, [_csib.eq(1), self.done.eq(0)]),
|
||||||
(2, [_csib.eq(0), _i.eq(0x20000000)]), # noop
|
(2, [_csib.eq(0), _i.eq(0x20000000)]), # noop
|
||||||
(3, [_csib.eq(0), _i.eq(0xaa995566)]), # sync word
|
(3, [_csib.eq(0), _i.eq(0xaa995566)]), # sync word
|
||||||
(4, [_csib.eq(0), _i.eq(0x20000000)]), # noop
|
(4, [_csib.eq(0), _i.eq(0x20000000)]), # noop
|
||||||
|
@ -60,7 +60,7 @@ class ICAP(Module, AutoCSR):
|
||||||
(11, [_csib.eq(0), _i.eq(0x0000000d)]), # desync command
|
(11, [_csib.eq(0), _i.eq(0x0000000d)]), # desync command
|
||||||
(12, [_csib.eq(0), _i.eq(0x20000000)]), # noop
|
(12, [_csib.eq(0), _i.eq(0x20000000)]), # noop
|
||||||
(13, [_csib.eq(0), _i.eq(0x20000000)]), # noop
|
(13, [_csib.eq(0), _i.eq(0x20000000)]), # noop
|
||||||
(14, [_csib.eq(1), self.done.status.eq(1)]),
|
(14, [_csib.eq(1), self.done.eq(1)]),
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -68,14 +68,42 @@ class ICAP(Module, AutoCSR):
|
||||||
if not simulation:
|
if not simulation:
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("ICAPE2",
|
Instance("ICAPE2",
|
||||||
p_ICAP_WIDTH="X32",
|
p_ICAP_WIDTH = "X32",
|
||||||
i_CLK=ClockSignal("icap"),
|
i_CLK = ClockSignal("icap"),
|
||||||
i_CSIB=_csib,
|
i_CSIB = _csib,
|
||||||
i_RDWRB=0,
|
i_RDWRB = 0,
|
||||||
i_I=Cat(*[_i[8*i:8*(i+1)][::-1] for i in range(4)]),
|
i_I = Cat(*[_i[8*i:8*(i+1)][::-1] for i in range(4)]),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def add_csr(self):
|
||||||
|
self._addr = CSRStorage(5, reset_less=True, description="ICAP Write Address.")
|
||||||
|
self._data = CSRStorage(32, reset_less=True, description="ICAP Write Data.")
|
||||||
|
self._send = CSRStorage(description="ICAP Control.\n\n Write ``1`` send a write command to the ICAP.")
|
||||||
|
self._done = CSRStatus(reset=1, description="ICAP Status.\n\n Write command done when read as ``1``.")
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
self.addr.eq(self._addr.storage),
|
||||||
|
self.data.eq(self._data.storage),
|
||||||
|
self.send.eq(self._send.re),
|
||||||
|
self._done.status.eq(self.done)
|
||||||
|
]
|
||||||
|
|
||||||
|
def add_reload(self):
|
||||||
|
self.reload = Signal() # Set to 1 to reload FPGA from logic.
|
||||||
|
|
||||||
|
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||||
|
fsm.act("IDLE",
|
||||||
|
If(self.reload,
|
||||||
|
NextState("RELOAD")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("RELOAD",
|
||||||
|
self.addr.eq(0x4),
|
||||||
|
self.data.eq(0xf),
|
||||||
|
self.send.eq(1),
|
||||||
|
)
|
||||||
|
|
||||||
def add_timing_constraints(self, platform, sys_clk_freq, sys_clk):
|
def add_timing_constraints(self, platform, sys_clk_freq, sys_clk):
|
||||||
platform.add_period_constraint(self.cd_icap.clk, 16*1e9/sys_clk_freq)
|
platform.add_period_constraint(self.cd_icap.clk, 16*1e9/sys_clk_freq)
|
||||||
platform.add_false_path_constraints(self.cd_icap.clk, sys_clk)
|
platform.add_false_path_constraints(self.cd_icap.clk, sys_clk)
|
||||||
|
|
Loading…
Reference in New Issue