luna-soc Documentation
eptri - SoC controller for the LUNA USB Device
General Description
eptri (endpoint-tri) is a three-interface CSR controller that allows a CPU or Wishbone design to control the endpoints of a LUNA USB Device.
Features
CONTROL peripheral for managing device connection, reset and connection speed.
SETUP interface peripheral for reading control transactions from the host.
OUT interface peripheral for reading data transfers from the host.
IN interface peripheral for writing data transactions to the host.
Introduction
Definitions
Controller refers to the
eptricontroller as a whole, including all peripherals.Peripheral refers to
USBDeviceController,SetupFIFOInterface,InFIFOInterfaceorOutFIFOInterface.
Block Diagram
┌────────────────────────────────────────┐ ┌──────────────────────────────────────┐
│USBDevice │ │EPTRI │
│ │ │ │
│ │ ├───────────────────────────┬──────────┤
│ │ │USBDeviceController │Registers │◀─────────▶
├─────────────┐ ┌───────────────────┤ │ ├──────────┤
│UTMIInterface│ │EndpointMultiplexer│ │ │IRQ │──────────▶
│ │ │ │ ├───────────────────────────┼──────────┤
┌──────────┐ │ │ │ │ │SetupFIFOInterface┌───────▶│Registers │◀─────────▶
│USB PHY │ │ │ │ │ ├──────────┐ │ ├──────────┤
◀─── D+ ──▶│ │ │ │ │ │ │8B FIFO │───────┘ │IRQ │──────────▶
│ │◀────▶│ │◀────▶│ │◀────▶├──────────┴────────────────┼──────────┤ SoC
◀─── D- ──▶│ │ │ │ │ │ │InFIFOInterface ┌────────│Registers │◀─────────▶
│ │ │ │ │ │ ├──────────┐ │ ├──────────┤
└──────────┘ │ │ │ │ │512B FIFO │◀──────┘ │IRQ │──────────▶
│ │ │ │ ├──────────┴────────────────┼──────────┤
│ │ │ │ │OutFIFOInterface ┌───────▶│Registers │◀─────────▶
│ │ │ │ ├──────────┐ │ ├──────────┤
│ │ │ │ │512B FIFO │───────┘ │IRQ │──────────▶
└─────────────┴──────┴───────────────────┘ └──────────┴────────────────┴──────────┘
Usage
The exact details for integrating a LUNA eptri peripheral into a design will depend on the SoC platform you are using.
For example, using luna-soc:
class Top(Elaboratable):
def __init__(self):
# instantiate the SoC
self.soc = LunaSoC(
cpu=VexRiscv(reset_addr=0x00000000, variant="cynthion"),
clock_frequency=int(60e6),
)
# instantiate the eptri device controller peripheral
self.usb0 = USBDeviceController()
# instantiate the three endpoint interface peripherals
self.usb0_ep_control = SetupFIFOInterface()
self.usb0_ep_in = InFIFOInterface()
self.usb0_ep_out = OutFIFOInterface()
# add the peripherals to the SoC
self.soc.add_peripheral(self.usb0)
self.soc.add_peripheral(self.usb0_ep_control, as_submodule=False)
self.soc.add_peripheral(self.usb0_ep_in, as_submodule=False)
self.soc.add_peripheral(self.usb0_ep_out, as_submodule=False)
def elaborate(self, platform):
m = Module()
m.submodules.soc = self.soc
# instantiate a LUNA USB device
usb0_bus = platform.request(platform.default_usb_connection)
usb0_device = USBDevice(bus=usb0_bus)
# add the eptri endpoint interface peripherals to the LUNA USB device
# as endpoint handlers
usb0_device.add_endpoint(self.usb0_ep_control)
usb0_device.add_endpoint(self.usb0_ep_in)
usb0_device.add_endpoint(self.usb0_ep_out)
# connect the eptri device controller to the LUNA USB device
m.d.comb += self.usb0.attach(usb0_device)
m.submodules.usb0_device = usb0_device
return m
Registers
The eptri controller provides four sets of registers corresponding to each peripheral.
USBx - USBDeviceController
CONTROL Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0000 |
[0:0] |
read-write |
|
0x0000 |
[8:8] |
read-write |
|
0x0000 |
[9:9] |
read-write |
|
Control register
connect: Set this bit to '1' to allow the associated USB device to connect to a host.
low_speed_only: Set this bit to '1' to force the device to operate at low speed.
full_speed_only: Set this bit to '1' to force the device to operate at full speed.
STATUS Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0002 |
[1:0] |
read-only |
|
Status register
speed: Indicates the current speed of the USB device. 0 indicates High; 1 => Full,
2 => Low, and 3 => SuperSpeed (incl SuperSpeed+).
EV_ENABLE Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0008 |
[0:0] |
read-write |
|
EV_PENDING Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0009 |
[0:0] |
read-write |
|
USBx_EP_CONTROL - SetupFIFOInterface
CONTROL Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0000 |
[7:0] |
write-only |
|
Control register
address: Controls the current device's USB address. Should be written after a SET_ADDRESS
request is received. Automatically resets back to zero on a USB reset.
STATUS Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0002 |
[7:0] |
read-only |
|
0x0002 |
[11:8] |
read-only |
|
0x0002 |
[12:12] |
read-only |
|
Status register
address: Holds the current device's active USB address.
epno: The endpoint number associated with the most recently captured SETUP packet.
have: `1` iff data is available in the FIFO.
RESET Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0004 |
[0:0] |
write-only |
|
Reset register
fifo: Local reset control for the SETUP handler; writing a '1' to this register clears
the handler state.
DATA Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0005 |
[7:0] |
read-only |
|
Data register
A FIFO that returns the bytes from the most recently captured SETUP packet.
Reading a byte from this register advances the FIFO. The first eight bytes read
from this contain the core SETUP packet.
EV_ENABLE Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0010 |
[0:0] |
read-write |
|
EV_PENDING Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0011 |
[0:0] |
read-write |
|
USBx_EP_IN - InFIFOInterface
ENDPOINT Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0000 |
[3:0] |
write-only |
|
Endpoint register
number: Contains the endpoint the enqueued packet is to be transmitted on. Writing to this field
marks the relevant packet as ready to transmit; and thus should only be written after a
full packet has been written into the FIFO. If no data has been placed into the DATA FIFO,
a zero-length packet is generated.
Note that any IN requests that do not match the endpoint number are automatically NAK'd.
STALL Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0001 |
[0:0] |
write-only |
|
Stall register
stalled: When this field contains '1', any IN tokens targeting `epno` will be responded to with a
STALL token, rather than DATA or a NAK.
For EP0, this field will automatically be cleared when a new SETUP token is received.
PID Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0002 |
[0:0] |
write-only |
|
Pid register
toggle: Sets the current PID toggle bit for the given endpoint.
STATUS Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0004 |
[15:0] |
read-only |
|
0x0004 |
[19:16] |
read-only |
|
0x0004 |
[24:24] |
read-only |
|
0x0004 |
[25:25] |
read-only |
|
0x0004 |
[26:26] |
read-only |
|
Status register
nak: Contains a bitmask of endpoints that have responded with a NAK since the
last read of this register.
epno: Contains the endpoint being transmitted on.
idle: This value is `1` if no packet is actively being transmitted.
have: This value is `1` if data is present in the transmit FIFO.
pid: Contains the current PID toggle bit for the given endpoint.
RESET Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0008 |
[0:0] |
write-only |
|
Reset register
fifo: A write to this field Clears the FIFO without transmitting.
DATA Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0009 |
[7:0] |
write-only |
|
Data register
Each write enqueues a byte to be transmitted; gradually building a single packet to
be transmitted. This queue should only ever contain a single packet; it is the software's
responsibility to handle breaking requests down into packets.
EV_ENABLE Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0010 |
[0:0] |
read-write |
|
EV_PENDING Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0011 |
[0:0] |
read-write |
|
USBx_EP_OUT - OutFIFOInterface
CONTROL Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0000 |
[7:0] |
read-write |
|
Control register
address: Controls the current device's USB address. Should be written after a SET_ADDRESS request
is received. Automatically resets back to zero on a USB reset.
ENDPOINT Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0001 |
[3:0] |
read-write |
|
Endpoint register
number: Selects the endpoint number to prime. This interface allows priming multiple endpoints
at once. That is, multiple endpoints can be ready to receive data at a time. See the `prime`
and `enable` bits for usage.
ENABLE Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0002 |
[0:0] |
write-only |
|
Enable register
enabled: Controls whether any data can be received on any primed OUT endpoint. This bit is
automatically cleared on receive in order to give the controller time to read data
from the FIFO. It must be re-enabled once the FIFO has been emptied.
PRIME Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0003 |
[0:0] |
write-only |
|
Prime register
primed: Controls "priming" an out endpoint. To receive data on any endpoint, the CPU must first
select the endpoint with the `epno` register; and then write a '1' into the prime and
enable register. This prepares our FIFO to receive data; and the next OUT transaction will
be captured into the FIFO.
When a transaction is complete, the `enable` bit is reset; the `prime` is not. This
effectively means that `enable` controls receiving on _any_ of the primed endpoints;
while `prime` can be used to build a collection of endpoints willing to participate in
receipt.
Note that this does not apply to the control endpoint. Once the control endpoint has
received a packet it will be un-primed and need to be re-primed before it can receive
again. This is to ensure that we can establish an order on the receipt of the setup
packet and any associated data.
Only one transaction / data packet is captured per `enable` write; repeated enabling is
necessary to capture multiple packets.
STALL Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0004 |
[0:0] |
write-only |
|
Stall register
stalled: Controls STALL'ing the active endpoint. Setting or clearing this bit will set or clear
STALL on the provided endpoint. Endpoint STALLs persist even after `epno` is changed; so
multiple endpoints can be stalled at once by writing their respective endpoint numbers
into `epno` register and then setting their `stall` bits.
PID Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0005 |
[0:0] |
write-only |
|
Pid register
toggle: Sets the current PID toggle bit for the given endpoint.
STATUS Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0006 |
[3:0] |
read-only |
|
0x0006 |
[8:8] |
read-only |
|
0x0006 |
[9:9] |
read-only |
|
Status register
epno: Contains the endpoint number associated with the data in the FIFO -- that is,
the endpoint number on which the relevant data was received.
have: `1` iff data is available in the FIFO.
pid: Contains the current PID toggle bit for the given endpoint.
RESET Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0008 |
[0:0] |
write-only |
|
Reset register
fifo: Local reset for the OUT handler; clears the out FIFO.
DATA Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0009 |
[7:0] |
read-only |
|
Data register
Read-only register. A FIFO that returns the bytes from the most recently captured OUT transaction.
Reading a byte from this register advances the FIFO.
byte: Contains the most recently received byte.
EV_ENABLE Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0020 |
[0:0] |
read-write |
|
EV_PENDING Register
Offset |
Range |
Access |
Field |
|---|---|---|---|
0x0021 |
[0:0] |
read-write |
|
Interrupts
Each of the eptri peripherals can generate the following interrupts:
Interrupt |
Peripheral |
Description |
|---|---|---|
USBx |
USBDeviceController |
Interrupt that triggers when the host issued a USB bus reset. |
USBx_EP_CONTROL |
SetupFIFOInterface |
Interrupt that triggers when the host wrote a new SETUP packet to the bus. |
USBx_EP_IN |
InFIFOInterface |
Interrupt that triggers after the peripheral has written a data packet to the bus and read back a PID ACK response from the host. |
USBx_EP_OUT |
OutFIFOInterface |
Interrupt that triggers when the peripheral has read a data packet from the host. |
Programming Guide
The programming guide provides sequence diagrams that detail the steps required to perform the various operations supported by the eptri controller.
The following pseudo-code is used through-out to indicate register operations:
Operation |
Description |
|---|---|
|
Read a value from the |
|
Write |
Device Connection
Bus Reset
Control OUT Transfers
Control IN Transfers
Bulk OUT Transfers
Bulk IN Transfers
luna_soc
luna_soc package
Subpackages
luna_soc.gateware package
Subpackages
luna_soc.gateware.core package
Subpackages
luna_soc.gateware.core.spiflash package
Submodules
luna_soc.gateware.core.spiflash.controller module
- class luna_soc.gateware.core.spiflash.controller.SPIController(*args, src_loc_at=0, **kwargs)
Bases:
ComponentWishbone generic SPI Flash Controller interface.
Provides a generic SPI Controller that can be interfaced using CSRs. Supports multiple access modes with the help of
widthandmaskregisters which can be used to configure the PHY into any supported SDR mode (single/dual/quad/octal).- class Cs(*args, src_loc_at=0, **kwargs)
Bases:
RegisterSPI chip select register
select : SPI chip select signal.
- select: <amaranth_soc.csr.reg.Field object at 0x7f50daa057f0>
- class Data(*args, src_loc_at=0, **kwargs)
Bases:
RegisterData register
rx : Read the next byte in the RX FIFO tx : Write the given byte to the TX FIFO
- class Phy(*args, src_loc_at=0, **kwargs)
Bases:
RegisterPHY control register
length : SPI transfer length in bits. width : SPI transfer bus width (1/2/4/8). mask : SPI DQ output enable mask.
- class Status(*args, src_loc_at=0, **kwargs)
Bases:
RegisterStatus register
rx_ready : RX FIFO contains data. tx_ready : TX FIFO ready to receive data.
- rx_ready: <amaranth_soc.csr.reg.Field object at 0x7f50da9ec6b0>
- tx_ready: <amaranth_soc.csr.reg.Field object at 0x7f50da9ec8d0>
- elaborate(platform)
luna_soc.gateware.core.spiflash.mmap module
- class luna_soc.gateware.core.spiflash.mmap.SPIFlashMemoryMap(*args, src_loc_at=0, **kwargs)
Bases:
ComponentWishbone Memory-mapped SPI Flash controller.
Supports sequential accesses so that command and address is only sent when necessary.
- MMAP_DEFAULT_TIMEOUT = 256
- OE_MASK = {1: 1, 2: 3, 4: 15, 8: 255}
- elaborate(platform)
- static reverse_bytes(word)
luna_soc.gateware.core.spiflash.phy module
- class luna_soc.gateware.core.spiflash.phy.ECP5ConfigurationFlashInterface(*args, src_loc_at=0, **kwargs)
Bases:
ElaboratableGateware that creates a connection to an MSPI configuration flash.
Automatically uses appropriate platform resources; this abstracts away details necessary to e.g. drive the MCLK lines on an ECP5, which has special handling.
- __init__(*, bus)
Params: bus – The SPI bus object to extend.
- elaborate(platform)
luna_soc.gateware.core.spiflash.port module
- class luna_soc.gateware.core.spiflash.port.SPIControlPort(data_width)
Bases:
Signature
- class luna_soc.gateware.core.spiflash.port.SPIControlPortCDC(*args, src_loc_at=0, **kwargs)
Bases:
ComponentConverts one SPIControlPort between clock domains.
- elaborate(platform)
- class luna_soc.gateware.core.spiflash.port.SPIControlPortCrossbar(*args, src_loc_at=0, **kwargs)
Bases:
ComponentMerge multiple SPIControlPorts with a round-robin scheduler.
- elaborate(platform)
- get_port(index)
- class luna_soc.gateware.core.spiflash.port.StreamCore2PHY(data_width)
Bases:
Signature- create(*, path=None, src_loc_at=0)
Create an interface object from this signature.
The default
Signature.create()implementation consists of one line:def create(self, *, path=None, src_loc_at=0): return PureInterface(self, path=path, src_loc_at=1 + src_loc_at)
This implementation creates an interface object from this signature that serves purely as a container for the attributes corresponding to the signature members, and implements no behavior. Such an implementation is sufficient for signatures created ad-hoc using the :py:`Signature({ ... })` constructor as well as simple signature subclasses.
When defining a
Signaturesubclass that needs to customize the behavior of the created interface objects, override this method with a similar implementation that references the class of your custom interface object:class CustomSignature(wiring.Signature): def create(self, *, path=None, src_loc_at=0): return CustomInterface(self, path=path, src_loc_at=1 + src_loc_at) class CustomInterface(wiring.PureInterface): @property def my_property(self): ...
The :py:`path` and :py:`src_loc_at` arguments are necessary to ensure the generated signals have informative names and accurate source location information.
The custom
create()method may take positional or keyword arguments in addition to the two listed above. Such arguments must have a default value, because theSignatureMembers.create()method will call theSignature.create()member without these additional arguments when this signature is a member of another signature.
- property data_width
- class luna_soc.gateware.core.spiflash.port.StreamCore2PHYInterface(signature, *, path=None, src_loc_at=0)
Bases:
PureInterface- property payload
Joint signal with all data.
- class luna_soc.gateware.core.spiflash.port.StreamPHY2Core(data_width)
Bases:
Signature- create(*, path=None, src_loc_at=0)
Create an interface object from this signature.
The default
Signature.create()implementation consists of one line:def create(self, *, path=None, src_loc_at=0): return PureInterface(self, path=path, src_loc_at=1 + src_loc_at)
This implementation creates an interface object from this signature that serves purely as a container for the attributes corresponding to the signature members, and implements no behavior. Such an implementation is sufficient for signatures created ad-hoc using the :py:`Signature({ ... })` constructor as well as simple signature subclasses.
When defining a
Signaturesubclass that needs to customize the behavior of the created interface objects, override this method with a similar implementation that references the class of your custom interface object:class CustomSignature(wiring.Signature): def create(self, *, path=None, src_loc_at=0): return CustomInterface(self, path=path, src_loc_at=1 + src_loc_at) class CustomInterface(wiring.PureInterface): @property def my_property(self): ...
The :py:`path` and :py:`src_loc_at` arguments are necessary to ensure the generated signals have informative names and accurate source location information.
The custom
create()method may take positional or keyword arguments in addition to the two listed above. Such arguments must have a default value, because theSignatureMembers.create()method will call theSignature.create()member without these additional arguments when this signature is a member of another signature.
- property data_width
luna_soc.gateware.core.spiflash.utils module
- class luna_soc.gateware.core.spiflash.utils.RoundRobin(*args, src_loc_at=0, **kwargs)
Bases:
ElaboratableRound-robin scheduler.
For a given set of requests, the round-robin scheduler will grant one request. Once it grants a request, if any other requests are active, it grants the next active request with a greater number, restarting from zero once it reaches the highest one.
Use
EnableInserterto control when the scheduler is updated.Parameters
- countint
Number of requests.
Attributes
- requestsSignal(count), in
Set of requests.
- grantSignal(range(count)), out
Number of the granted request. Does not change if there are no active requests.
- validSignal(), out
Asserted if grant corresponds to an active request. Deasserted otherwise, i.e. if no requests are active.
- elaborate(platform)
Module contents
- class luna_soc.gateware.core.spiflash.ECP5ConfigurationFlashInterface(*args, src_loc_at=0, **kwargs)
Bases:
ElaboratableGateware that creates a connection to an MSPI configuration flash.
Automatically uses appropriate platform resources; this abstracts away details necessary to e.g. drive the MCLK lines on an ECP5, which has special handling.
- __init__(*, bus)
Params: bus – The SPI bus object to extend.
- elaborate(platform)
- class luna_soc.gateware.core.spiflash.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
ComponentSPI Flash peripheral main module.
This class provides a wrapper that can instantiate both
SPIControllerandSPIFlashMemoryMapand connect them to the PHY.Both options share access to the PHY using a crossbar. Also, performs CDC if a different clock is used in the PHY.
- elaborate(platform)
- class luna_soc.gateware.core.spiflash.PinSignature
Bases:
Signature
luna_soc.gateware.core.usb2 package
Submodules
luna_soc.gateware.core.usb2.device module
Contains the organizing gateware used to add USB Device functionality
to your own designs; including the core USBDevice class.
- class luna_soc.gateware.core.usb2.device.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
ComponentSoC controller for a USBDevice.
Breaks our USBDevice control and status signals out into registers so a CPU / Wishbone master can control our USB device.
The attributes below are intended to connect to a USBDevice. Typically, they’d be created by using the .controller() method on a USBDevice object, which will automatically connect all relevant signals.
Attributes
- connect: Signal(), output
High when the USBDevice should be allowed to connect to a host.
- class Control(*args, src_loc_at=0, **kwargs)
Bases:
RegisterControl register
connect: Set this bit to ‘1’ to allow the associated USB device to connect to a host. low_speed_only: Set this bit to ‘1’ to force the device to operate at low speed. full_speed_only: Set this bit to ‘1’ to force the device to operate at full speed.
- connect: <amaranth_soc.csr.reg.Field object at 0x7f50da6f25b0>
- full_speed_only: <amaranth_soc.csr.reg.Field object at 0x7f50da82b280>
- low_speed_only: <amaranth_soc.csr.reg.Field object at 0x7f50da9674d0>
- class Status(*args, src_loc_at=0, **kwargs)
Bases:
RegisterStatus register
- speed: Indicates the current speed of the USB device. 0 indicates High; 1 => Full,
2 => Low, and 3 => SuperSpeed (incl SuperSpeed+).
- speed: <amaranth_soc.csr.reg.Field object at 0x7f50da804550>
- attach(device: USBDevice)
Returns a list of statements necessary to connect this to a USB controller.
The returned values makes all of the connections necessary to provide control and fetch status from the relevant USB device. These can be made either combinationally or synchronously, but combinational is recommended; as these signals are typically fed from a register anyway.
Parameters
- device: USBDevice
The
USBDeviceobject to be controlled.
- elaborate(platform)
luna_soc.gateware.core.usb2.ep_control module
Implementation of a Triple-FIFO endpoint manager.
Equivalent (but not binary-compatbile) implementation of ValentyUSB’s eptri.
For an example, see examples/usb/eptri or TinyUSB’s luna/dcd_eptri.c.
- class luna_soc.gateware.core.usb2.ep_control.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
ComponentSetup component of our eptri-equivalent interface.
Implements the USB Setup FIFO, which handles SETUP packets on any endpoint.
This interface is similar to an
OutFIFOInterface, but always ACKs packets, and does not allow for any flow control; as a USB device must always be ready to accept control packets. [USB2.0: 8.6.1]Attributes
- interface: EndpointInterface
Our primary interface to the core USB device hardware.
- class Control(*args, src_loc_at=0, **kwargs)
Bases:
RegisterControl register
- address: Controls the current device’s USB address. Should be written after a SET_ADDRESS
request is received. Automatically resets back to zero on a USB reset.
- address: <amaranth_soc.csr.reg.Field object at 0x7f50da872960>
- class Data(*args, src_loc_at=0, **kwargs)
Bases:
RegisterData register
A FIFO that returns the bytes from the most recently captured SETUP packet. Reading a byte from this register advances the FIFO. The first eight bytes read from this contain the core SETUP packet.
- byte: <amaranth_soc.csr.reg.Field object at 0x7f50da7387d0>
- class Reset(*args, src_loc_at=0, **kwargs)
Bases:
RegisterReset register
- fifo: Local reset control for the SETUP handler; writing a ‘1’ to this register clears
the handler state.
- fifo: <amaranth_soc.csr.reg.Field object at 0x7f50da7385f0>
- class Status(*args, src_loc_at=0, **kwargs)
Bases:
RegisterStatus register
address: Holds the current device’s active USB address. epno: The endpoint number associated with the most recently captured SETUP packet. have: 1 iff data is available in the FIFO.
- address: <amaranth_soc.csr.reg.Field object at 0x7f50da8dbd50>
- epno: <amaranth_soc.csr.reg.Field object at 0x7f50da8dbcd0>
- have: <amaranth_soc.csr.reg.Field object at 0x7f50da810130>
- elaborate(platform)
luna_soc.gateware.core.usb2.ep_in module
Implementation of a Triple-FIFO endpoint manager.
Equivalent (but not binary-compatbile) implementation of ValentyUSB’s eptri.
For an example, see examples/usb/eptri or TinyUSB’s luna/dcd_eptri.c.
- class luna_soc.gateware.core.usb2.ep_in.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
ComponentIN component of our eptri-equivalent interface.
Implements the FIFO that handles eptri IN requests. This FIFO collects USB data, and transmits it in response to an IN token. Like all eptri interfaces; it can handle only one pending packet at a time.
Attributes
- interface: EndpointInterface
Our primary interface to the core USB device hardware.
- class Data(*args, src_loc_at=0, **kwargs)
Bases:
RegisterData register
Each write enqueues a byte to be transmitted; gradually building a single packet to be transmitted. This queue should only ever contain a single packet; it is the software’s responsibility to handle breaking requests down into packets.
- byte: <amaranth_soc.csr.reg.Field object at 0x7f50da739850>
- class Endpoint(*args, src_loc_at=0, **kwargs)
Bases:
RegisterEndpoint register
- number: Contains the endpoint the enqueued packet is to be transmitted on. Writing to this field
marks the relevant packet as ready to transmit; and thus should only be written after a full packet has been written into the FIFO. If no data has been placed into the DATA FIFO, a zero-length packet is generated. Note that any IN requests that do not match the endpoint number are automatically NAK’d.
- number: <amaranth_soc.csr.reg.Field object at 0x7f50da738b30>
- class Pid(*args, src_loc_at=0, **kwargs)
Bases:
RegisterPid register
toggle: Sets the current PID toggle bit for the given endpoint.
- toggle: <amaranth_soc.csr.reg.Field object at 0x7f50da738e90>
- class Reset(*args, src_loc_at=0, **kwargs)
Bases:
RegisterReset register
fifo: A write to this field Clears the FIFO without transmitting.
- fifo: <amaranth_soc.csr.reg.Field object at 0x7f50da739610>
- class Stall(*args, src_loc_at=0, **kwargs)
Bases:
RegisterStall register
- stalled: When this field contains ‘1’, any IN tokens targeting epno will be responded to with a
STALL token, rather than DATA or a NAK. For EP0, this field will automatically be cleared when a new SETUP token is received.
- stalled: <amaranth_soc.csr.reg.Field object at 0x7f50da738cb0>
- class Status(*args, src_loc_at=0, **kwargs)
Bases:
RegisterStatus register
- nak: Contains a bitmask of endpoints that have responded with a NAK since the
last read of this register.
epno: Contains the endpoint being transmitted on. idle: This value is 1 if no packet is actively being transmitted. have: This value is 1 if data is present in the transmit FIFO. pid: Contains the current PID toggle bit for the given endpoint.
- epno: <amaranth_soc.csr.reg.Field object at 0x7f50da739130>
- have: <amaranth_soc.csr.reg.Field object at 0x7f50da739370>
- idle: <amaranth_soc.csr.reg.Field object at 0x7f50da7392b0>
- nak: <amaranth_soc.csr.reg.Field object at 0x7f50da739070>
- pid: <amaranth_soc.csr.reg.Field object at 0x7f50da739430>
- __init__(max_packet_size=512)
Parameters
- max_packet_size: int, optional
Sets the maximum packet size that can be transmitted on this endpoint. This should match the value provided in the relevant endpoint descriptor.
- elaborate(platform)
luna_soc.gateware.core.usb2.ep_out module
Implementation of a Triple-FIFO endpoint manager.
Equivalent (but not binary-compatbile) implementation of ValentyUSB’s eptri.
For an example, see examples/usb/eptri or TinyUSB’s luna/dcd_eptri.c.
- class luna_soc.gateware.core.usb2.ep_out.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
ComponentOUT component of our eptri
Implements the OUT FIFO, which handles receiving packets from our host.
Attributes
- interface: EndpointInterface
Our primary interface to the core USB device hardware.
- class Control(*args, src_loc_at=0, **kwargs)
Bases:
RegisterControl register
- address: Controls the current device’s USB address. Should be written after a SET_ADDRESS request
is received. Automatically resets back to zero on a USB reset.
- address: <amaranth_soc.csr.reg.Field object at 0x7f50da739bb0>
- class Data(*args, src_loc_at=0, **kwargs)
Bases:
RegisterData register
Read-only register. A FIFO that returns the bytes from the most recently captured OUT transaction. Reading a byte from this register advances the FIFO.
byte: Contains the most recently received byte.
- byte: <amaranth_soc.csr.reg.Field object at 0x7f50da73abd0>
- class Enable(*args, src_loc_at=0, **kwargs)
Bases:
RegisterEnable register
- enabled: Controls whether any data can be received on any primed OUT endpoint. This bit is
automatically cleared on receive in order to give the controller time to read data from the FIFO. It must be re-enabled once the FIFO has been emptied.
- enabled: <amaranth_soc.csr.reg.Field object at 0x7f50da739e50>
- class Endpoint(*args, src_loc_at=0, **kwargs)
Bases:
RegisterEndpoint register
number: Selects the endpoint number to prime. This interface allows priming multiple endpoints at once. That is, multiple endpoints can be ready to receive data at a time. See the prime and enable bits for usage.
- number: <amaranth_soc.csr.reg.Field object at 0x7f50da739c70>
- class Pid(*args, src_loc_at=0, **kwargs)
Bases:
RegisterPid register
toggle: Sets the current PID toggle bit for the given endpoint.
- toggle: <amaranth_soc.csr.reg.Field object at 0x7f50da73a3f0>
- class Prime(*args, src_loc_at=0, **kwargs)
Bases:
RegisterPrime register
- primed: Controls “priming” an out endpoint. To receive data on any endpoint, the CPU must first
select the endpoint with the epno register; and then write a ‘1’ into the prime and enable register. This prepares our FIFO to receive data; and the next OUT transaction will be captured into the FIFO.
When a transaction is complete, the enable bit is reset; the prime is not. This effectively means that enable controls receiving on _any_ of the primed endpoints; while prime can be used to build a collection of endpoints willing to participate in receipt.
Note that this does not apply to the control endpoint. Once the control endpoint has received a packet it will be un-primed and need to be re-primed before it can receive again. This is to ensure that we can establish an order on the receipt of the setup packet and any associated data.
Only one transaction / data packet is captured per enable write; repeated enabling is necessary to capture multiple packets.
- primed: <amaranth_soc.csr.reg.Field object at 0x7f50da73a030>
- class Reset(*args, src_loc_at=0, **kwargs)
Bases:
RegisterReset register
fifo: Local reset for the OUT handler; clears the out FIFO.
- fifo: <amaranth_soc.csr.reg.Field object at 0x7f50da73a9f0>
- class Stall(*args, src_loc_at=0, **kwargs)
Bases:
RegisterStall register
- stalled: Controls STALL’ing the active endpoint. Setting or clearing this bit will set or clear
STALL on the provided endpoint. Endpoint STALLs persist even after epno is changed; so multiple endpoints can be stalled at once by writing their respective endpoint numbers into epno register and then setting their stall bits.
- stalled: <amaranth_soc.csr.reg.Field object at 0x7f50da73a210>
- class Status(*args, src_loc_at=0, **kwargs)
Bases:
RegisterStatus register
- epno: Contains the endpoint number associated with the data in the FIFO – that is,
the endpoint number on which the relevant data was received.
have: 1 iff data is available in the FIFO. pid: Contains the current PID toggle bit for the given endpoint.
- epno: <amaranth_soc.csr.reg.Field object at 0x7f50da73a5d0>
- have: <amaranth_soc.csr.reg.Field object at 0x7f50da73a750>
- pid: <amaranth_soc.csr.reg.Field object at 0x7f50da73a810>
- __init__(max_packet_size=512)
Parameters
- max_packet_size: int, optional
Sets the maximum packet size that can be transmitted on this endpoint. This should match the value provided in the relevant endpoint descriptor.
- elaborate(platform)
luna_soc.gateware.core.usb2.ulpi module
ULPI interfacing hardware.
- class luna_soc.gateware.core.usb2.ulpi.Signature
Bases:
SignatureULPI bus signature.
Interface attributes
- i
Signal Input value of the ULPI data lines.
- o
Signal Output value of the ULPI data lines.
- oe
Signal True iff we’re trying to drive the ULPI data lines.
- clk
Signal The ULPI clock signal.
- nxt
Signal The ULPI ‘next’ throttle signal.
- stp
Signal The ULPI ‘stop’ event signal.
- dir
Signal The ULPI bus-direction signal.
- rst
Signal The ULPI ‘reset’ signal.
- i
Module contents
Submodules
luna_soc.gateware.core.blockram module
- class luna_soc.gateware.core.blockram.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
ComponentSRAM storage peripheral.
Parameters
- sizeint
Memory size in bytes.
- data_widthint
The width of each memory word.
- granularityint
The number of bits of data per each address.
- writablebool
Memory is writable.
- initlist[byte] Optional
The initial value of the relevant memory.
- namestr
A descriptive name for the given memory.
Attributes
- bus
amaranth_soc.wishbone.Interface Wishbone bus interface.
- property constant_map
- elaborate(platform)
- property init
luna_soc.gateware.core.ila module
- class luna_soc.gateware.core.ila.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
ComponentA simple peripheral interface to the ila.
- class Control(*args, src_loc_at=0, **kwargs)
Bases:
RegisterA CSR register.
Parameters
- fields
dictorlistorField Collection of register fields. If
None(default), a dict is populated from Python variable annotations.fieldsis used to create aFieldActionMap,FieldActionArray, orFieldAction, depending on its type (dict, list, or Field).
Interface attributes
- element
Element Interface between this register and a CSR bus primitive.
Attributes
- field
FieldActionMaporFieldActionArrayorFieldAction Collection of field instances.
- f
FieldActionMaporFieldActionArrayorFieldAction Shorthand for
Register.field.
Raises
TypeErrorIf
fieldsis neitherNone, adict, alist, or aField.ValueErrorIf
fieldsis notNoneand at least one variable annotation is aField.ValueErrorIf
element.accessis not readable and at least one field is readable.ValueErrorIf
element.accessis not writable and at least one field is writable.
- trigger: <amaranth_soc.csr.reg.Field object at 0x7f50db0aaba0>
- fields
- class Trace(*args, src_loc_at=0, **kwargs)
Bases:
RegisterA CSR register.
Parameters
- fields
dictorlistorField Collection of register fields. If
None(default), a dict is populated from Python variable annotations.fieldsis used to create aFieldActionMap,FieldActionArray, orFieldAction, depending on its type (dict, list, or Field).
Interface attributes
- element
Element Interface between this register and a CSR bus primitive.
Attributes
- field
FieldActionMaporFieldActionArrayorFieldAction Collection of field instances.
- f
FieldActionMaporFieldActionArrayorFieldAction Shorthand for
Register.field.
Raises
TypeErrorIf
fieldsis neitherNone, adict, alist, or aField.ValueErrorIf
fieldsis notNoneand at least one variable annotation is aField.ValueErrorIf
element.accessis not readable and at least one field is readable.ValueErrorIf
element.accessis not writable and at least one field is writable.
- a: <amaranth_soc.csr.reg.Field object at 0x7f50daee4cd0>
- b: <amaranth_soc.csr.reg.Field object at 0x7f50daee4e10>
- c: <amaranth_soc.csr.reg.Field object at 0x7f50daf96780>
- d: <amaranth_soc.csr.reg.Field object at 0x7f50daf96d70>
- fields
- elaborate(platform)
luna_soc.gateware.core.timer module
A simple timer peripheral.
- class luna_soc.gateware.core.timer.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
Component- class Counter(*args, src_loc_at=0, **kwargs)
Bases:
RegisterA CSR register.
Parameters
- fields
dictorlistorField Collection of register fields. If
None(default), a dict is populated from Python variable annotations.fieldsis used to create aFieldActionMap,FieldActionArray, orFieldAction, depending on its type (dict, list, or Field).
Interface attributes
- element
Element Interface between this register and a CSR bus primitive.
Attributes
- field
FieldActionMaporFieldActionArrayorFieldAction Collection of field instances.
- f
FieldActionMaporFieldActionArrayorFieldAction Shorthand for
Register.field.
Raises
TypeErrorIf
fieldsis neitherNone, adict, alist, or aField.ValueErrorIf
fieldsis notNoneand at least one variable annotation is aField.ValueErrorIf
element.accessis not readable and at least one field is readable.ValueErrorIf
element.accessis not writable and at least one field is writable.
- __init__(width)
Counter value
- fields
- class Enable(*args, src_loc_at=0, **kwargs)
Bases:
RegisterCounter enable
- enable: <amaranth_soc.csr.reg.Field object at 0x7f50dac25c50>
- class Mode(*args, src_loc_at=0, **kwargs)
Bases:
RegisterTimer mode. When
periodicis set to 1 the counter will automatically be reset to the reload value.- periodic: <amaranth_soc.csr.reg.Field object at 0x7f50dac24050>
- class Reload(*args, src_loc_at=0, **kwargs)
Bases:
RegisterReload value of counter.
- elaborate(platform)
luna_soc.gateware.core.uart module
- class luna_soc.gateware.core.uart.Peripheral(*args, src_loc_at=0, **kwargs)
Bases:
Component- class BaudRate(*args, src_loc_at=0, **kwargs)
Bases:
Registerbaud rate divider, defaults to init
- class RxAvail(*args, src_loc_at=0, **kwargs)
Bases:
Registeris ‘1’ when 1-byte receive buffer is full; reset by a read from rx_data
- rxe: <amaranth_soc.csr.reg.Field object at 0x7f50dab55c50>
- class RxData(*args, src_loc_at=0, **kwargs)
Bases:
Registervalid to read from when rx_avail is high, last received byte
- data: <amaranth_soc.csr.reg.Field object at 0x7f50da9909b0>
- class TxData(*args, src_loc_at=0, **kwargs)
Bases:
Registervalid to write to when tx_rdy is high, will trigger a transmit
- data: <amaranth_soc.csr.reg.Field object at 0x7f50dac85a90>
- class TxReady(*args, src_loc_at=0, **kwargs)
Bases:
Registeris ‘1’ when 1-byte transmit buffer is empty
- txe: <amaranth_soc.csr.reg.Field object at 0x7f50daea1a90>
- elaborate(platform)
Module contents
luna_soc.gateware.cpu package
Submodules
Module contents
Module contents
luna_soc.generate package
Submodules
luna_soc.generate.c module
Generate a C library for SoC designs.
- class luna_soc.generate.c.Header(memory_map: ~amaranth_soc.memory.MemoryMap, interrupts: dict[int, (<class 'str'>, <class 'amaranth.lib.wiring.Component'>)])
Bases:
object- generate(file=None, macro_name='SOC_RESOURCES', platform_name='Generic Platform')
Generate a C header file that simplifies access to the platform’s resources.
- Parameters:
macro_name – Optional. The name of the guard macro for the C header, as a string without spaces.
file – Optional. If provided, this will be treated as the file= argument to the print() – function. This can be used to generate file content instead of printing to the terminal.
- class luna_soc.generate.c.LinkerScript(memory_map: MemoryMap, reset_addr: int = 0)
Bases:
object- generate(file=None, macro_name='SOC_RESOURCES', platform_name='Generic Platform')
Generates a ldscript that holds our primary RAM and ROM regions.
- Parameters:
file – Optional. If provided, this will be treated as the file= argument to the print() – function. This can be used to generate file content instead of printing to the terminal.
luna_soc.generate.introspect module
Introspection tools for SoC designs.
- luna_soc.generate.introspect.csr_base(memory_map: MemoryMap) int
Scan a memory map for the starting address for csr peripheral registers.
- luna_soc.generate.introspect.csr_peripherals(memory_map: MemoryMap) dict[Name, list[ResourceInfo]]
Scan a memory map for csr peripheral registers.
- luna_soc.generate.introspect.interrupts(fragment: Component) dict[int, (<class 'str'>, <class 'amaranth.lib.wiring.Component'>)]
- luna_soc.generate.introspect.memory_map(fragment: Component) MemoryMap
- luna_soc.generate.introspect.reset_addr(fragment: Component) MemoryMap
- luna_soc.generate.introspect.soc(fragment: Component) Component
- luna_soc.generate.introspect.wb_peripherals(memory_map: MemoryMap) dict[~amaranth_soc.memory.MemoryMap.Name, list[tuple[~amaranth.lib.wiring.Component, ~amaranth_soc.memory.MemoryMap.Name, (<class 'int'>, <class 'int'>)]]]
Scan a memory map for wishbone peripherals.
luna_soc.generate.rust module
Generate Rust support files for SoC designs.
luna_soc.generate.svd module
Generate a SVD file for SoC designs.
Module contents
luna_soc.util package
Submodules
Module contents
Submodules
luna_soc.top_level_cli module
- luna_soc.top_level_cli.build(args, fragment, platform, build_dir)
Top-level build command. Invokes the build steps for each artifact to be generated.
- luna_soc.top_level_cli.top_level_cli(fragment, *pos_args, **kwargs)
Runs a default CLI that assists in building and running SoC gateware.
If the user’s options resulted in the board being programmed, this returns the fragment that was programmed onto the board. Otherwise, it returns None.
- Parameters:
fragment – The design to be built; or a callable that returns a fragment, – such as a Elaborable type. If the latter is provided, any keyword or positional arguments not specified here will be passed to this callable.