fix formatting on spiopi
Pycharm really butchered the code when I did a copy-and-paste... it has questionable default formatting preferences.
This commit is contained in:
parent
cc6ed667df
commit
33d9e45a8b
|
@ -1,6 +1,3 @@
|
|||
# This file is Copyright (c) 2020 bunnie <bunnie@kosagi.com>
|
||||
# License: BSD
|
||||
|
||||
from litex.soc.interconnect.csr_eventmanager import *
|
||||
from litex.soc.interconnect import wishbone
|
||||
from litex.soc.integration.doc import AutoDoc, ModuleDoc
|
||||
|
@ -79,7 +76,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
CSRField("dummy", size=5, description="Number of dummy cycles", reset=10),
|
||||
])
|
||||
|
||||
delay_type = "VAR_LOAD"
|
||||
delay_type="VAR_LOAD"
|
||||
|
||||
# DQS input conditioning -----------------------------------------------------------------
|
||||
dqs_iobuf = Signal()
|
||||
|
@ -89,6 +86,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
Instance("BUFR", i_I=pads.dqs, o_O=dqs_iobuf),
|
||||
]
|
||||
|
||||
|
||||
# DQ connections -------------------------------------------------------------------------
|
||||
# PHY API
|
||||
self.do = Signal(16) # OPI data to SPI
|
||||
|
@ -127,40 +125,33 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
self.specials += Instance("ODDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE",
|
||||
i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=1,
|
||||
i_D1=do_rise[i], i_D2=do_fall[i], o_Q=dq.o[i - 1],
|
||||
i_D1=do_rise[i], i_D2=do_fall[i], o_Q=dq.o[i-1],
|
||||
)
|
||||
if sim == False:
|
||||
if i == 1: # only wire up o_CNTVALUEOUT for one instance
|
||||
self.specials += Instance("IDELAYE2",
|
||||
p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA",
|
||||
p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="FALSE",
|
||||
p_REFCLK_FREQUENCY=200.0,
|
||||
p_PIPE_SEL="FALSE", p_IDELAY_VALUE=dq_delay_taps,
|
||||
p_IDELAY_TYPE=delay_type,
|
||||
p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="FALSE", p_REFCLK_FREQUENCY=200.0,
|
||||
p_PIPE_SEL="FALSE", p_IDELAY_VALUE=dq_delay_taps, p_IDELAY_TYPE=delay_type,
|
||||
|
||||
i_C=ClockSignal(), i_CINVCTRL=0, i_REGRST=0, i_LDPIPEEN=0, i_INC=0,
|
||||
i_CE=0,
|
||||
i_C=ClockSignal(), i_CINVCTRL=0, i_REGRST=0, i_LDPIPEEN=0, i_INC=0, i_CE=0,
|
||||
i_LD=self.delay_update,
|
||||
i_CNTVALUEIN=self.delay_config.fields.d,
|
||||
o_CNTVALUEOUT=self.delay_status.fields.q,
|
||||
i_IDATAIN=dq.i[i - 1], o_DATAOUT=dq_delayed[i],
|
||||
i_CNTVALUEIN=self.delay_config.fields.d, o_CNTVALUEOUT=self.delay_status.fields.q,
|
||||
i_IDATAIN=dq.i[i-1], o_DATAOUT=dq_delayed[i],
|
||||
),
|
||||
else: # don't wire up o_CNTVALUEOUT for others
|
||||
self.specials += Instance("IDELAYE2",
|
||||
p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA",
|
||||
p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="FALSE",
|
||||
p_REFCLK_FREQUENCY=200.0,
|
||||
p_PIPE_SEL="FALSE", p_IDELAY_VALUE=dq_delay_taps,
|
||||
p_IDELAY_TYPE=delay_type,
|
||||
p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="FALSE", p_REFCLK_FREQUENCY=200.0,
|
||||
p_PIPE_SEL="FALSE", p_IDELAY_VALUE=dq_delay_taps, p_IDELAY_TYPE=delay_type,
|
||||
|
||||
i_C=ClockSignal(), i_CINVCTRL=0, i_REGRST=0, i_LDPIPEEN=0, i_INC=0,
|
||||
i_CE=0,
|
||||
i_C=ClockSignal(), i_CINVCTRL=0, i_REGRST=0, i_LDPIPEEN=0, i_INC=0, i_CE=0,
|
||||
i_LD=self.delay_update,
|
||||
i_CNTVALUEIN=self.delay_config.fields.d,
|
||||
i_IDATAIN=dq.i[i - 1], o_DATAOUT=dq_delayed[i],
|
||||
i_IDATAIN=dq.i[i-1], o_DATAOUT=dq_delayed[i],
|
||||
),
|
||||
else:
|
||||
self.comb += dq_delayed[i].eq(dq.i[i - 1])
|
||||
self.comb += dq_delayed[i].eq(dq.i[i-1])
|
||||
self.specials += Instance("IDDR", name="{}{}".format(iddr_name, str(i)),
|
||||
p_DDR_CLK_EDGE="SAME_EDGE_PIPELINED",
|
||||
i_C=dqs_iobuf, i_R=ResetSignal(), i_S=0, i_CE=1,
|
||||
|
@ -224,7 +215,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
# wire up CS_N
|
||||
spi_cs_n = Signal()
|
||||
opi_cs_n = Signal()
|
||||
self.comb += cs_n.eq((self.spi_mode & spi_cs_n) | (~self.spi_mode & opi_cs_n))
|
||||
self.comb += cs_n.eq( (self.spi_mode & spi_cs_n) | (~self.spi_mode & opi_cs_n) )
|
||||
self.specials += [
|
||||
Instance("ODDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE",
|
||||
|
@ -342,8 +333,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
""")
|
||||
self.bus = wishbone.Interface()
|
||||
|
||||
self.command = CSRStorage(
|
||||
description="Write individual bits to issue special commands to SPI; setting multiple bits at once leads to undefined behavior.",
|
||||
self.command = CSRStorage(description="Write individual bits to issue special commands to SPI; setting multiple bits at once leads to undefined behavior.",
|
||||
fields=[
|
||||
CSRField("wakeup", size=1, description="Sequence through init & wakeup routine"),
|
||||
CSRField("sector_erase", size=1, description="Erase a sector"),
|
||||
|
@ -373,8 +363,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
self.comb += do_mux_fall.eq(~self.spi_mode & do_fall[0] | self.spi_mode & self.mosi)
|
||||
|
||||
has_dummy = Signal() # indicates if the current "req" requires dummy cycles to be appended (used for both OPI/SPI)
|
||||
rom_addr = Signal(32,
|
||||
reset=0xFFFFFFFC) # location of the internal ROM address pointer; reset to invalid address to force an address request on first read
|
||||
rom_addr = Signal(32, reset=0xFFFFFFFC) # location of the internal ROM address pointer; reset to invalid address to force an address request on first read
|
||||
|
||||
# MAC/PHY abstraction for OPI
|
||||
txphy_do = Signal(16) # two sources of data out for OPI, one from the PHY, one from MAC
|
||||
|
@ -416,7 +405,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
# Direct FIFO primitive is more resource-efficient and faster than migen primitive.
|
||||
Instance("FIFO_DUALCLOCK_MACRO",
|
||||
p_DEVICE="7SERIES", p_FIFO_SIZE="18Kb", p_DATA_WIDTH=32, p_FIRST_WORD_FALL_THROUGH="TRUE",
|
||||
p_ALMOST_EMPTY_OFFSET=6, p_ALMOST_FULL_OFFSET=(512 - (8 * prefetch_lines)),
|
||||
p_ALMOST_EMPTY_OFFSET=6, p_ALMOST_FULL_OFFSET=(512- (8*prefetch_lines)),
|
||||
|
||||
o_ALMOSTEMPTY=rx_almostempty, o_ALMOSTFULL=rx_almostfull,
|
||||
o_DO=opi_fifo_rd, o_EMPTY=rx_empty, o_FULL=rx_full,
|
||||
|
@ -428,7 +417,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
self.sync.dqs += opi_di.eq(self.di)
|
||||
self.comb += opi_fifo_wd.eq(Cat(opi_di, self.di))
|
||||
|
||||
# --------- OPI Rx Phy machine ------------------------------
|
||||
#--------- OPI Rx Phy machine ------------------------------
|
||||
self.submodules.rxphy = rxphy = FSM(reset_state="IDLE")
|
||||
cti_pipe = Signal(3)
|
||||
rxphy_cnt = Signal(3)
|
||||
|
@ -444,10 +433,8 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
NextValue(rx_fifo_rst, 1),
|
||||
).Elif(opi_rx_run,
|
||||
NextValue(rx_wren, 1),
|
||||
If((self.bus.cyc & self.bus.stb & ~self.bus.we) & ((self.bus.cti == 2) |
|
||||
((
|
||||
self.bus.cti == 7) & ~self.bus.ack)),
|
||||
# handle case of non-pipelined read, ack is late
|
||||
If( (self.bus.cyc & self.bus.stb & ~self.bus.we) & ((self.bus.cti == 2) |
|
||||
((self.bus.cti == 7) & ~self.bus.ack) ), # handle case of non-pipelined read, ack is late
|
||||
If(~rx_empty,
|
||||
NextValue(self.bus.dat_r, opi_fifo_rd),
|
||||
rx_rden.eq(1),
|
||||
|
@ -468,6 +455,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
|
||||
|
||||
# TxPHY machine: OPI -------------------------------------------------------------------------
|
||||
txphy_cnt = Signal(4)
|
||||
tx_run = Signal()
|
||||
|
@ -477,10 +465,10 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
txcmd_clken = Signal()
|
||||
txphy_oe = Signal()
|
||||
txcmd_oe = Signal()
|
||||
self.sync += opi_cs_n.eq((tx_run & txphy_cs_n) | (~tx_run & txcmd_cs_n))
|
||||
self.comb += If(tx_run, self.do.eq(txphy_do)).Else(self.do.eq(txcmd_do))
|
||||
self.comb += opi_clk_en.eq((tx_run & txphy_clken) | (~tx_run & txcmd_clken))
|
||||
self.comb += self.tx.eq((tx_run & txphy_oe) | (~tx_run & txcmd_oe))
|
||||
self.sync += opi_cs_n.eq( (tx_run & txphy_cs_n) | (~tx_run & txcmd_cs_n) )
|
||||
self.comb += If( tx_run, self.do.eq(txphy_do) ).Else( self.do.eq(txcmd_do) )
|
||||
self.comb += opi_clk_en.eq( (tx_run & txphy_clken) | (~tx_run & txcmd_clken) )
|
||||
self.comb += self.tx.eq( (tx_run & txphy_oe) | (~tx_run & txcmd_oe) )
|
||||
tx_almostfull = Signal()
|
||||
self.sync += tx_almostfull.eq(rx_almostfull) # sync the rx_almostfull signal into the local clock domain
|
||||
txphy_bus = Signal()
|
||||
|
@ -500,7 +488,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
txphy.act("TX_SETUP",
|
||||
NextValue(opi_rx_run, 0),
|
||||
NextValue(txphy_cnt, txphy_cnt - 1),
|
||||
If(txphy_cnt > 0,
|
||||
If( txphy_cnt > 0,
|
||||
NextValue(txphy_cs_n, 1)
|
||||
).Else(
|
||||
NextValue(txphy_cs_n, 0),
|
||||
|
@ -542,7 +530,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
txphy.act("TX_FILL",
|
||||
If(tx_run,
|
||||
If(((~txphy_bus & (self.bus.cyc & self.bus.stb & ~self.bus.we & (self.bus.cti == 2))) &
|
||||
If( ((~txphy_bus & (self.bus.cyc & self.bus.stb & ~self.bus.we & (self.bus.cti == 2))) &
|
||||
(opi_addr[2:] != self.bus.adr)) | tx_resetcycle,
|
||||
# it's a new bus cycle, and the requested address is not equal to the current read buffer address
|
||||
NextValue(txphy_clken, 1),
|
||||
|
@ -578,7 +566,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
|
||||
# --------- OPI CMD machine ------------------------------
|
||||
#--------- OPI CMD machine ------------------------------
|
||||
self.submodules.opicmd = opicmd = FSM(reset_state="RESET")
|
||||
opicmd.act("RESET",
|
||||
NextValue(txcmd_do, 0),
|
||||
|
@ -608,7 +596,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
# - then run the command
|
||||
# - Else wait until a bus cycle, and once it happens, put the system into run mode
|
||||
If(self.bus.cyc & self.bus.stb,
|
||||
If(~self.bus.we & (self.bus.cti == 2),
|
||||
If(~self.bus.we & (self.bus.cti ==2),
|
||||
NextState("TX_RUN")
|
||||
).Else(
|
||||
# handle other cases here, e.g. what do we do if we get a write? probably
|
||||
|
@ -626,7 +614,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
opicmd.act("WAIT_DISPATCH", # wait until the current cycle is done, then stop TX and dispatch command
|
||||
If(~(self.bus.cyc & self.bus.stb),
|
||||
If( ~(self.bus.cyc & self.bus.stb),
|
||||
NextValue(tx_run, 0),
|
||||
NextState("DISPATCH_CMD")
|
||||
)
|
||||
|
@ -665,8 +653,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
spi_di_load = Signal() # spi_do load is pipelined back one cycle using this mechanism
|
||||
spi_di_load2 = Signal()
|
||||
spi_ack_pipe = Signal()
|
||||
self.sync += [
|
||||
# pipelining is required the MISO path is very slow (IOB->fabric FD), and a falling-edge retiming reg is used to meet timing
|
||||
self.sync += [ # pipelining is required the MISO path is very slow (IOB->fabric FD), and a falling-edge retiming reg is used to meet timing
|
||||
spi_di_load2.eq(spi_di_load),
|
||||
If(spi_di_load2, spi_di.eq(Cat(self.miso, spi_si[:-1]))).Else(spi_di.eq(spi_di)),
|
||||
spi_ack.eq(spi_ack_pipe),
|
||||
|
@ -690,11 +677,11 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
spiphy.act("REQ",
|
||||
If(spicount > 0,
|
||||
NextValue(spicount, spicount - 1),
|
||||
NextValue(spicount, spicount-1),
|
||||
NextValue(spi_clk_en, 1),
|
||||
NextValue(spi_so, Cat(0, spi_so[:-1])),
|
||||
NextValue(spi_ack_pipe, 0),
|
||||
).Elif((spicount == 0) & spi_req & ~spi_dummy, # back-to-back transaction
|
||||
).Elif( (spicount == 0) & spi_req & ~spi_dummy, # back-to-back transaction
|
||||
NextValue(spi_clk_en, 1),
|
||||
NextValue(spicount, 7),
|
||||
NextValue(spi_clk_en, 1),
|
||||
|
@ -702,12 +689,12 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
spi_di_load.eq(1), # "naked" .eq() create single-cycle pulses that default back to 0
|
||||
NextValue(spi_ack_pipe, 1),
|
||||
NextValue(spi_dummy, has_dummy),
|
||||
).Elif((spicount == 0) & ~spi_req & ~spi_dummy, # go back to idle
|
||||
).Elif( (spicount == 0) & ~spi_req & ~spi_dummy, # go back to idle
|
||||
spi_di_load.eq(1),
|
||||
NextValue(spi_ack_pipe, 1),
|
||||
NextValue(spi_clk_en, 0),
|
||||
NextState("RESET"),
|
||||
).Elif((spicount == 0) & spi_dummy,
|
||||
).Elif( (spicount == 0) & spi_dummy,
|
||||
spi_di_load.eq(1),
|
||||
NextValue(spicount, self.config.fields.dummy),
|
||||
NextValue(spi_clk_en, 1),
|
||||
|
@ -733,6 +720,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
|
||||
|
||||
# SPI MAC machine -------------------------------------------------------------------------------
|
||||
# default active on boot
|
||||
addr_updated = Signal()
|
||||
|
@ -757,14 +745,13 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
mac.act("IDLE",
|
||||
If(self.spi_mode, # this machine stays in idle once spi_mode is dropped
|
||||
NextValue(self.bus.ack, 0),
|
||||
If((self.bus.cyc == 1) & (self.bus.stb == 1) & (self.bus.we == 0) & (self.bus.cti != 7),
|
||||
# read cycle requested, not end-of-burst
|
||||
If((rom_addr[2:] != self.bus.adr) & new_cycle,
|
||||
If((self.bus.cyc == 1) & (self.bus.stb == 1) & (self.bus.we == 0) & (self.bus.cti != 7), # read cycle requested, not end-of-burst
|
||||
If( (rom_addr[2:] != self.bus.adr) & new_cycle,
|
||||
NextValue(rom_addr, Cat(Signal(2, reset=0), self.bus.adr)),
|
||||
NextValue(addr_updated, 1),
|
||||
NextValue(spi_cs_n, 1), # raise CS in anticipation of a new address cycle
|
||||
NextState("SPI_READ_32_CS"),
|
||||
).Elif((rom_addr[2:] == self.bus.adr) | (~new_cycle & self.bus.cti == 2),
|
||||
).Elif( (rom_addr[2:] == self.bus.adr) | (~new_cycle & self.bus.cti == 2),
|
||||
NextValue(mac_count, 3), # get another beat of 4 bytes at the next address
|
||||
NextState("SPI_READ_32")
|
||||
).Else(
|
||||
|
@ -791,21 +778,21 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
|
||||
# --------- wakup chip ------------------------------
|
||||
#--------- wakup chip ------------------------------
|
||||
mac.act("WAKEUP_PRE",
|
||||
NextValue(spi_cs_n, 1), # why isn't this sticking? i shouldn't have to put this here
|
||||
NextValue(mac_count, 4),
|
||||
NextState("WAKEUP_PRE_CS_WAIT")
|
||||
)
|
||||
mac.act("WAKEUP_PRE_CS_WAIT",
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count-1),
|
||||
If(mac_count == 0,
|
||||
NextState("WAKEUP_WUP"),
|
||||
NextValue(spi_cs_n, 0),
|
||||
)
|
||||
)
|
||||
mac.act("WAKEUP_WUP",
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count-1),
|
||||
If(mac_count == 0,
|
||||
NextValue(spi_cs_n, 0),
|
||||
NextValue(spi_do, 0xab), # wakeup from deep sleep
|
||||
|
@ -822,9 +809,9 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
|
||||
# --------- WREN+CR2 - dummy cycles ------------------------------
|
||||
#--------- WREN+CR2 - dummy cycles ------------------------------
|
||||
mac.act("WAKEUP_CR2_WREN_1",
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count-1),
|
||||
If(mac_count == 0,
|
||||
NextValue(spi_cs_n, 0),
|
||||
NextValue(spi_do, 0x06), # WREN to unlock CR2 writing
|
||||
|
@ -841,7 +828,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
mac.act("WAKEUP_CR2_DUMMY_CMD",
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count-1),
|
||||
If(mac_count == 0,
|
||||
NextValue(spi_cs_n, 0),
|
||||
NextValue(spi_do, 0x72), # CR2 command
|
||||
|
@ -853,7 +840,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
mac.act("WAKEUP_CR2_DUMMY_ADRHI",
|
||||
NextValue(spi_do, 0x00), # we want to send 00_00_03_00
|
||||
If(spi_ack,
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count -1),
|
||||
),
|
||||
If(mac_count == 0,
|
||||
NextState("WAKEUP_CR2_DUMMY_ADRMID")
|
||||
|
@ -880,9 +867,9 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
|
||||
# --------- WREN+CR2 to DOPI mode ------------------------------
|
||||
#--------- WREN+CR2 to DOPI mode ------------------------------
|
||||
mac.act("WAKEUP_CR2_WREN_2",
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count-1),
|
||||
If(mac_count == 0,
|
||||
NextValue(spi_cs_n, 0),
|
||||
NextValue(spi_do, 0x06), # WREN to unlock CR2 writing
|
||||
|
@ -899,7 +886,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
)
|
||||
mac.act("WAKEUP_CR2_DOPI_CMD",
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count-1),
|
||||
If(mac_count == 0,
|
||||
NextValue(spi_cs_n, 0),
|
||||
NextValue(spi_do, 0x72), # CR2 command
|
||||
|
@ -931,14 +918,14 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
mac.act("WAKEUP_CS_EXIT",
|
||||
NextValue(self.spi_mode, 0), # now enter DOPI mode
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count-1),
|
||||
If(mac_count == 0,
|
||||
NextState("IDLE"),
|
||||
)
|
||||
)
|
||||
|
||||
if spiread:
|
||||
# --------- SPI read machine ------------------------------
|
||||
#--------- SPI read machine ------------------------------
|
||||
mac.act("SPI_READ_32",
|
||||
If(addr_updated,
|
||||
NextState("SPI_READ_32_CS"),
|
||||
|
@ -954,9 +941,8 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
).Else(
|
||||
NextValue(spi_req, 0),
|
||||
If(spi_ack,
|
||||
If(self.spi_mode,
|
||||
# protect these in a spi_mode mux to prevent excess inference of logic to handle otherwise implicit dual-master situation
|
||||
NextValue(self.bus.dat_r, Cat(d_to_wb[8:], spi_di)),
|
||||
If(self.spi_mode, # protect these in a spi_mode mux to prevent excess inference of logic to handle otherwise implicit dual-master situation
|
||||
NextValue(self.bus.dat_r, Cat(d_to_wb[8:],spi_di)),
|
||||
NextValue(self.bus.ack, 1),
|
||||
),
|
||||
NextValue(rom_addr, rom_addr + 1),
|
||||
|
@ -968,14 +954,14 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
mac.act("SPI_READ_32_D",
|
||||
If(spi_ack,
|
||||
# shift in one byte at a time to d_to_wb(32)
|
||||
NextValue(d_to_wb, Cat(d_to_wb[8:], spi_di, )),
|
||||
NextValue(d_to_wb, Cat(d_to_wb[8:],spi_di,)),
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextState("SPI_READ_32"),
|
||||
NextValue(rom_addr, rom_addr + 1),
|
||||
)
|
||||
)
|
||||
mac.act("SPI_READ_32_CS",
|
||||
NextValue(mac_count, mac_count - 1),
|
||||
NextValue(mac_count, mac_count-1),
|
||||
If(mac_count == 0,
|
||||
NextValue(spi_cs_n, 0),
|
||||
NextState("SPI_READ_32_A0"),
|
||||
|
@ -987,8 +973,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
NextState("SPI_READ_32_A1"),
|
||||
)
|
||||
mac.act("SPI_READ_32_A1",
|
||||
NextValue(spi_do, rom_addr[24:] & 0x7),
|
||||
# queue up MSB to send, leave req high; mask off unused high bits
|
||||
NextValue(spi_do, rom_addr[24:] & 0x7), # queue up MSB to send, leave req high; mask off unused high bits
|
||||
If(spi_ack,
|
||||
NextState("SPI_READ_32_A2"),
|
||||
)
|
||||
|
@ -1045,10 +1030,8 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
|||
CSRField("ecc_address", size=32, description="Address of the most recent ECC event")
|
||||
])
|
||||
self.ecc_status = CSRStatus(fields=[
|
||||
CSRField("ecc_error", size=1,
|
||||
description="Live status of the ECS_N bit (ECC error on current packet when low)"),
|
||||
CSRField("ecc_overflow", size=1,
|
||||
description="More than one ECS_N event has happened since th last time ecc_address was checked")
|
||||
CSRField("ecc_error", size=1, description="Live status of the ECS_N bit (ECC error on current packet when low)"),
|
||||
CSRField("ecc_overflow", size=1, description="More than one ECS_N event has happened since th last time ecc_address was checked")
|
||||
])
|
||||
|
||||
self.comb += self.ecc_status.fields.ecc_error.eq(ecs_n)
|
||||
|
|
Loading…
Reference in New Issue