Deprecate slave terminology
http://oshwa.org/a-resolution-to-redefine-spi-signal-names
This commit is contained in:
parent
00d1118d41
commit
0b4c5059f2
|
@ -16,13 +16,17 @@ class I2S_FORMAT(Enum):
|
|||
I2S_LEFT_JUSTIFIED = 2
|
||||
|
||||
class S7I2S(Module, AutoCSR, AutoDoc):
|
||||
def __init__(self, pads, fifo_depth=256, master=False, concatenate_channels=True, sample_width=16, frame_format=I2S_FORMAT.I2S_LEFT_JUSTIFIED, lrck_ref_freq=100e6, lrck_freq=44100, bits_per_channel=28):
|
||||
def __init__(self, pads, fifo_depth=256, controller=False, master=False, concatenate_channels=True, sample_width=16, frame_format=I2S_FORMAT.I2S_LEFT_JUSTIFIED, lrck_ref_freq=100e6, lrck_freq=44100, bits_per_channel=28):
|
||||
if master == True:
|
||||
print("Master/slave terminology deprecated, please use controller/peripheral. Please see http://oshwa.org/a-resolution-to-redefine-spi-signal-names.")
|
||||
controller = True
|
||||
|
||||
self.intro = ModuleDoc("""Intro
|
||||
|
||||
I2S master/slave creates a master/slave audio interface instance depending on a configured master variable.
|
||||
I2S controller/peripheral creates a controller/peripheral audio interface instance depending on a configured controller variable.
|
||||
Tx and Rx interfaces are inferred based upon the presence or absence of the respective pins in the "pads" argument.
|
||||
|
||||
When device is configured as master you can manipulate LRCK and SCLK signals using below variables.
|
||||
When device is configured as controller you can manipulate LRCK and SCLK signals using below variables.
|
||||
|
||||
- lrck_ref_freq - is a reference signal that is required to achive desired LRCK and SCLK frequencies.
|
||||
Have be the same as your sys_clk.
|
||||
|
@ -31,8 +35,8 @@ class S7I2S(Module, AutoCSR, AutoDoc):
|
|||
- bits_per_channel - defines SCLK frequency. Mind you, that based on sys_clk frequency,
|
||||
the requested amount of bits per channel may vary from configured.
|
||||
|
||||
When device is configured as slave I2S interface, sampling rate and framing is set by the
|
||||
programming of the audio CODEC chip. A slave configuration defers the
|
||||
When device is configured as peripheral I2S interface, sampling rate and framing is set by the
|
||||
programming of the audio CODEC chip. A peripheral configuration defers the
|
||||
generation of audio clocks to the CODEC, which has PLLs specialized to generate the correct
|
||||
frequencies for audio sampling rates.
|
||||
|
||||
|
@ -163,7 +167,7 @@ class S7I2S(Module, AutoCSR, AutoDoc):
|
|||
]
|
||||
|
||||
|
||||
if master == True:
|
||||
if controller == True:
|
||||
if bits_per_channel < sample_width and frame_format == I2S_FORMAT.I2S_STANDARD:
|
||||
bits_per_channel = sample_width + 1
|
||||
print("I2S warning: bits per channel can't be smaller than sample_width. Setting bits per channel to {}".format(sample_width + 1))
|
||||
|
|
|
@ -14,7 +14,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
dq_delay_taps = 31,
|
||||
sclk_name = "SCLK_ODDR",
|
||||
iddr_name = "SPI_IDDR",
|
||||
miso_name = "MISO_FDRE",
|
||||
cipo_name = "CIPO_FDRE",
|
||||
sim = False,
|
||||
spiread = False,
|
||||
prefetch_lines = 1):
|
||||
|
@ -100,8 +100,8 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
self.di = Signal(16) # OPI data from SPI
|
||||
self.tx = Signal() # When asserted OPI is transmitting data to SPI, otherwise, receiving
|
||||
|
||||
self.mosi = Signal() # SPI data to SPI
|
||||
self.miso = Signal() # SPI data from SPI
|
||||
self.copi = Signal() # SPI data to SPI
|
||||
self.cipo = Signal() # SPI data from SPI
|
||||
|
||||
# Delay programming API
|
||||
self.delay_config = CSRStorage(fields=[
|
||||
|
@ -125,7 +125,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
self.comb += self.di.eq(Cat(di_fall, di_rise))
|
||||
|
||||
# OPI DDR registers
|
||||
dq = TSTriple(7) # dq[0] is special because it is also MOSI
|
||||
dq = TSTriple(7) # dq[0] is special because it is also copi
|
||||
dq_delayed = Signal(8)
|
||||
self.specials += dq.get_tristate(pads.dq[1:])
|
||||
for i in range(1, 8):
|
||||
|
@ -198,19 +198,19 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
)
|
||||
# SPI SDR register
|
||||
self.specials += [
|
||||
Instance("FDRE", name="{}".format(miso_name),
|
||||
Instance("FDRE", name="{}".format(cipo_name),
|
||||
i_C = ~ClockSignal("spinor"),
|
||||
i_CE = 1,
|
||||
i_R = 0,
|
||||
o_Q = self.miso,
|
||||
o_Q = self.cipo,
|
||||
i_D = dq_delayed[1],
|
||||
)
|
||||
]
|
||||
|
||||
# bit 0 (MOSI) is special-cased to handle SPI mode
|
||||
dq_mosi = TSTriple(1) # this has similar structure but an independent "oe" signal
|
||||
self.specials += dq_mosi.get_tristate(pads.dq[0])
|
||||
do_mux_rise = Signal() # mux signal for mosi/dq select of bit 0
|
||||
# bit 0 (copi) is special-cased to handle SPI mode
|
||||
dq_copi = TSTriple(1) # this has similar structure but an independent "oe" signal
|
||||
self.specials += dq_copi.get_tristate(pads.dq[0])
|
||||
do_mux_rise = Signal() # mux signal for copi/dq select of bit 0
|
||||
do_mux_fall = Signal()
|
||||
self.specials += [
|
||||
Instance("ODDR",
|
||||
|
@ -221,7 +221,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
i_CE = 1,
|
||||
i_D1 = do_mux_rise,
|
||||
i_D2 = do_mux_fall,
|
||||
o_Q = dq_mosi.o,
|
||||
o_Q = dq_copi.o,
|
||||
),
|
||||
Instance("IDDR",
|
||||
p_DDR_CLK_EDGE="SAME_EDGE_PIPELINED",
|
||||
|
@ -253,11 +253,11 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
i_CE = 0,
|
||||
i_LD = self.delay_update,
|
||||
i_CNTVALUEIN = self.delay_config.fields.d,
|
||||
i_IDATAIN = dq_mosi.i,
|
||||
i_IDATAIN = dq_copi.i,
|
||||
o_DATAOUT = dq_delayed[0],
|
||||
),
|
||||
else:
|
||||
self.comb += dq_delayed[0].eq(dq_mosi.i)
|
||||
self.comb += dq_delayed[0].eq(dq_copi.i)
|
||||
|
||||
# Wire up SCLK interface
|
||||
clk_en = Signal()
|
||||
|
@ -430,11 +430,11 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
# Tristate mux
|
||||
self.sync += [
|
||||
dq.oe.eq(~spi_mode & self.tx),
|
||||
dq_mosi.oe.eq(spi_mode | self.tx),
|
||||
dq_copi.oe.eq(spi_mode | self.tx),
|
||||
]
|
||||
# Data out mux (no data in mux, as we can just sample data in all the time without harm)
|
||||
self.comb += do_mux_rise.eq(~spi_mode & do_rise[0] | spi_mode & self.mosi)
|
||||
self.comb += do_mux_fall.eq(~spi_mode & do_fall[0] | spi_mode & self.mosi)
|
||||
self.comb += do_mux_rise.eq(~spi_mode & do_rise[0] | spi_mode & self.copi)
|
||||
self.comb += do_mux_fall.eq(~spi_mode & do_fall[0] | spi_mode & self.copi)
|
||||
|
||||
# Indicates if the current "req" requires dummy cycles to be appended (used for both OPI/SPI)
|
||||
has_dummy = Signal()
|
||||
|
@ -746,7 +746,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
# internal signals are:
|
||||
# selection - spi_mode
|
||||
# OPI - self.do(16), self.di(16), self.tx
|
||||
# SPI - self.mosi, self.miso
|
||||
# SPI - self.copi, self.cipo
|
||||
# cs_n - both
|
||||
# ecs_n - OPI
|
||||
# clk_en - both
|
||||
|
@ -758,15 +758,15 @@ class S7SPIOPI(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()
|
||||
# Pipelining is required the MISO path is very slow (IOB->fabric FD), and a falling-edge
|
||||
# Pipelining is required the cipo path is very slow (IOB->fabric FD), and a falling-edge
|
||||
# retiming reg is used to meet timing
|
||||
self.sync += [
|
||||
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.cipo, spi_si[:-1]))).Else(spi_di.eq(spi_di)),
|
||||
spi_ack.eq(spi_ack_pipe),
|
||||
]
|
||||
self.comb += self.mosi.eq(spi_so[7])
|
||||
self.sync += spi_si.eq(Cat(self.miso, spi_si[:-1]))
|
||||
self.comb += self.copi.eq(spi_so[7])
|
||||
self.sync += spi_si.eq(Cat(self.cipo, spi_si[:-1]))
|
||||
self.submodules.spiphy = spiphy = FSM(reset_state="RESET")
|
||||
spiphy.act("RESET",
|
||||
If(spi_req,
|
||||
|
@ -1056,7 +1056,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
|||
NextValue(spi_req, 0),
|
||||
If(spi_ack,
|
||||
# Protect these in a spi_mode mux to prevent excess inference of logic to
|
||||
# handle otherwise implicit dual-master situation
|
||||
# handle otherwise implicit dual-controller situation
|
||||
If(spi_mode,
|
||||
NextValue(bus.dat_r, Cat(d_to_wb[8:],spi_di)),
|
||||
NextValue(bus.ack, 1),
|
||||
|
|
Loading…
Reference in New Issue