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.csr_eventmanager import *
|
||||||
from litex.soc.interconnect import wishbone
|
from litex.soc.interconnect import wishbone
|
||||||
from litex.soc.integration.doc import AutoDoc, ModuleDoc
|
from litex.soc.integration.doc import AutoDoc, ModuleDoc
|
||||||
|
@ -89,6 +86,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
Instance("BUFR", i_I=pads.dqs, o_O=dqs_iobuf),
|
Instance("BUFR", i_I=pads.dqs, o_O=dqs_iobuf),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# DQ connections -------------------------------------------------------------------------
|
# DQ connections -------------------------------------------------------------------------
|
||||||
# PHY API
|
# PHY API
|
||||||
self.do = Signal(16) # OPI data to SPI
|
self.do = Signal(16) # OPI data to SPI
|
||||||
|
@ -133,28 +131,21 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
if i == 1: # only wire up o_CNTVALUEOUT for one instance
|
if i == 1: # only wire up o_CNTVALUEOUT for one instance
|
||||||
self.specials += Instance("IDELAYE2",
|
self.specials += Instance("IDELAYE2",
|
||||||
p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA",
|
p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA",
|
||||||
p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="FALSE",
|
p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="FALSE", p_REFCLK_FREQUENCY=200.0,
|
||||||
p_REFCLK_FREQUENCY=200.0,
|
p_PIPE_SEL="FALSE", p_IDELAY_VALUE=dq_delay_taps, p_IDELAY_TYPE=delay_type,
|
||||||
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_C=ClockSignal(), i_CINVCTRL=0, i_REGRST=0, i_LDPIPEEN=0, i_INC=0, i_CE=0,
|
||||||
i_CE=0,
|
|
||||||
i_LD=self.delay_update,
|
i_LD=self.delay_update,
|
||||||
i_CNTVALUEIN=self.delay_config.fields.d,
|
i_CNTVALUEIN=self.delay_config.fields.d, o_CNTVALUEOUT=self.delay_status.fields.q,
|
||||||
o_CNTVALUEOUT=self.delay_status.fields.q,
|
|
||||||
i_IDATAIN=dq.i[i-1], o_DATAOUT=dq_delayed[i],
|
i_IDATAIN=dq.i[i-1], o_DATAOUT=dq_delayed[i],
|
||||||
),
|
),
|
||||||
else: # don't wire up o_CNTVALUEOUT for others
|
else: # don't wire up o_CNTVALUEOUT for others
|
||||||
self.specials += Instance("IDELAYE2",
|
self.specials += Instance("IDELAYE2",
|
||||||
p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA",
|
p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA",
|
||||||
p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="FALSE",
|
p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="FALSE", p_REFCLK_FREQUENCY=200.0,
|
||||||
p_REFCLK_FREQUENCY=200.0,
|
p_PIPE_SEL="FALSE", p_IDELAY_VALUE=dq_delay_taps, p_IDELAY_TYPE=delay_type,
|
||||||
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_C=ClockSignal(), i_CINVCTRL=0, i_REGRST=0, i_LDPIPEEN=0, i_INC=0, i_CE=0,
|
||||||
i_CE=0,
|
|
||||||
i_LD=self.delay_update,
|
i_LD=self.delay_update,
|
||||||
i_CNTVALUEIN=self.delay_config.fields.d,
|
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],
|
||||||
|
@ -342,8 +333,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
""")
|
""")
|
||||||
self.bus = wishbone.Interface()
|
self.bus = wishbone.Interface()
|
||||||
|
|
||||||
self.command = CSRStorage(
|
self.command = CSRStorage(description="Write individual bits to issue special commands to SPI; setting multiple bits at once leads to undefined behavior.",
|
||||||
description="Write individual bits to issue special commands to SPI; setting multiple bits at once leads to undefined behavior.",
|
|
||||||
fields=[
|
fields=[
|
||||||
CSRField("wakeup", size=1, description="Sequence through init & wakeup routine"),
|
CSRField("wakeup", size=1, description="Sequence through init & wakeup routine"),
|
||||||
CSRField("sector_erase", size=1, description="Erase a sector"),
|
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)
|
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)
|
has_dummy = Signal() # indicates if the current "req" requires dummy cycles to be appended (used for both OPI/SPI)
|
||||||
rom_addr = Signal(32,
|
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
|
||||||
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
|
# MAC/PHY abstraction for OPI
|
||||||
txphy_do = Signal(16) # two sources of data out for OPI, one from the PHY, one from MAC
|
txphy_do = Signal(16) # two sources of data out for OPI, one from the PHY, one from MAC
|
||||||
|
@ -445,9 +434,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
).Elif(opi_rx_run,
|
).Elif(opi_rx_run,
|
||||||
NextValue(rx_wren, 1),
|
NextValue(rx_wren, 1),
|
||||||
If( (self.bus.cyc & self.bus.stb & ~self.bus.we) & ((self.bus.cti == 2) |
|
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
|
||||||
self.bus.cti == 7) & ~self.bus.ack)),
|
|
||||||
# handle case of non-pipelined read, ack is late
|
|
||||||
If(~rx_empty,
|
If(~rx_empty,
|
||||||
NextValue(self.bus.dat_r, opi_fifo_rd),
|
NextValue(self.bus.dat_r, opi_fifo_rd),
|
||||||
rx_rden.eq(1),
|
rx_rden.eq(1),
|
||||||
|
@ -468,6 +455,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# TxPHY machine: OPI -------------------------------------------------------------------------
|
# TxPHY machine: OPI -------------------------------------------------------------------------
|
||||||
txphy_cnt = Signal(4)
|
txphy_cnt = Signal(4)
|
||||||
tx_run = Signal()
|
tx_run = Signal()
|
||||||
|
@ -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_load = Signal() # spi_do load is pipelined back one cycle using this mechanism
|
||||||
spi_di_load2 = Signal()
|
spi_di_load2 = Signal()
|
||||||
spi_ack_pipe = Signal()
|
spi_ack_pipe = Signal()
|
||||||
self.sync += [
|
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
|
||||||
# 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),
|
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)),
|
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),
|
spi_ack.eq(spi_ack_pipe),
|
||||||
|
@ -733,6 +720,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# SPI MAC machine -------------------------------------------------------------------------------
|
# SPI MAC machine -------------------------------------------------------------------------------
|
||||||
# default active on boot
|
# default active on boot
|
||||||
addr_updated = Signal()
|
addr_updated = Signal()
|
||||||
|
@ -757,8 +745,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
mac.act("IDLE",
|
mac.act("IDLE",
|
||||||
If(self.spi_mode, # this machine stays in idle once spi_mode is dropped
|
If(self.spi_mode, # this machine stays in idle once spi_mode is dropped
|
||||||
NextValue(self.bus.ack, 0),
|
NextValue(self.bus.ack, 0),
|
||||||
If((self.bus.cyc == 1) & (self.bus.stb == 1) & (self.bus.we == 0) & (self.bus.cti != 7),
|
If((self.bus.cyc == 1) & (self.bus.stb == 1) & (self.bus.we == 0) & (self.bus.cti != 7), # read cycle requested, not end-of-burst
|
||||||
# read cycle requested, not end-of-burst
|
|
||||||
If( (rom_addr[2:] != self.bus.adr) & new_cycle,
|
If( (rom_addr[2:] != self.bus.adr) & new_cycle,
|
||||||
NextValue(rom_addr, Cat(Signal(2, reset=0), self.bus.adr)),
|
NextValue(rom_addr, Cat(Signal(2, reset=0), self.bus.adr)),
|
||||||
NextValue(addr_updated, 1),
|
NextValue(addr_updated, 1),
|
||||||
|
@ -954,8 +941,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
).Else(
|
).Else(
|
||||||
NextValue(spi_req, 0),
|
NextValue(spi_req, 0),
|
||||||
If(spi_ack,
|
If(spi_ack,
|
||||||
If(self.spi_mode,
|
If(self.spi_mode, # protect these in a spi_mode mux to prevent excess inference of logic to handle otherwise implicit dual-master situation
|
||||||
# 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.dat_r, Cat(d_to_wb[8:],spi_di)),
|
||||||
NextValue(self.bus.ack, 1),
|
NextValue(self.bus.ack, 1),
|
||||||
),
|
),
|
||||||
|
@ -987,8 +973,7 @@ class SpiOpi(Module, AutoCSR, AutoDoc):
|
||||||
NextState("SPI_READ_32_A1"),
|
NextState("SPI_READ_32_A1"),
|
||||||
)
|
)
|
||||||
mac.act("SPI_READ_32_A1",
|
mac.act("SPI_READ_32_A1",
|
||||||
NextValue(spi_do, rom_addr[24:] & 0x7),
|
NextValue(spi_do, rom_addr[24:] & 0x7), # queue up MSB to send, leave req high; mask off unused high bits
|
||||||
# queue up MSB to send, leave req high; mask off unused high bits
|
|
||||||
If(spi_ack,
|
If(spi_ack,
|
||||||
NextState("SPI_READ_32_A2"),
|
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")
|
CSRField("ecc_address", size=32, description="Address of the most recent ECC event")
|
||||||
])
|
])
|
||||||
self.ecc_status = CSRStatus(fields=[
|
self.ecc_status = CSRStatus(fields=[
|
||||||
CSRField("ecc_error", size=1,
|
CSRField("ecc_error", size=1, description="Live status of the ECS_N bit (ECC error on current packet when low)"),
|
||||||
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_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)
|
self.comb += self.ecc_status.fields.ecc_error.eq(ecs_n)
|
||||||
|
|
Loading…
Reference in New Issue