From 1462160ba66302aaae69dca9e54fd71498a8b3ef Mon Sep 17 00:00:00 2001 From: Mike Walters Date: Mon, 16 Sep 2024 22:45:16 +0100 Subject: [PATCH 1/6] Bump Amaranth to v0.5.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 30b37175..ded872de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ "pyserial>=3.5", "pyusb>1.1.1", "pyvcd>=0.2.4", - "amaranth~=0.4.0", + "amaranth~=0.5.0", "usb-protocol~=0.9.1", ] From 6c28d98bef0e1d671978e705de63c3478866431b Mon Sep 17 00:00:00 2001 From: Mike Walters Date: Mon, 16 Sep 2024 23:15:37 +0100 Subject: [PATCH 2/6] Replace uses of amaranth.hdl.Memory with amaranth.lib.memory.Memory --- luna/gateware/debug/ila.py | 23 ++++++++++--------- luna/gateware/memory.py | 9 ++++---- luna/gateware/stream/generator.py | 9 ++++---- .../usb/request/windows/ms_descriptor.py | 7 +++--- luna/gateware/usb/usb2/descriptor.py | 7 +++--- luna/gateware/usb/usb2/transfer.py | 17 +++++++------- luna/gateware/usb/usb3/endpoints/stream.py | 8 +++---- 7 files changed, 42 insertions(+), 38 deletions(-) diff --git a/luna/gateware/debug/ila.py b/luna/gateware/debug/ila.py index bf76632c..9b6d80a6 100644 --- a/luna/gateware/debug/ila.py +++ b/luna/gateware/debug/ila.py @@ -13,17 +13,18 @@ import tempfile import subprocess -from abc import ABCMeta, abstractmethod +from abc import ABCMeta, abstractmethod -from amaranth import Signal, Module, Cat, Elaboratable, Memory, ClockDomain, DomainRenamer -from amaranth.lib.cdc import FFSynchronizer -from amaranth.lib.fifo import AsyncFIFOBuffered -from vcd import VCDWriter -from vcd.gtkw import GTKWSave +from amaranth import Cat, DomainRenamer, Elaboratable, Module, Signal +from amaranth.lib.cdc import FFSynchronizer +from amaranth.lib.fifo import AsyncFIFOBuffered +from amaranth.lib.memory import Memory +from vcd import VCDWriter +from vcd.gtkw import GTKWSave -from ..stream import StreamInterface -from ..interface.uart import UARTMultibyteTransmitter -from ..interface.spi import SPIDeviceInterface, SPIBus +from ..stream import StreamInterface +from ..interface.uart import UARTMultibyteTransmitter +from ..interface.spi import SPIDeviceInterface, SPIBus class IntegratedLogicAnalyzer(Elaboratable): @@ -77,7 +78,7 @@ def __init__(self, *, signals, sample_depth, domain="sync", sample_rate=60e6, sa # # Create a backing store for our samples. # - self.mem = Memory(width=self.sample_width, depth=sample_depth, name="ila_buffer") + self.mem = Memory(shape=self.sample_width, depth=sample_depth, init=[]) # @@ -97,7 +98,7 @@ def elaborate(self, platform): # Memory ports. write_port = self.mem.write_port() read_port = self.mem.read_port(domain="sync") - m.submodules += [write_port, read_port] + m.submodules['ila_buffer'] = self.mem # If necessary, create synchronized versions of the relevant signals. if self.samples_pretrigger >= 2: diff --git a/luna/gateware/memory.py b/luna/gateware/memory.py index 54befb2c..34c58958 100644 --- a/luna/gateware/memory.py +++ b/luna/gateware/memory.py @@ -8,7 +8,8 @@ This module contains definitions of memory units that work well for USB applications. """ -from amaranth import Elaboratable, Module, Signal, Memory +from amaranth import Elaboratable, Module, Signal +from amaranth.lib.memory import Memory from amaranth.hdl.xfrm import DomainRenamer @@ -108,9 +109,9 @@ def elaborate(self, platform): # # Core internal "backing store". # - memory = Memory(width=self.width, depth=self.depth + 1, name=self.name) - m.submodules.read_port = read_port = memory.read_port() - m.submodules.write_port = write_port = memory.write_port() + m.submodules[self.name] = memory = Memory(shape=self.width, depth=self.depth + 1, init=[]) + read_port = memory.read_port() + write_port = memory.write_port() # Always connect up our memory's data/en ports to ours. m.d.comb += [ diff --git a/luna/gateware/stream/generator.py b/luna/gateware/stream/generator.py index 2da54f9c..4eef92e6 100644 --- a/luna/gateware/stream/generator.py +++ b/luna/gateware/stream/generator.py @@ -6,8 +6,9 @@ """ Stream generators. """ -from amaranth import * -from . import StreamInterface +from amaranth import Array, Const, DomainRenamer, Elaboratable, Module, Signal +from amaranth.lib.memory import Memory +from . import StreamInterface class ConstantStreamGenerator(Elaboratable): @@ -153,8 +154,8 @@ def elaborate(self, platform): data_initializer, valid_bits_last_word = self._get_initializer_value() data_length = len(data_initializer) - rom = Memory(width=self._data_width, depth=data_length, init=data_initializer) - m.submodules.rom_read_port = rom_read_port = rom.read_port(transparent=False) + m.submodules.rom = rom = Memory(shape=self._data_width, depth=data_length, init=data_initializer) + rom_read_port = rom.read_port() if self._max_length_width: # Register maximum length, to improve timing. diff --git a/luna/gateware/usb/request/windows/ms_descriptor.py b/luna/gateware/usb/request/windows/ms_descriptor.py index 34dbdccc..cf53facc 100644 --- a/luna/gateware/usb/request/windows/ms_descriptor.py +++ b/luna/gateware/usb/request/windows/ms_descriptor.py @@ -6,7 +6,8 @@ import struct -from amaranth import DomainRenamer, Elaboratable, Memory, Module, Signal +from amaranth import DomainRenamer, Elaboratable, Module, Signal +from amaranth.lib.memory import Memory from usb_protocol.emitters.descriptors.microsoft10 import MicrosoftOS10DescriptorCollection from ...stream import USBInStreamInterface @@ -182,8 +183,8 @@ def elaborate(self, platform): # rom_content, descriptor_max_length, max_index, min_index = self.generate_rom_content() - rom = Memory(width=32, depth=len(rom_content), init=rom_content) - m.submodules.rom_read_port = rom_read_port = rom.read_port(transparent=False) + m.submodules.rom = rom = Memory(shape=32, depth=len(rom_content), init=rom_content) + rom_read_port = rom.read_port() # Create convenience aliases to the upper and lower half of the ROM. rom_upper_half = rom_read_port.data.word_select(1, 16) diff --git a/luna/gateware/usb/usb2/descriptor.py b/luna/gateware/usb/usb2/descriptor.py index d6b0664d..89764e7d 100644 --- a/luna/gateware/usb/usb2/descriptor.py +++ b/luna/gateware/usb/usb2/descriptor.py @@ -8,7 +8,8 @@ import struct import functools -from amaranth import * +from amaranth import Cat, DomainRenamer, Elaboratable, Module, Signal +from amaranth.lib.memory import Memory from usb_protocol.emitters.descriptors import DeviceDescriptorCollection from usb_protocol.types.descriptors.standard import StandardDescriptorNumbers @@ -368,8 +369,8 @@ def elaborate(self, platform) -> Module: # rom_content, descriptor_max_length, max_type_index = self.generate_rom_content() - rom = Memory(width=32, depth=len(rom_content), init=rom_content) - m.submodules.rom_read_port = rom_read_port = rom.read_port(transparent=False) + m.submodules.rom = rom = Memory(shape=32, depth=len(rom_content), init=rom_content) + rom_read_port = rom.read_port() # Create convenience aliases to the upper and lower half of the ROM. rom_upper_half = rom_read_port.data.word_select(1, 16) diff --git a/luna/gateware/usb/usb2/transfer.py b/luna/gateware/usb/usb2/transfer.py index 41d6c726..8f33f937 100644 --- a/luna/gateware/usb/usb2/transfer.py +++ b/luna/gateware/usb/usb2/transfer.py @@ -9,12 +9,12 @@ Its components facilitate data transfer longer than a single packet. """ -from amaranth import Signal, Elaboratable, Module, Array -from amaranth.hdl.mem import Memory +from amaranth import Signal, Elaboratable, Module, Array +from amaranth.lib.memory import Memory -from .packet import HandshakeExchangeInterface, TokenDetectorInterface -from ..stream import USBInStreamInterface -from ...stream import StreamInterface +from .packet import HandshakeExchangeInterface, TokenDetectorInterface +from ..stream import USBInStreamInterface +from ...stream import StreamInterface class USBInTransferManager(Elaboratable): """ Sequencer that converts a long data stream (a USB *transfer*) into a burst of USB packets. @@ -135,13 +135,12 @@ def elaborate(self, platform): # # We'll create two buffers; so we can fill one as we empty the other. - buffer = Array(Memory(width=8, depth=self._max_packet_size, name=f"transmit_buffer_{i}") for i in range(2)) + m.submodules.transmit_buffer_0 = transmit_buffer_0 = Memory(shape=8, depth=self._max_packet_size, init=[]) + m.submodules.transmit_buffer_1 = transmit_buffer_1 = Memory(shape=8, depth=self._max_packet_size, init=[]) + buffer = Array([transmit_buffer_0, transmit_buffer_1]) buffer_write_ports = Array(buffer[i].write_port(domain="usb") for i in range(2)) buffer_read_ports = Array(buffer[i].read_port(domain="usb") for i in range(2)) - m.submodules.read_port_0, m.submodules.read_port_1 = buffer_read_ports - m.submodules.write_port_0, m.submodules.write_port_1 = buffer_write_ports - # Create values equivalent to the buffer numbers for our read and write buffer; which switch # whenever we swap our two buffers. write_buffer_number = self.buffer_toggle diff --git a/luna/gateware/usb/usb3/endpoints/stream.py b/luna/gateware/usb/usb3/endpoints/stream.py index 04f874dc..a08176cd 100644 --- a/luna/gateware/usb/usb3/endpoints/stream.py +++ b/luna/gateware/usb/usb3/endpoints/stream.py @@ -11,6 +11,7 @@ """ from amaranth import * +from amaranth.lib.memory import Memory from usb_protocol.types import USBDirection from ...stream import SuperSpeedStreamInterface @@ -111,12 +112,11 @@ def elaborate(self, platform): # We'll create two buffers; so we can fill one as we empty the other. # Since each buffer will be used for every other transaction, we'll use a simple flag to identify # which of our "ping-pong" buffers is currently being targeted. - buffer = Array(Memory(width=data_width, depth=buffer_depth, name=f"transmit_buffer_{i}") for i in range(2)) + buffer = Array(Memory(shape=data_width, depth=buffer_depth, init=[]) for _ in range(2)) buffer_write_ports = Array(buffer[i].write_port(domain="ss") for i in range(2)) - buffer_read_ports = Array(buffer[i].read_port(domain="ss", transparent=False) for i in range(2)) + buffer_read_ports = Array(buffer[i].read_port(domain="ss") for i in range(2)) - m.submodules.read_port_0, m.submodules.read_port_1 = buffer_read_ports - m.submodules.write_port_0, m.submodules.write_port_1 = buffer_write_ports + m.submodules.transmit_buffer_0, m.submodules.transmit_buffer_1 = buffer # Create values equivalent to the buffer numbers for our read and write buffer; which switch # whenever we swap our two buffers. From bd3d87014235c14eb4c125ea045613807d6f63c2 Mon Sep 17 00:00:00 2001 From: Mike Walters Date: Mon, 16 Sep 2024 23:17:54 +0100 Subject: [PATCH 3/6] Remove uses of Signal.width --- luna/gateware/usb/usb2/descriptor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/luna/gateware/usb/usb2/descriptor.py b/luna/gateware/usb/usb2/descriptor.py index 89764e7d..cfd5238d 100644 --- a/luna/gateware/usb/usb2/descriptor.py +++ b/luna/gateware/usb/usb2/descriptor.py @@ -383,7 +383,7 @@ def elaborate(self, platform) -> Module: # ... and to the ROM's lower half, not counting the last two bits (which are always 0, # as our pointers are always aligned). This creates an element pointer counted in words, # instead of in bytes; and thus one compatible with our read_port addr. - rom_element_pointer = rom_read_port.data.bit_select(2, rom_read_port.addr.width) + rom_element_pointer = rom_read_port.data.bit_select(2, len(rom_read_port.addr)) # # Figure out the maximum length we're willing to send. @@ -408,7 +408,7 @@ def elaborate(self, platform) -> Module: # Registers that store descriptor length and data base address. descriptor_length = Signal(16) - descriptor_data_base_address = Signal(rom_read_port.addr.width) + descriptor_data_base_address = Signal.like(rom_read_port.addr) # Track when we're on the first and last packet. on_first_packet = position_in_stream == self.start_position @@ -529,7 +529,7 @@ def elaborate(self, platform) -> Module: position_in_stream .eq(position_in_stream + 1), bytes_sent .eq(bytes_sent + 1), ] - m.d.comb += rom_read_port.addr.eq(descriptor_data_base_address+(position_in_stream + 1).bit_select(2, position_in_stream.width - 2)), + m.d.comb += rom_read_port.addr.eq(descriptor_data_base_address+(position_in_stream + 1).bit_select(2, len(position_in_stream) - 2)), # Otherwise, we've finished! Return to IDLE. with m.Else(): From 1528a97d8ac128b52fb65db1d69d70561a19638c Mon Sep 17 00:00:00 2001 From: Mike Walters Date: Mon, 16 Sep 2024 23:21:26 +0100 Subject: [PATCH 4/6] Replace uses of `reset=` with `init=` --- applets/clear_endpoint_halt_test.py | 4 ++-- applets/hyperram_diagnostic.py | 2 +- examples/usb/stress_test_device.py | 2 +- luna/gateware/architecture/car.py | 2 +- luna/gateware/debug/ila.py | 2 +- luna/gateware/interface/flash.py | 4 ++-- luna/gateware/interface/gateware_phy/receiver.py | 8 ++++---- .../gateware/interface/gateware_phy/transmitter.py | 2 +- luna/gateware/interface/i2c.py | 14 +++++++------- luna/gateware/interface/jtag.py | 4 ++-- luna/gateware/interface/serdes_phy/ecp5.py | 8 ++++---- luna/gateware/interface/serdes_phy/xc7.py | 6 +++--- luna/gateware/interface/serdes_phy/xc7_gtp.py | 2 +- luna/gateware/interface/serdes_phy/xc7_gtx.py | 2 +- luna/gateware/interface/spi.py | 6 +++--- luna/gateware/interface/uart.py | 4 ++-- luna/gateware/interface/ulpi.py | 10 +++++----- luna/gateware/usb/usb2/device.py | 4 ++-- luna/gateware/usb/usb2/endpoints/isochronous.py | 2 +- luna/gateware/usb/usb2/packet.py | 4 ++-- luna/gateware/usb/usb2/request.py | 2 +- luna/gateware/usb/usb2/reset.py | 6 +++--- luna/gateware/usb/usb2/transfer.py | 2 +- luna/gateware/usb/usb3/device.py | 4 ++-- luna/gateware/usb/usb3/link/crc.py | 6 +++--- luna/gateware/usb/usb3/link/receiver.py | 8 ++++---- luna/gateware/usb/usb3/link/transmitter.py | 2 +- luna/gateware/usb/usb3/physical/power.py | 2 +- luna/gateware/usb/usb3/physical/scrambling.py | 2 +- luna/gateware/usb/usb3/protocol/endpoint.py | 2 +- tests/test_i2c.py | 4 ++-- 31 files changed, 66 insertions(+), 66 deletions(-) diff --git a/applets/clear_endpoint_halt_test.py b/applets/clear_endpoint_halt_test.py index 0e7637c9..0d22c6a9 100755 --- a/applets/clear_endpoint_halt_test.py +++ b/applets/clear_endpoint_halt_test.py @@ -31,7 +31,7 @@ COUNTER_MAX = 251 GET_OUT_COUNTER_VALID = 0 -out_counter_valid = Signal(reset=1) +out_counter_valid = Signal(init=1) class VendorRequestHandler(ControlRequestHandler): @@ -137,7 +137,7 @@ def elaborate(self, platform): m.d.usb += in_counter.eq(0) # Expect a counter on the OUT endpoint, and verify that it is contiguous. - prev_out_counter = Signal(8, reset=COUNTER_MAX) + prev_out_counter = Signal(8, init=COUNTER_MAX) with m.If(stream_out_ep.stream.valid): out_counter = stream_out_ep.stream.payload counter_increase = out_counter == (prev_out_counter + 1) diff --git a/applets/hyperram_diagnostic.py b/applets/hyperram_diagnostic.py index 25d4c18a..432ac952 100755 --- a/applets/hyperram_diagnostic.py +++ b/applets/hyperram_diagnostic.py @@ -69,7 +69,7 @@ def elaborate(self, platform): m.submodules.registers = registers psram_address = registers.add_register(REGISTER_RAM_ADDR) - read_length = registers.add_register(REGISTER_RAM_READ_LENGTH, reset=1) + read_length = registers.add_register(REGISTER_RAM_READ_LENGTH, init=1) m.submodules.read_fifo = read_fifo = SyncFIFO(width=REG_WIDTH, depth=32) m.submodules.write_fifo = write_fifo = SyncFIFO(width=REG_WIDTH, depth=32) diff --git a/examples/usb/stress_test_device.py b/examples/usb/stress_test_device.py index eba92a2d..5719f6d1 100755 --- a/examples/usb/stress_test_device.py +++ b/examples/usb/stress_test_device.py @@ -60,7 +60,7 @@ def elaborate(self, platform): tx = interface.tx # Counter that stores how many bytes we have left to send. - bytes_to_send = Signal(range(0, self._max_packet_size + 1), reset=0) + bytes_to_send = Signal(range(0, self._max_packet_size + 1), init=0) # True iff we're the active endpoint. endpoint_selected = \ diff --git a/luna/gateware/architecture/car.py b/luna/gateware/architecture/car.py index a70f1e45..c76ad571 100644 --- a/luna/gateware/architecture/car.py +++ b/luna/gateware/architecture/car.py @@ -56,7 +56,7 @@ def elaborate(self, platform): cycles_in_reset = Signal(range(0, self.reset_length_cycles)) reset_state = 'RESETTING' if self.power_on_reset else 'IDLE' - with m.FSM(reset=reset_state, domain='sync') as fsm: + with m.FSM(init=reset_state, domain='sync') as fsm: # Drive the PHY reset whenever we're in the RESETTING cycle. m.d.comb += [ diff --git a/luna/gateware/debug/ila.py b/luna/gateware/debug/ila.py index 9b6d80a6..68936f25 100644 --- a/luna/gateware/debug/ila.py +++ b/luna/gateware/debug/ila.py @@ -455,7 +455,7 @@ def elaborate(self, platform): # SENDING -- we now have a valid buffer of samples to send up to the host; # we'll transmit them over our stream interface. with m.State("SENDING"): - data_valid = Signal(reset=1) + data_valid = Signal(init=1) m.d.comb += [ # While we're sending, we're always providing valid data to the UART. in_domain_stream.valid .eq(data_valid), diff --git a/luna/gateware/interface/flash.py b/luna/gateware/interface/flash.py index b4af21a9..9a436d0a 100644 --- a/luna/gateware/interface/flash.py +++ b/luna/gateware/interface/flash.py @@ -103,8 +103,8 @@ def elaborate(self, platform): ] # Output shift register and bit counter - shreg_o = Signal(8, reset=self.READ_UID) - count_o = Signal(range(128), reset=8*(1+4+8)-1) # bytes: 1 opcode, 4 padding, 8 id + shreg_o = Signal(8, init=self.READ_UID) + count_o = Signal(range(128), init=8*(1+4+8)-1) # bytes: 1 opcode, 4 padding, 8 id with m.FSM(domain=self._domain): diff --git a/luna/gateware/interface/gateware_phy/receiver.py b/luna/gateware/interface/gateware_phy/receiver.py index 298fde3c..9dd72e2c 100644 --- a/luna/gateware/interface/gateware_phy/receiver.py +++ b/luna/gateware/interface/gateware_phy/receiver.py @@ -439,7 +439,7 @@ def __init__(self): # pass all of the outputs through a pipe stage self.o_data = Signal() self.o_error = Signal() - self.o_stall = Signal(reset=1) + self.o_stall = Signal(init=1) def elaborate(self, platform): @@ -536,7 +536,7 @@ def elaborate(self, platform): # Instead of using a counter, we will use a sentinel bit in the shift # register to indicate when it is full. - shift_reg = Signal(width+1, reset=0b1) + shift_reg = Signal(width+1, init=0b1) m.d.comb += self.o_data.eq(shift_reg[0:width]) m.d.usb_io += self.o_put.eq(shift_reg[width-1] & ~shift_reg[width] & self.i_valid), @@ -562,8 +562,8 @@ def __init__(self): self.o_bit_strobe = Signal() # Reset state is J - self.i_usbp = Signal(reset=1) - self.i_usbn = Signal(reset=0) + self.i_usbp = Signal(init=1) + self.i_usbn = Signal(init=0) self.o_data_strobe = Signal() self.o_data_payload = Signal(8) diff --git a/luna/gateware/interface/gateware_phy/transmitter.py b/luna/gateware/interface/gateware_phy/transmitter.py index acb5c67b..63f4bf0e 100644 --- a/luna/gateware/interface/gateware_phy/transmitter.py +++ b/luna/gateware/interface/gateware_phy/transmitter.py @@ -94,7 +94,7 @@ def elaborate(self, platform): m = Module() shifter = Signal(self._width) - pos = Signal(self._width, reset=0b1) + pos = Signal(self._width, init=0b1) with m.If(self.i_enable): diff --git a/luna/gateware/interface/i2c.py b/luna/gateware/interface/i2c.py index 0fedfb74..76f2d175 100644 --- a/luna/gateware/interface/i2c.py +++ b/luna/gateware/interface/i2c.py @@ -231,9 +231,9 @@ def __init__(self, pads): self.sda_t = pads.sda_t if hasattr(pads, "sda_t") else pads.sda self.scl_i = Signal() - self.scl_o = Signal(reset=1) + self.scl_o = Signal(init=1) self.sda_i = Signal() - self.sda_o = Signal(reset=1) + self.sda_o = Signal(init=1) self.sample = Signal(name="bus_sample") self.setup = Signal(name="bus_setup") @@ -248,7 +248,7 @@ def elaborate(self, platform): self.sda_t.o .eq(0), self.sda_t.oe .eq(~self.sda_o), ] - m.submodules += FFSynchronizer(self.sda_t.i, self.sda_i, reset=1) + m.submodules += FFSynchronizer(self.sda_t.i, self.sda_i, init=1) # But the SCL line does not need to: only if we want to support clock stretching if hasattr(self.scl_t, "oe"): @@ -256,7 +256,7 @@ def elaborate(self, platform): self.scl_t.o .eq(0), self.scl_t.oe .eq(~self.scl_o), ] - m.submodules += FFSynchronizer(self.scl_t.i, self.scl_i, reset=1) + m.submodules += FFSynchronizer(self.scl_t.i, self.scl_i, init=1) else: # SCL output only m.d.comb += [ @@ -265,8 +265,8 @@ def elaborate(self, platform): ] # Additional signals for bus state detection - scl_r = Signal(reset=1) - sda_r = Signal(reset=1) + scl_r = Signal(init=1) + sda_r = Signal(init=1) m.d.sync += [ scl_r.eq(self.scl_i), sda_r.eq(self.sda_i), @@ -327,7 +327,7 @@ def __init__(self, pads, period_cyc, clk_stretch=True): self.period_cyc = int(period_cyc) self.clk_stretch = clk_stretch - self.busy = Signal(reset=1) + self.busy = Signal(init=1) self.start = Signal() self.stop = Signal() self.read = Signal() diff --git a/luna/gateware/interface/jtag.py b/luna/gateware/interface/jtag.py index 37cc59a0..ebf7993e 100644 --- a/luna/gateware/interface/jtag.py +++ b/luna/gateware/interface/jtag.py @@ -200,8 +200,8 @@ def elaborate(self, platform): # ir_size = self.command_size + 1 dr_size = self.word_size + 1 - instruction_register = Signal(ir_size, reset=(2 ** ir_size - 1)) - data_register = Signal(dr_size, reset=(2 ** dr_size - 1)) + instruction_register = Signal(ir_size, init=(2 ** ir_size - 1)) + data_register = Signal(dr_size, init=(2 ** dr_size - 1)) # # JTAG interface. diff --git a/luna/gateware/interface/serdes_phy/ecp5.py b/luna/gateware/interface/serdes_phy/ecp5.py index c086a423..520049d1 100644 --- a/luna/gateware/interface/serdes_phy/ecp5.py +++ b/luna/gateware/interface/serdes_phy/ecp5.py @@ -445,10 +445,10 @@ def __init__(self): self.rx_coding_err = Signal() # Reset out. - self.tx_pll_reset = Signal(reset=1) - self.tx_pcs_reset = Signal(reset=1) - self.rx_cdr_reset = Signal(reset=1) - self.rx_pcs_reset = Signal(reset=1) + self.tx_pll_reset = Signal(init=1) + self.tx_pcs_reset = Signal(init=1) + self.rx_cdr_reset = Signal(init=1) + self.rx_pcs_reset = Signal(init=1) # Status out. self.tx_pcs_ready = Signal() diff --git a/luna/gateware/interface/serdes_phy/xc7.py b/luna/gateware/interface/serdes_phy/xc7.py index ce4980f9..b5a9f270 100644 --- a/luna/gateware/interface/serdes_phy/xc7.py +++ b/luna/gateware/interface/serdes_phy/xc7.py @@ -113,13 +113,13 @@ def elaborate(self, platform): class DRPFieldController(Elaboratable): """ Gateware that atomically updates part of a word via DRP. """ - def __init__(self, *, addr: int, bits: slice, reset=0): + def __init__(self, *, addr: int, bits: slice, init=0): self._addr = addr self._bits = bits self.drp = DRPInterface() - self.value = Signal(bits.stop - bits.start, reset=reset) + self.value = Signal(bits.stop - bits.start, init=reset) def elaborate(self, platform): @@ -193,7 +193,7 @@ def elaborate(self, platform): timer = Signal(range(cycles)) # Defer reset immediately after configuration; and never again, even if our domain is reset. - defer = Signal(reset=1, reset_less=True) + defer = Signal(init=1, reset_less=True) with m.If(defer): m.d.ss += timer.eq(timer + 1) diff --git a/luna/gateware/interface/serdes_phy/xc7_gtp.py b/luna/gateware/interface/serdes_phy/xc7_gtp.py index 8fe650bd..c25c5cfb 100644 --- a/luna/gateware/interface/serdes_phy/xc7_gtp.py +++ b/luna/gateware/interface/serdes_phy/xc7_gtp.py @@ -282,7 +282,7 @@ def elaborate(self, platform): m.submodules += FFSynchronizer(self.rx_termination, rx_termination, o_domain="ss") m.submodules.rx_term = rx_term = DRPFieldController( - addr=0x0011, bits=slice(4, 6), reset=0b10) # RX_CM_SEL + addr=0x0011, bits=slice(4, 6), init=0b10) # RX_CM_SEL m.d.comb += [ rx_term.value.eq(Mux(rx_termination, 0b11, # Programmable diff --git a/luna/gateware/interface/serdes_phy/xc7_gtx.py b/luna/gateware/interface/serdes_phy/xc7_gtx.py index 6ebba051..ada8a509 100644 --- a/luna/gateware/interface/serdes_phy/xc7_gtx.py +++ b/luna/gateware/interface/serdes_phy/xc7_gtx.py @@ -388,7 +388,7 @@ def elaborate(self, platform): m.submodules += FFSynchronizer(self.rx_termination, rx_termination, o_domain="ss") m.submodules.rx_term = rx_term = DRPFieldController( - addr=0x0011, bits=slice(4, 6), reset=0b10) # RX_CM_SEL + addr=0x0011, bits=slice(4, 6), init=0b10) # RX_CM_SEL m.d.comb += [ rx_term.value.eq(Mux(self.rx_termination, 0b11, # Programmable diff --git a/luna/gateware/interface/spi.py b/luna/gateware/interface/spi.py index a12bb5e0..12f180fb 100644 --- a/luna/gateware/interface/spi.py +++ b/luna/gateware/interface/spi.py @@ -102,7 +102,7 @@ def elaborate(self, platform): # We'll use separate buffers for transmit and receive, # as this makes the code a little more readable. - bit_count = Signal(range(0, self.word_size), reset=0) + bit_count = Signal(range(0, self.word_size), init=0) current_tx = Signal.like(self.word_out) current_rx = Signal.like(self.word_in) @@ -537,7 +537,7 @@ def add_read_only_register(self, address, *, read, read_strobe=None): def add_register(self, address, *, value_signal=None, size=None, name=None, read_strobe=None, - write_strobe=None, reset=0): + write_strobe=None, init=0): """ Adds a standard, memory-backed register. Parameters: @@ -561,7 +561,7 @@ def add_register(self, address, *, value_signal=None, size=None, name=None, read # Generate a backing store for the register, if we don't already have one. if value_signal is None: size = self.register_size if (size is None) else size - value_signal = Signal(size, name=name, reset=reset) + value_signal = Signal(size, name=name, init=init) # If we don't have a write strobe signal, create an internal one. if write_strobe is None: diff --git a/luna/gateware/interface/uart.py b/luna/gateware/interface/uart.py index a34da7f0..71a0eb7f 100644 --- a/luna/gateware/interface/uart.py +++ b/luna/gateware/interface/uart.py @@ -49,7 +49,7 @@ def __init__(self, *, divisor): # # I/O port # - self.tx = Signal(reset=1) + self.tx = Signal(init=1) self.driving = Signal() self.stream = StreamInterface() @@ -168,7 +168,7 @@ def __init__(self, *, byte_width, divisor): # # I/O port # - self.tx = Signal(reset=1) + self.tx = Signal(init=1) self.stream = StreamInterface(payload_width=byte_width * 8) self.idle = Signal() diff --git a/luna/gateware/interface/ulpi.py b/luna/gateware/interface/ulpi.py index 0bc3b7f8..37e3f0f6 100644 --- a/luna/gateware/interface/ulpi.py +++ b/luna/gateware/interface/ulpi.py @@ -397,14 +397,14 @@ def __init__(self, *, register_window, own_register_window=False): # I/O port # self.bus_idle = Signal() - self.xcvr_select = Signal(2, reset=0b01) + self.xcvr_select = Signal(2, init=0b01) self.term_select = Signal() self.op_mode = Signal(2) self.suspend = Signal() self.id_pullup = Signal() - self.dp_pulldown = Signal(reset=1) - self.dm_pulldown = Signal(reset=1) + self.dp_pulldown = Signal(init=1) + self.dm_pulldown = Signal(init=1) self.chrg_vbus = Signal() self.dischrg_vbus = Signal() @@ -412,7 +412,7 @@ def __init__(self, *, register_window, own_register_window=False): self.busy = Signal() # Extra/non-UTMI properties. - self.use_external_vbus_indicator = Signal(reset=1) + self.use_external_vbus_indicator = Signal(init=1) # # Internal variables. @@ -432,7 +432,7 @@ def add_composite_register(self, m, address, value, *, reset_value=0): -- of the given register; allowing us to avoid an initial write. """ - current_register_value = Signal(8, reset=reset_value, name=f"current_register_value_{address:02x}") + current_register_value = Signal(8, init=reset_value, name=f"current_register_value_{address:02x}") # Create internal signals that request register updates. write_requested = Signal(name=f"write_requested_{address:02x}") diff --git a/luna/gateware/usb/usb2/device.py b/luna/gateware/usb/usb2/device.py index 086917bb..756272d7 100644 --- a/luna/gateware/usb/usb2/device.py +++ b/luna/gateware/usb/usb2/device.py @@ -224,10 +224,10 @@ def elaborate(self, platform): # # Stores the device's current address. Used to identify which packets are for us. - address = Signal(7, reset=0) + address = Signal(7, init=0) # Stores the device's current configuration. Defaults to unconfigured. - configuration = Signal(8, reset=0) + configuration = Signal(8, init=0) # diff --git a/luna/gateware/usb/usb2/endpoints/isochronous.py b/luna/gateware/usb/usb2/endpoints/isochronous.py index dde94eac..e9b383a5 100644 --- a/luna/gateware/usb/usb2/endpoints/isochronous.py +++ b/luna/gateware/usb/usb2/endpoints/isochronous.py @@ -90,7 +90,7 @@ def elaborate(self, platform): # Track our state in our transmission. bytes_left_in_frame = Signal.like(self.bytes_in_frame) - bytes_left_in_packet = Signal(range(0, self._max_packet_size + 1), reset=self._max_packet_size - 1) + bytes_left_in_packet = Signal(range(0, self._max_packet_size + 1), init=self._max_packet_size - 1) next_data_pid = Signal(2) # Reset our state at the start of each frame. diff --git a/luna/gateware/usb/usb2/packet.py b/luna/gateware/usb/usb2/packet.py index a8f61f70..2fea7540 100644 --- a/luna/gateware/usb/usb2/packet.py +++ b/luna/gateware/usb/usb2/packet.py @@ -561,7 +561,7 @@ def __init__(self, initial_value=0xFFFF): self.tx_data = Signal(8) self.tx_valid = Signal() - self.crc = Signal(16, reset=initial_value) + self.crc = Signal(16, init=initial_value) def add_interface(self, interface : DataCRCInterface): @@ -611,7 +611,7 @@ def elaborate(self, platform): m = Module() # Register that contains the running CRCs. - crc = Signal(16, reset=self._initial_value) + crc = Signal(16, init=self._initial_value) # Signal that contains the output version of our active CRC. output_crc = Signal.like(crc) diff --git a/luna/gateware/usb/usb2/request.py b/luna/gateware/usb/usb2/request.py index e509649d..67be59ed 100644 --- a/luna/gateware/usb/usb2/request.py +++ b/luna/gateware/usb/usb2/request.py @@ -90,7 +90,7 @@ def __init__(self): self.tx = USBInStreamInterface() self.handshakes_out = HandshakeExchangeInterface(is_detector=True) self.handshakes_in = HandshakeExchangeInterface(is_detector=False) - self.tx_data_pid = Signal(reset=1) + self.tx_data_pid = Signal(init=1) diff --git a/luna/gateware/usb/usb2/reset.py b/luna/gateware/usb/usb2/reset.py index a41fb246..d0e07436 100644 --- a/luna/gateware/usb/usb2/reset.py +++ b/luna/gateware/usb/usb2/reset.py @@ -130,9 +130,9 @@ def __init__(self): self.bus_reset = Signal() self.suspended = Signal() - self.current_speed = Signal(2, reset=USBSpeed.FULL) - self.operating_mode = Signal(2, reset=UTMIOperatingMode.NORMAL) - self.termination_select = Signal(1, reset=1) + self.current_speed = Signal(2, init=USBSpeed.FULL) + self.operating_mode = Signal(2, init=UTMIOperatingMode.NORMAL) + self.termination_select = Signal(1, init=1) self.tx = UTMITransmitInterface() diff --git a/luna/gateware/usb/usb2/transfer.py b/luna/gateware/usb/usb2/transfer.py index 8f33f937..6c28e39a 100644 --- a/luna/gateware/usb/usb2/transfer.py +++ b/luna/gateware/usb/usb2/transfer.py @@ -93,7 +93,7 @@ def __init__(self, max_packet_size): # Note: we'll start with DATA1 in our register; as we'll toggle our data PID # before we send. - self.data_pid = Signal(2, reset=1) + self.data_pid = Signal(2, init=1) self.buffer_toggle = Signal() self.tokenizer = TokenDetectorInterface() diff --git a/luna/gateware/usb/usb3/device.py b/luna/gateware/usb/usb3/device.py index 3616fc28..5acb9b27 100644 --- a/luna/gateware/usb/usb3/device.py +++ b/luna/gateware/usb/usb3/device.py @@ -100,10 +100,10 @@ def elaborate(self, platform): # # Stores the device's current address. Used to identify which packets are for us. - address = Signal(7, reset=0) + address = Signal(7, init=0) # Stores the device's current configuration. Defaults to unconfigured. - configuration = Signal(8, reset=0) + configuration = Signal(8, init=0) # diff --git a/luna/gateware/usb/usb3/link/crc.py b/luna/gateware/usb/usb3/link/crc.py index 4cb27fca..c7492faf 100644 --- a/luna/gateware/usb/usb3/link/crc.py +++ b/luna/gateware/usb/usb3/link/crc.py @@ -76,7 +76,7 @@ def __init__(self, initial_value=0xFFFF): self.data_input = Signal(32) self.advance_crc = Signal() - self.crc = Signal(16, reset=initial_value) + self.crc = Signal(16, init=initial_value) def _generate_next_crc(self, current_crc, data_in): @@ -133,7 +133,7 @@ def elaborate(self, platform): m = Module() # Register that contains the running CRCs. - crc = Signal(16, reset=self._initial_value) + crc = Signal(16, init=self._initial_value) # If we're clearing our CRC in progress, move our holding register back to # our initial value. @@ -391,7 +391,7 @@ def elaborate(self, platform): m = Module() # Register that contains the running CRCs. - crc = Signal(32, reset=self._initial_value) + crc = Signal(32, init=self._initial_value) # Internal signals representing our next internal state given various input sizes. next_crc_3B = Signal.like(crc) diff --git a/luna/gateware/usb/usb3/link/receiver.py b/luna/gateware/usb/usb3/link/receiver.py index 2f789ae6..53cbc918 100644 --- a/luna/gateware/usb/usb3/link/receiver.py +++ b/luna/gateware/usb/usb3/link/receiver.py @@ -258,7 +258,7 @@ def elaborate(self, platform): # ... and which header we'll need to ACK next. # We'll start with the maximum number, so our first advertisement wraps us back around to zero. - next_header_to_ack = Signal.like(expected_sequence_number, reset=-1) + next_header_to_ack = Signal.like(expected_sequence_number, init=-1) # @@ -266,7 +266,7 @@ def elaborate(self, platform): # # Keep track of how many header received acknowledgements (LGOODs) we need to send. - acks_to_send = Signal(range(self._buffer_count + 1), reset=1) + acks_to_send = Signal(range(self._buffer_count + 1), init=1) enqueue_ack = Signal() dequeue_ack = Signal() @@ -279,7 +279,7 @@ def elaborate(self, platform): # Keep track of how many link credits we've yet to free. # We'll start with every one of our buffers marked as "pending free"; this ensures # we perform our credit restoration properly. - credits_to_issue = Signal.like(acks_to_send, reset=self._buffer_count) + credits_to_issue = Signal.like(acks_to_send, init=self._buffer_count) enqueue_credit_issue = Signal() dequeue_credit_issue = Signal() @@ -326,7 +326,7 @@ def elaborate(self, platform): write_pointer = Signal.like(read_pointer) # Track how many buffers we currently have in use. - buffers_filled = Signal.like(credits_to_issue, reset=0) + buffers_filled = Signal.like(credits_to_issue, init=0) reserve_buffer = Signal() release_buffer = Signal() diff --git a/luna/gateware/usb/usb3/link/transmitter.py b/luna/gateware/usb/usb3/link/transmitter.py index d44999bb..95d13a37 100644 --- a/luna/gateware/usb/usb3/link/transmitter.py +++ b/luna/gateware/usb/usb3/link/transmitter.py @@ -671,7 +671,7 @@ def elaborate(self, platform): next_expected_credit = Signal(range(self._buffer_count)) # Keep track of what sequence number we expect to have ACK'd next. - next_expected_ack_number = Signal(self.SEQUENCE_NUMBER_WIDTH, reset=-1) + next_expected_ack_number = Signal(self.SEQUENCE_NUMBER_WIDTH, init=-1) # Handle link commands as we receive them. with m.If(lc_detector.new_command): diff --git a/luna/gateware/usb/usb3/physical/power.py b/luna/gateware/usb/usb3/physical/power.py index d5694b6d..a75bcd80 100644 --- a/luna/gateware/usb/usb3/physical/power.py +++ b/luna/gateware/usb/usb3/physical/power.py @@ -138,7 +138,7 @@ def __init__(self): # self.request_detection = Signal() - self.power_state = Signal(2, reset=2) + self.power_state = Signal(2, init=2) self.detection_control = Signal() self.phy_status = Signal() self.rx_status = Signal(3) diff --git a/luna/gateware/usb/usb3/physical/scrambling.py b/luna/gateware/usb/usb3/physical/scrambling.py index 32e7af11..f2139b47 100644 --- a/luna/gateware/usb/usb3/physical/scrambling.py +++ b/luna/gateware/usb/usb3/physical/scrambling.py @@ -59,7 +59,7 @@ def elaborate(self, platform): m = Module() next_value = Signal(16) - current_value = Signal(16, reset=self._initial_value) + current_value = Signal(16, init=self._initial_value) def xor_bits(*indices): bits = (current_value[i] for i in indices) diff --git a/luna/gateware/usb/usb3/protocol/endpoint.py b/luna/gateware/usb/usb3/protocol/endpoint.py index 5f3cfce7..63a023d8 100644 --- a/luna/gateware/usb/usb3/protocol/endpoint.py +++ b/luna/gateware/usb/usb3/protocol/endpoint.py @@ -78,7 +78,7 @@ def __init__(self): self.tx_length = Signal(range(1024 + 1)) self.tx_endpoint_number = Signal(4) self.tx_sequence_number = Signal(5) - self.tx_direction = Signal(reset=1) + self.tx_direction = Signal(init=1) # Handshaking / transaction packet exchange. self.handshakes_out = HandshakeGeneratorInterface() diff --git a/tests/test_i2c.py b/tests/test_i2c.py index d8b470b9..64972304 100644 --- a/tests/test_i2c.py +++ b/tests/test_i2c.py @@ -12,8 +12,8 @@ class I2CInitiatorTestbench(I2CInitiator): def __init__(self, pads, period_cyc, clk_stretch=True): super().__init__(pads, period_cyc, clk_stretch) - self.scl_o = Signal(reset=1) # used to override values from testbench - self.sda_o = Signal(reset=1) + self.scl_o = Signal(init=1) # used to override values from testbench + self.sda_o = Signal(init=1) def elaborate(self, platform): m = super().elaborate(platform) From 43c5c2b8371c4b8eae056c4c24b9b899766a2499 Mon Sep 17 00:00:00 2001 From: Mike Walters Date: Thu, 2 Jan 2025 13:08:16 +0000 Subject: [PATCH 5/6] Remove old examples/components that used the `debug_spi` interface --- applets/ulpi-test.py | 152 -------------------- examples/debugging/basic_ila.py | 59 -------- examples/debugging/basic_ila_fast_domain.py | 73 ---------- examples/debugging/ila_shared_bus.py | 111 -------------- examples/hw_features/debug_spi.py | 50 ------- examples/hw_features/debug_spi_reg.py | 48 ------- examples/hw_features/uart_bridge.py | 71 --------- luna/gateware/applets/dc_flash.py | 70 --------- 8 files changed, 634 deletions(-) delete mode 100755 applets/ulpi-test.py delete mode 100755 examples/debugging/basic_ila.py delete mode 100755 examples/debugging/basic_ila_fast_domain.py delete mode 100755 examples/debugging/ila_shared_bus.py delete mode 100755 examples/hw_features/debug_spi.py delete mode 100755 examples/hw_features/debug_spi_reg.py delete mode 100755 examples/hw_features/uart_bridge.py delete mode 100644 luna/gateware/applets/dc_flash.py diff --git a/applets/ulpi-test.py b/applets/ulpi-test.py deleted file mode 100755 index 7ab38d50..00000000 --- a/applets/ulpi-test.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python3 -# pylint: disable=maybe-no-member -# -# This file is part of LUNA. -# -# Copyright (c) 2020 Great Scott Gadgets -# SPDX-License-Identifier: BSD-3-Clause - -import sys -import time - -from prompt_toolkit import HTML -from prompt_toolkit import print_formatted_text as pprint - -from amaranth import Signal, Elaboratable, Module, Cat, ClockDomain, ClockSignal, ResetInserter -from amaranth.lib.cdc import FFSynchronizer - -from luna import top_level_cli - -from apollo_fpga import ApolloDebugger, ApolloILAFrontend -from luna.gateware.debug.ila import SyncSerialILA - - -from luna.gateware.utils.cdc import synchronize -from luna.gateware.architecture.car import LunaECP5DomainGenerator -from luna.gateware.interface.spi import SPIRegisterInterface, SPIMultiplexer, SPIBus -from luna.gateware.interface.ulpi import UTMITranslator -from luna.gateware.usb.analyzer import USBAnalyzer - - -DATA_AVAILABLE = 1 -ANALYZER_RESULT = 2 - - -class ULPIDiagnostic(Elaboratable): - """ Gateware that evalutes ULPI PHY functionality. """ - - - def elaborate(self, platform): - m = Module() - - # Generate our clock domains. - clocking = LunaECP5DomainGenerator() - m.submodules.clocking = clocking - - # Grab a reference to our debug-SPI bus. - board_spi = synchronize(m, platform.request("debug_spi").i) - - # Create our SPI-connected registers. - m.submodules.spi_registers = spi_registers = SPIRegisterInterface(7, 8) - m.d.comb += spi_registers.spi.connect(board_spi) - - # Create our UTMI translator. - ulpi = platform.request(platform.default_usb_connection) - m.submodules.utmi = utmi = UTMITranslator(ulpi=ulpi) - - - # Strap our power controls to be in VBUS passthrough by default, - # on the target port. - m.d.comb += [ - platform.request("power_a_port").o .eq(0), - platform.request("pass_through_vbus").o .eq(1), - ] - - - # Hook up our LEDs to status signals. - m.d.comb += [ - platform.request("led", 2).o .eq(utmi.session_valid), - platform.request("led", 3).o .eq(utmi.rx_active), - platform.request("led", 4).o .eq(utmi.rx_error) - ] - - # Set up our parameters. - m.d.comb += [ - - # Set our mode to non-driving and full speed. - utmi.op_mode .eq(0b01), - utmi.xcvr_select .eq(0b01), - - # Disable the DP/DM pull resistors. - utmi.dm_pulldown .eq(0), - utmi.dm_pulldown .eq(0), - utmi.term_select .eq(0) - ] - - read_strobe = Signal() - - # Create a USB analyzer, and connect a register up to its output. - m.submodules.analyzer = analyzer = USBAnalyzer(utmi_interface=utmi) - - # Provide registers that indicate when there's data ready, and what the result is. - spi_registers.add_read_only_register(DATA_AVAILABLE, read=analyzer.data_available) - spi_registers.add_read_only_register(ANALYZER_RESULT, read=analyzer.data_out, read_strobe=read_strobe) - - m.d.comb += [ - platform.request("led", 0).o .eq(analyzer.capturing), - platform.request("led", 1).o .eq(analyzer.data_available), - platform.request("led", 5).o .eq(analyzer.overrun), - - analyzer.next .eq(read_strobe) - ] - - - # Debug output. - m.d.comb += [ - platform.request("user_io", 0, dir="o").o .eq(ClockSignal("usb")), - platform.request("user_io", 1, dir="o").o .eq(ulpi.dir), - platform.request("user_io", 2, dir="o").o .eq(ulpi.nxt), - platform.request("user_io", 3, dir="o").o .eq(analyzer.sampling), - ] - - - # Return our elaborated module. - return m - - -if __name__ == "__main__": - analyzer = top_level_cli(ULPIDiagnostic) - debugger = ApolloDebugger() - - time.sleep(1) - - def data_is_available(): - return debugger.spi.register_read(DATA_AVAILABLE) - - def read_byte(): - return debugger.spi.register_read(ANALYZER_RESULT) - - def get_next_byte(): - while not data_is_available(): - time.sleep(0.1) - - return read_byte() - - # Tiny stateful parser for our analyzer. - while True: - - # Grab our header, and process it. - size = (get_next_byte() << 16) | get_next_byte() - - # Then read and print out our body - packet = [get_next_byte() for _ in range(size)] - packet_hex = [f"{byte:02x}" for byte in packet] - packet_as_string = bytes(packet) - print(f"{packet_as_string}: {packet_hex}") - - #byte = get_next_byte() - #print(f"{byte:02x} ", end="") - #sys.stdout.flush() - - - diff --git a/examples/debugging/basic_ila.py b/examples/debugging/basic_ila.py deleted file mode 100755 index 18909da0..00000000 --- a/examples/debugging/basic_ila.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is part of LUNA. -# -# Copyright (c) 2020 Great Scott Gadgets -# SPDX-License-Identifier: BSD-3-Clause - -import sys - -from amaranth import * -from apollo_fpga import create_ila_frontend - -from luna import top_level_cli -from luna.gateware.platform import NullPin -from luna.gateware.utils.cdc import synchronize -from luna.gateware.debug.ila import SyncSerialILA - - -class ILAExample(Elaboratable): - """ Gateware module that demonstrates use of the internal ILA. """ - - def __init__(self): - self.counter = Signal(28) - self.ila = SyncSerialILA(signals=[self.counter], sample_depth=32) - - def emit_analysis_vcd(self, filename='-'): - frontend = create_ila_frontend(self.ila) - frontend.emit_vcd(filename) - - - def elaborate(self, platform): - m = Module() - m.submodules += self.ila - - # Clock divider / counter. - m.d.sync += self.counter.eq(self.counter + 1) - - # Set our ILA to trigger each time the counter is at a random value. - # This shows off our example a bit better than counting at zero. - m.d.comb += self.ila.trigger.eq(self.counter == 7) - - # Grab our I/O connectors. - leds = [platform.request_optional("led", i, default=NullPin(), dir="o").o for i in range(0, 6)] - spi_bus = synchronize(m, platform.request('debug_spi')) - - # Attach the LEDs and User I/O to the MSBs of our counter. - m.d.comb += Cat(leds).eq(self.counter[-7:-1]) - - # Connect our ILA up to our board's aux SPI. - m.d.comb += self.ila.spi.connect(spi_bus) - - # Return our elaborated module. - return m - - -if __name__ == "__main__": - example = top_level_cli(ILAExample) - example.emit_analysis_vcd() - diff --git a/examples/debugging/basic_ila_fast_domain.py b/examples/debugging/basic_ila_fast_domain.py deleted file mode 100755 index 9d92e29e..00000000 --- a/examples/debugging/basic_ila_fast_domain.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is part of LUNA. -# -# Copyright (c) 2020 Great Scott Gadgets -# SPDX-License-Identifier: BSD-3-Clause - -import sys -from amaranth import Signal, Module, Elaboratable, ClockDomain, ClockSignal, Cat - -from luna import top_level_cli -from luna.gateware.utils.cdc import synchronize -from luna.gateware.debug.ila import SyncSerialILA -from luna.gateware.architecture.car import LunaECP5DomainGenerator - -from apollo_fpga import create_ila_frontend - -# -# Clock frequencies for each of the domains. -# Can be modified to test at faster or slower frequencies. -# -CLOCK_FREQUENCIES = { - "fast": 240, - "sync": 120, - "usb": 60 -} - -class ILAExample(Elaboratable): - """ Gateware module that demonstrates use of the internal ILA. """ - - def __init__(self): - self.counter = Signal(28) - self.ila = SyncSerialILA(signals=[self.counter], sample_depth=32, domain='fast') - - - def interactive_display(self): - frontend = create_ila_frontend(self.ila) - frontend.interactive_display() - - - def elaborate(self, platform): - m = Module() - m.submodules += self.ila - - # Generate our clock domains. - clocking = LunaECP5DomainGenerator(clock_frequencies=CLOCK_FREQUENCIES) - m.submodules.clocking = clocking - - # Clock divider / counter. - m.d.fast += self.counter.eq(self.counter + 1) - - # Set our ILA to trigger each time the counter is at a random value. - # This shows off our example a bit better than counting at zero. - m.d.comb += self.ila.trigger.eq(self.counter == 7) - - # Grab our I/O connectors. - leds = [platform.request("led", i, dir="o").o for i in range(0, 6)] - spi_bus = synchronize(m, platform.request('debug_spi'), o_domain='fast') - - # Attach the LEDs and User I/O to the MSBs of our counter. - m.d.comb += Cat(leds).eq(self.counter[-7:-1]) - - # Connect our ILA up to our board's aux SPI. - m.d.comb += self.ila.spi.connect(spi_bus) - - # Return our elaborated module. - return m - - -if __name__ == "__main__": - example = top_level_cli(ILAExample) - example.interactive_display() - diff --git a/examples/debugging/ila_shared_bus.py b/examples/debugging/ila_shared_bus.py deleted file mode 100755 index ab7eee03..00000000 --- a/examples/debugging/ila_shared_bus.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is part of LUNA. -# -# Copyright (c) 2020 Great Scott Gadgets -# SPDX-License-Identifier: BSD-3-Clause - -# NOTE: This example requires a working `gtkwave` binary -# to be present and on the system path; and will display the -# relevant output automatically in GTKWave. - -import time - -from amaranth import Signal, Elaboratable, Module, Cat, ClockDomain, ClockSignal, ResetInserter -from amaranth.lib.cdc import FFSynchronizer - -from luna import top_level_cli -from apollo_fpga import ApolloDebugger, ApolloILAFrontend -from luna.gateware.utils.cdc import synchronize -from luna.gateware.interface.spi import SPIRegisterInterface, SPIMultiplexer, SPIBus -from luna.gateware.debug.ila import SyncSerialILA - -REGISTER_ID = 1 -REGISTER_ILA = 2 - -class ILASharedBusExample(Elaboratable): - """ - Gateware that demonstrates sharing the Debug SPI bus between - a register interface and an ILA. - """ - - def __init__(self): - self.counter = Signal(28) - self.toggle = Signal() - self.ila = SyncSerialILA(signals=[self.counter, self.toggle], sample_depth=32) - - - def elaborate(self, platform): - m = Module() - m.submodules += self.ila - - # Grab a reference to our debug-SPI bus. - board_spi = synchronize(m, platform.request("debug_spi")) - - # Clock divider / counter. - m.d.sync += self.counter.eq(self.counter + 1) - - # Another example signal, for variety. - m.d.sync += self.toggle.eq(~self.toggle) - - # Create an SPI bus for our ILA. - ila_spi = SPIBus() - m.d.comb += [ - self.ila.spi .connect(ila_spi), - - # For sharing, we'll connect the _inverse_ of the primary - # chip select to our ILA bus. This will allow us to send - # ILA data when CS is un-asserted, and register data when - # CS is asserted. - ila_spi.cs .eq(~board_spi.cs.i) - ] - - # Create a set of registers... - spi_registers = SPIRegisterInterface() - m.submodules.spi_registers = spi_registers - - # ... and an SPI bus for them. - reg_spi = SPIBus() - m.d.comb += [ - spi_registers.spi .connect(reg_spi), - reg_spi.cs .eq(board_spi.cs.i) - ] - - # Multiplex our ILA and register SPI busses. - m.submodules.mux = SPIMultiplexer([ila_spi, reg_spi]) - m.d.comb += m.submodules.mux.shared_lines.connect(board_spi) - - # Add a simple ID register to demonstrate our registers. - spi_registers.add_read_only_register(REGISTER_ID, read=0xDEADBEEF) - - # Create a simple SFR that will trigger an ILA capture when written, - # and which will display our sample status read. - spi_registers.add_sfr(REGISTER_ILA, - read=self.ila.complete, - write_strobe=self.ila.trigger - ) - - # Attach the LEDs and User I/O to the MSBs of our counter. - leds = [platform.request("led", i, dir="o").o for i in range(0, 6)] - m.d.comb += Cat(leds).eq(self.counter[-7:-1]) - - # Return our elaborated module. - return m - - -if __name__ == "__main__": - example = top_level_cli(ILASharedBusExample) - - # Create a debug and ILA connection. - debugger = ApolloDebugger() - ila = ApolloILAFrontend(debugger, ila=example.ila, use_inverted_cs=True) - - # Trigger an ILA capture. - debugger.spi.register_write(REGISTER_ILA, 0) - - # Wait for the capture to be complete. - while not debugger.spi.register_read(REGISTER_ILA): - time.sleep(0.001) - - # Finally, read back the capture and display it on-screen. - ila.interactive_display() diff --git a/examples/hw_features/debug_spi.py b/examples/hw_features/debug_spi.py deleted file mode 100755 index abc1d3ca..00000000 --- a/examples/hw_features/debug_spi.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is part of LUNA. -# -# Copyright (c) 2020 Great Scott Gadgets -# SPDX-License-Identifier: BSD-3-Clause - -from amaranth import Signal, Elaboratable, Module -from amaranth.lib.cdc import FFSynchronizer - -from luna import top_level_cli -from luna.gateware.utils.cdc import synchronize -from luna.gateware.interface.spi import SPIDeviceInterface, SPIBus - - -class DebugSPIExample(Elaboratable): - """ Hardware meant to demonstrate use of the Debug Controller's SPI interface. """ - - - def __init__(self): - - # Base ourselves around an SPI command interface. - self.interface = SPIDeviceInterface(clock_phase=1) - - - def elaborate(self, platform): - m = Module() - board_spi = platform.request("debug_spi") - - # Use our command interface. - m.submodules.interface = self.interface - - # - # Synchronize and connect our SPI. - # - spi = synchronize(m, board_spi) - m.d.comb += self.interface.spi.connect(spi) - - # Turn on a single LED, just to show something's running. - led = platform.request('led', 0).o - m.d.comb += led.eq(1) - - # Echo back the last received data. - m.d.comb += self.interface.word_out.eq(self.interface.word_in) - - return m - - -if __name__ == "__main__": - top_level_cli(DebugSPIExample) diff --git a/examples/hw_features/debug_spi_reg.py b/examples/hw_features/debug_spi_reg.py deleted file mode 100755 index 87fb3b50..00000000 --- a/examples/hw_features/debug_spi_reg.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is part of LUNA. -# -# Copyright (c) 2020 Great Scott Gadgets -# SPDX-License-Identifier: BSD-3-Clause - -from amaranth import Signal, Elaboratable, Module, Cat -from amaranth.lib.cdc import FFSynchronizer - -from luna import top_level_cli - -from luna.gateware.utils.cdc import synchronize -from luna.gateware.interface.spi import SPIRegisterInterface -from luna.gateware.platform import NullPin - -class DebugSPIRegisterExample(Elaboratable): - """ Gateware meant to demonstrate use of the Debug Controller's register interface. """ - - - def elaborate(self, platform): - m = Module() - board_spi = platform.request("debug_spi") - - # Create a set of registers, and expose them over SPI. - spi_registers = SPIRegisterInterface(default_read_value=0x4C554E41) #default read = u'LUNA' - m.submodules.spi_registers = spi_registers - - # Fill in some example registers. - # (Register 0 is reserved for size autonegotiation). - spi_registers.add_read_only_register(1, read=0xc001cafe) - led_reg = spi_registers.add_register(2, size=6, name="leds") - spi_registers.add_read_only_register(3, read=0xdeadbeef) - - # ... and tie our LED register to our LEDs. - led_out = Cat([platform.request_optional("led", i, default=NullPin()).o for i in range(0, 8)]) - m.d.comb += led_out.eq(led_reg) - - # Connect up our synchronized copies of the SPI registers. - spi = synchronize(m, board_spi) - m.d.comb += spi_registers.spi.connect(spi) - - - return m - - -if __name__ == "__main__": - top_level_cli(DebugSPIRegisterExample) diff --git a/examples/hw_features/uart_bridge.py b/examples/hw_features/uart_bridge.py deleted file mode 100755 index 601f8e1d..00000000 --- a/examples/hw_features/uart_bridge.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is part of LUNA. -# -# Copyright (c) 2020 Great Scott Gadgets -# SPDX-License-Identifier: BSD-3-Clause -""" -Example of using the debug controller's UART bridge. - -Connect to the ttyACM connection at 115200 baud, 8N1, -and you should see "Hello World" 'typed' repeatedly. -""" - -from amaranth import Signal, Elaboratable, Module, Array, Cat - -from luna import top_level_cli -from luna.gateware.interface.uart import UARTTransmitter - - -class UARTBridgeExample(Elaboratable): - - def elaborate(self, platform): - m = Module() - uart = platform.request("uart") - - clock_freq = int(60e6) - char_freq = int(6e6) - - # Create our UART transmitter. - transmitter = UARTTransmitter(divisor=int(clock_freq // 115200)) - m.submodules.transmitter = transmitter - stream = transmitter.stream - - # Create a counter that will let us transmit ten times per second. - counter = Signal(range(0, char_freq)) - with m.If(counter == (char_freq - 1)): - m.d.sync += counter.eq(0) - with m.Else(): - m.d.sync += counter.eq(counter + 1) - - # Create a simple ROM with a message for ourselves... - letters = Array(ord(i) for i in "Hello, world! \r\n") - - # ... and count through it whenever we send a letter. - current_letter = Signal(range(0, len(letters))) - with m.If(stream.ready): - m.d.sync += current_letter.eq(current_letter + 1) - - # Hook everything up. - m.d.comb += [ - stream.payload .eq(letters[current_letter]), - stream.valid .eq(counter == 0), - - uart.tx.o .eq(transmitter.tx), - ] - - # If this platform has an output-enable control on its UART, drive it iff - # we're actively driving a transmission. - if hasattr(uart.tx, 'oe'): - m.d.comb += uart.tx.oe.eq(transmitter.driving), - - - # Turn on a single LED, just to show something's running. - led = Cat(platform.request('led', i).o for i in range(6)) - m.d.comb += led.eq(~transmitter.tx) - - return m - - -if __name__ == "__main__": - top_level_cli(UARTBridgeExample) diff --git a/luna/gateware/applets/dc_flash.py b/luna/gateware/applets/dc_flash.py deleted file mode 100644 index 56b96ea5..00000000 --- a/luna/gateware/applets/dc_flash.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# This file is part of LUNA. -# -# Copyright (c) 2020 Great Scott Gadgets -# SPDX-License-Identifier: BSD-3-Clause - -import operator -from functools import reduce - -from amaranth import Signal, Elaboratable, Module, Cat, ClockDomain, ClockSignal, ResetInserter -from amaranth.lib.cdc import FFSynchronizer - -from luna.gateware.utils.cdc import synchronize -from luna.gateware.interface.spi import SPIRegisterInterface -from luna.gateware.interface.flash import ECP5ConfigurationFlashInterface - -REGISTER_ID = 1 - -class DebugControllerFlashBridge(Elaboratable): - """ Hardware that makes the configuration flash accessible from the Debug Controller. """ - - def elaborate(self, platform): - m = Module() - - # Create a set of registers, and expose them over SPI. - board_spi = platform.request("debug_spi") - spi_registers = SPIRegisterInterface(default_read_value=-1) - m.submodules.spi_registers = spi_registers - - # Identify ourselves as the SPI flash bridge. - spi_registers.add_read_only_register(REGISTER_ID, read=0x53504946) - - - # - # SPI flash passthrough connections. - # - flash_sdo = Signal() - - spi_flash_bus = platform.request('spi_flash') - spi_flash_passthrough = ECP5ConfigurationFlashInterface(bus=spi_flash_bus) - - m.submodules += spi_flash_passthrough - m.d.comb += [ - spi_flash_passthrough.sck .eq(board_spi.sck.i), - spi_flash_passthrough.sdi .eq(board_spi.sdi.i), - flash_sdo .eq(spi_flash_passthrough.sdo), - ] - - # - # Structural connections. - # - spi = synchronize(m, board_spi) - - # Select the passthrough or gateware SPI based on our chip-select values. - gateware_sdo = Signal() - with m.If(board_spi.cs.i): - m.d.comb += board_spi.sdo.o.eq(gateware_sdo) - with m.Else(): - m.d.comb += board_spi.sdo.o.eq(flash_sdo) - - # Connect our register interface to our board SPI. - m.d.comb += [ - spi_registers.spi.sck .eq(spi.sck.i), - spi_registers.spi.sdi .eq(spi.sdi.i), - gateware_sdo .eq(spi_registers.spi.sdo), - spi_registers.spi.cs .eq(spi.cs.i) - ] - - return m - From ca97c7e5376a3df3aa9467bd67f7c04400e858a1 Mon Sep 17 00:00:00 2001 From: Mike Walters Date: Thu, 2 Jan 2025 13:19:41 +0000 Subject: [PATCH 6/6] Remove `synchronize` helper function --- .../interface/gateware_phy/receiver.py | 9 +-- luna/gateware/usb/usb2/endpoints/status.py | 7 +- luna/gateware/usb/usb3/physical/lfps.py | 8 ++- luna/gateware/utils/__init__.py | 3 +- luna/gateware/utils/cdc.py | 65 +------------------ tests/test_cdc.py | 45 +------------ 6 files changed, 18 insertions(+), 119 deletions(-) diff --git a/luna/gateware/interface/gateware_phy/receiver.py b/luna/gateware/interface/gateware_phy/receiver.py index 9dd72e2c..45296373 100644 --- a/luna/gateware/interface/gateware_phy/receiver.py +++ b/luna/gateware/interface/gateware_phy/receiver.py @@ -33,11 +33,10 @@ # from amaranth import Elaboratable, Module, Signal, Cat, Const, ClockSignal +from amaranth.lib.cdc import FFSynchronizer from amaranth.lib.fifo import AsyncFIFOBuffered from amaranth.hdl.xfrm import ResetInserter -from ...utils.cdc import synchronize - class RxClockDataRecovery(Elaboratable): """RX Clock Data Recovery module. @@ -102,8 +101,10 @@ def elaborate(self, platform): # Synchronize the USB signals at our I/O boundary. # Despite the assumptions made in ValentyUSB, this line rate recovery FSM # isn't enough to properly synchronize these inputs. We'll explicitly synchronize. - sync_dp = synchronize(m, self._usbp, o_domain="usb_io") - sync_dn = synchronize(m, self._usbn, o_domain="usb_io") + sync_dp = Signal() + sync_dn = Signal() + m.submodules.dp_cdc = FFSynchronizer(self._usbp, sync_dp, o_domain="usb_io") + m.submodules.dn_cdc = FFSynchronizer(self._usbn, sync_dn, o_domain="usb_io") ####################################################################### # Line State Recovery State Machine diff --git a/luna/gateware/usb/usb2/endpoints/status.py b/luna/gateware/usb/usb2/endpoints/status.py index b4d63400..795fa6b2 100644 --- a/luna/gateware/usb/usb2/endpoints/status.py +++ b/luna/gateware/usb/usb2/endpoints/status.py @@ -10,10 +10,10 @@ repeatedly poll a device for status. """ -from amaranth import Elaboratable, Module, Signal, Array +from amaranth import Elaboratable, Module, Signal, Array +from amaranth.lib.cdc import FFSynchronizer from ..endpoint import EndpointInterface -from ....utils.cdc import synchronize class USBSignalInEndpoint(Elaboratable): @@ -76,7 +76,8 @@ def elaborate(self, platform): if self._signal_domain == "usb": target_signal = self.signal else: - target_signal = synchronize(m, self.signal, o_domain="usb") + target_signal = Signal() + m.submodules.target_signal_cdc = FFSynchronizer(self.signal, target_signal, o_domain="usb") # Store a latched version of our signal, captured before we start a transmission. diff --git a/luna/gateware/usb/usb3/physical/lfps.py b/luna/gateware/usb/usb3/physical/lfps.py index b8cff422..ad60dce9 100644 --- a/luna/gateware/usb/usb3/physical/lfps.py +++ b/luna/gateware/usb/usb3/physical/lfps.py @@ -28,9 +28,10 @@ from math import ceil -from amaranth import * +from amaranth import * +from amaranth.lib.cdc import FFSynchronizer -from ....utils import synchronize, rising_edge_detected +from ....utils import rising_edge_detected __all__ = ['LFPSTransceiver'] @@ -106,7 +107,8 @@ def elaborate(self, platform): m = Module() # Create an in-domain version of our square-wave-detector signal. - present = synchronize(m, self.signaling_received, o_domain="ss") + present = Signal() + m.submodules.present_cdc = FFSynchronizer(self.signaling_received, present, o_domain="ss") # Figure out how large of a counter we're going to need... burst_cycles_min = ceil(self._clock_frequency * self._pattern.burst.t_min) diff --git a/luna/gateware/utils/__init__.py b/luna/gateware/utils/__init__.py index 1150dc54..1bf432c5 100644 --- a/luna/gateware/utils/__init__.py +++ b/luna/gateware/utils/__init__.py @@ -4,11 +4,10 @@ """ Simple utility constructs for LUNA. """ from amaranth import Module, Signal, Cat -from .cdc import synchronize __all__ = [ 'rising_edge_detected', 'falling_edge_detected', 'any_edge_detected', - 'past_value_of', 'synchronize' + 'past_value_of' ] diff --git a/luna/gateware/utils/cdc.py b/luna/gateware/utils/cdc.py index afdabd2f..eb9cdd0b 100644 --- a/luna/gateware/utils/cdc.py +++ b/luna/gateware/utils/cdc.py @@ -7,70 +7,7 @@ """ Helpers for clock domain crossings. """ -from amaranth import Record, Signal -from amaranth.lib.cdc import FFSynchronizer -from amaranth.lib.io import Pin -from amaranth.hdl.rec import DIR_FANOUT - - -def synchronize(m, signal, *, output=None, o_domain='sync', stages=2): - """ Convenience function. Synchronizes a signal, or equivalent collection. - - Parameters: - input -- The signal to be synchronized. - output -- The signal to output the result of the synchronization - to, or None to have one created for you. - domain -- The name of the domain to be synchronized to. - stages -- The depth (in FFs) of the synchronization chain. - Longer incurs more delay. Must be >= 2 to avoid metastability. - - Returns: - record -- The post-synchronization signal. Will be equivalent to the - `output` record if provided, or a new, created signal otherwise. - """ - - # Quick function to create a synchronizer with our domain and stages. - def create_synchronizer(signal, output): - return FFSynchronizer(signal, output, o_domain=o_domain, stages=stages) - - if output is None: - if isinstance(signal, Signal): - output = Signal.like(signal) - else: - output = Record.like(signal) - - # If the object knows how to synchronize itself, let it. - if hasattr(signal, '_synchronize_'): - signal._synchronize_(m, output, o_domain=o_domain, stages=stages) - return output - - # Trivial case: if this element doesn't have a layout, - # we can just synchronize it directly. - if not hasattr(signal, 'layout'): - m.submodules += create_synchronizer(signal, output) - return output - - # Otherwise, we'll need to make sure we only synchronize - # elements with non-output directions. - for name, layout, direction in signal.layout: - # Skip any output elements, as they're already - # in our clock domain, and we don't want to drive them. - if (direction == DIR_FANOUT): - m.d.comb += signal[name].eq(output[name]) - continue - elif hasattr(signal[name], 'o') and ~hasattr(signal[name], 'i'): - m.d.comb += signal[name].o.eq(output[name]) - continue - - # If this is a record itself, we'll need to recurse. - if isinstance(signal[name], (Record, Pin)): - synchronize(m, signal[name], output=output[name], - o_domain=o_domain, stages=stages) - continue - - m.submodules += create_synchronizer(signal[name], output[name]) - - return output +from amaranth import Signal def stretch_strobe_signal(m, strobe, *, to_cycles, output=None, domain=None, allow_delay=False): diff --git a/tests/test_cdc.py b/tests/test_cdc.py index 628b792c..49b68201 100644 --- a/tests/test_cdc.py +++ b/tests/test_cdc.py @@ -7,49 +7,8 @@ from luna.gateware.test import LunaGatewareTestCase, sync_test_case from unittest import TestCase -from amaranth import Module, Record, Signal -from amaranth.lib.io import Pin -from amaranth.hdl.rec import DIR_FANIN, DIR_FANOUT -from luna.gateware.utils.cdc import synchronize, stretch_strobe_signal - -class SynchronizedTest(TestCase): - - def test_signal(self): - m = Module() - synchronize(m, Signal()) - - def test_directional_record(self): - m = Module() - - record = Record([ - ('sig_in', 1, DIR_FANIN), - ('sig_out', 1, DIR_FANOUT) - ]) - synchronize(m, record) - - def test_nested_record(self): - m = Module() - - record = Record([ - ('sig_in', 1, DIR_FANIN), - ('sig_out', 1, DIR_FANOUT), - ('nested', [ - ('subsig_in', 1, DIR_FANIN), - ('subsig_out', 1, DIR_FANOUT), - ]) - ]) - synchronize(m, record) - - def test_pins(self): - m = Module() - pins = { - "sig_in": Pin(1, "i"), - "sig_out": Pin(1, "o"), - } - record = Record([ - (f_name, f.layout) for (f_name, f) in pins.items() - ], fields=pins) - synchronize(m, record) +from amaranth import Module, Signal +from luna.gateware.utils.cdc import stretch_strobe_signal class StrobeStretcherTest(LunaGatewareTestCase):