Merge branch 'master' of http://github.com/enjoy-digital/litex
This commit is contained in:
commit
e9f0ff68ce
|
@ -11,9 +11,7 @@ from litex.soc.integration.doc import AutoDoc, ModuleDoc
|
||||||
|
|
||||||
class S7I2SSlave(Module, AutoCSR, AutoDoc):
|
class S7I2SSlave(Module, AutoCSR, AutoDoc):
|
||||||
def __init__(self, pads, fifo_depth=256):
|
def __init__(self, pads, fifo_depth=256):
|
||||||
self.intro = ModuleDoc("""
|
self.intro = ModuleDoc("""Intro
|
||||||
Intro
|
|
||||||
*******
|
|
||||||
|
|
||||||
I2S slave creates a slave audio interface instance. Tx and Rx interfaces are inferred based
|
I2S slave creates a slave audio interface instance. Tx and Rx interfaces are inferred based
|
||||||
upon the presence or absence of the respective pins in the "pads" argument.
|
upon the presence or absence of the respective pins in the "pads" argument.
|
||||||
|
@ -24,7 +22,7 @@ class S7I2SSlave(Module, AutoCSR, AutoDoc):
|
||||||
to a CODEC without a programmable bit offset!
|
to a CODEC without a programmable bit offset!
|
||||||
|
|
||||||
System Interface
|
System Interface
|
||||||
=================
|
----------------
|
||||||
|
|
||||||
Audio interchange is done with the system using 16-bit stereo samples, with the right channel
|
Audio interchange is done with the system using 16-bit stereo samples, with the right channel
|
||||||
mapped to the least significant word of a 32-bit word. Thus each 32-bit word is a single
|
mapped to the least significant word of a 32-bit word. Thus each 32-bit word is a single
|
||||||
|
@ -56,12 +54,12 @@ class S7I2SSlave(Module, AutoCSR, AutoDoc):
|
||||||
- enable the Tx FIFO to run
|
- enable the Tx FIFO to run
|
||||||
- poll or wait for interrupt; upon interrupt, write `fifo_depth` words. Repeat.
|
- poll or wait for interrupt; upon interrupt, write `fifo_depth` words. Repeat.
|
||||||
- to close stream, mute the DAC and stop the request clock. Ideally, this can be completed
|
- to close stream, mute the DAC and stop the request clock. Ideally, this can be completed
|
||||||
before the FIFO is emptied, so there is no jarring pop or truncation of data
|
before the FIFO is emptied, so there is no jarring pop or truncation of data
|
||||||
- stop FIFO running. Next initiation should reset the FIFO to ensure leftover previous data
|
- stop FIFO running. Next initiation should reset the FIFO to ensure leftover previous data
|
||||||
in FIFO is cleared.
|
in FIFO is cleared.
|
||||||
|
|
||||||
CODEC Interface
|
CODEC Interface
|
||||||
================
|
---------------
|
||||||
|
|
||||||
The interface assumes we have a sysclk domain running around 100MHz, and that our typical max
|
The interface assumes we have a sysclk domain running around 100MHz, and that our typical max
|
||||||
audio rate is 44.1kHz * 24bits * 2channels = 2.1168MHz audio clock. Thus, the architecture
|
audio rate is 44.1kHz * 24bits * 2channels = 2.1168MHz audio clock. Thus, the architecture
|
||||||
|
@ -87,12 +85,11 @@ class S7I2SSlave(Module, AutoCSR, AutoDoc):
|
||||||
- Data is updated on the falling edge
|
- Data is updated on the falling edge
|
||||||
- Data is sampled on the rising edge
|
- Data is sampled on the rising edge
|
||||||
- Words are MSB-to-LSB, left-justified (**NOTE: this is a deviation from strict I2S, which
|
- Words are MSB-to-LSB, left-justified (**NOTE: this is a deviation from strict I2S, which
|
||||||
offsets by 1 from the left**)
|
offsets by 1 from the left**)
|
||||||
- Sync is an input (FPGA is slave, codec is master): low => left channel, high => right channel
|
- Sync is an input (FPGA is slave, codec is master): low => left channel, high => right channel
|
||||||
- Sync can be longer than the wordlen, extra bits are just ignored
|
- Sync can be longer than the wordlen, extra bits are just ignored
|
||||||
- Tx is data to the codec (SDI pin on LM49352)
|
- Tx is data to the codec (SDI pin on LM49352)
|
||||||
- Rx is data from the codec (SDO pin on LM49352)
|
- Rx is data from the codec (SDO pin on LM49352)
|
||||||
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# One cache line is 8 32-bit words, need to always have enough space for one line or else
|
# One cache line is 8 32-bit words, need to always have enough space for one line or else
|
||||||
|
|
|
@ -18,9 +18,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
||||||
sim = False,
|
sim = False,
|
||||||
spiread = False,
|
spiread = False,
|
||||||
prefetch_lines = 1):
|
prefetch_lines = 1):
|
||||||
self.intro = ModuleDoc("""
|
self.intro = ModuleDoc("""Intro
|
||||||
Intro
|
|
||||||
********
|
|
||||||
|
|
||||||
SpiOpi implements a dual-mode SPI or OPI interface. OPI is an octal (8-bit) wide variant of
|
SpiOpi implements a dual-mode SPI or OPI interface. OPI is an octal (8-bit) wide variant of
|
||||||
SPI, which is unique to Macronix parts. It is concurrently interoperable with SPI. The chip
|
SPI, which is unique to Macronix parts. It is concurrently interoperable with SPI. The chip
|
||||||
|
@ -300,14 +298,13 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.architecture = ModuleDoc("""
|
self.architecture = ModuleDoc("""Architecture
|
||||||
Architecture
|
|
||||||
**************
|
|
||||||
|
|
||||||
The machine is split into two separate pieces, one to handle SPI, and one to handle OPI.
|
The machine is split into two separate pieces, one to handle SPI, and one to handle OPI.
|
||||||
|
|
||||||
SPI
|
SPI
|
||||||
=====
|
-----
|
||||||
|
|
||||||
The SPI machine architecture is split into two levels: MAC and PHY.
|
The SPI machine architecture is split into two levels: MAC and PHY.
|
||||||
|
|
||||||
The MAC layer is responsible for:
|
The MAC layer is responsible for:
|
||||||
|
@ -333,7 +330,8 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
||||||
Thus holding "req" high can allow the PHY to back-to-back issue cycles without pause.
|
Thus holding "req" high can allow the PHY to back-to-back issue cycles without pause.
|
||||||
|
|
||||||
OPI
|
OPI
|
||||||
=====
|
-----
|
||||||
|
|
||||||
The OPI machine is split into three parts: a command controller, a Tx PHY, and an Rx PHY.
|
The OPI machine is split into three parts: a command controller, a Tx PHY, and an Rx PHY.
|
||||||
|
|
||||||
The Tx PHY is configured with a "dummy cycle" count register, as there is a variable length
|
The Tx PHY is configured with a "dummy cycle" count register, as there is a variable length
|
||||||
|
@ -389,6 +387,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc):
|
||||||
- pre-fetch is aborted because bus_adr and next read address don't match and FIFO is reset
|
- pre-fetch is aborted because bus_adr and next read address don't match and FIFO is reset
|
||||||
|
|
||||||
RxPHY:
|
RxPHY:
|
||||||
|
|
||||||
- while CTI==2, assemble data into 32-bit words as soon as EMPTY is deasserted,
|
- while CTI==2, assemble data into 32-bit words as soon as EMPTY is deasserted,
|
||||||
present a bus_ack, and increment the next read address pointer
|
present a bus_ack, and increment the next read address pointer
|
||||||
- when CTI==7, ack the data, and wait until the next bus cycle with CTI==2 to resume
|
- when CTI==7, ack the data, and wait until the next bus cycle with CTI==2 to resume
|
||||||
|
|
|
@ -1044,7 +1044,8 @@ class LiteXSoC(SoC):
|
||||||
dw = 32,
|
dw = 32,
|
||||||
interface = "wishbone",
|
interface = "wishbone",
|
||||||
endianness = self.cpu.endianness)
|
endianness = self.cpu.endianness)
|
||||||
ethmac_region = SoCRegion(size=0x2000, cached=False)
|
ethmac_region = SoCRegion(origin=self.mem_map.get("ethmac", None),
|
||||||
|
size=0x2000, cached=False)
|
||||||
self.bus.add_slave(name="ethmac", slave=self.ethmac.bus, region=ethmac_region)
|
self.bus.add_slave(name="ethmac", slave=self.ethmac.bus, region=ethmac_region)
|
||||||
self.add_csr("ethmac")
|
self.add_csr("ethmac")
|
||||||
self.add_interrupt("ethmac")
|
self.add_interrupt("ethmac")
|
||||||
|
|
Loading…
Reference in New Issue