diff --git a/examples/usb/superspeed/simple_device.py b/examples/usb/superspeed/simple_device.py index 71cb5769f..814c75302 100755 --- a/examples/usb/superspeed/simple_device.py +++ b/examples/usb/superspeed/simple_device.py @@ -6,7 +6,6 @@ # SPDX-License-Identifier: BSD-3-Clause from amaranth import * -from amaranth.hdl.ast import Fell from usb_protocol.emitters import SuperSpeedDeviceDescriptorCollection diff --git a/examples/usb/superspeed/stream_in_device.py b/examples/usb/superspeed/stream_in_device.py index c05f2cd22..85165f084 100755 --- a/examples/usb/superspeed/stream_in_device.py +++ b/examples/usb/superspeed/stream_in_device.py @@ -6,7 +6,6 @@ # SPDX-License-Identifier: BSD-3-Clause from amaranth import * -from amaranth.hdl.ast import Fell from usb_protocol.emitters import SuperSpeedDeviceDescriptorCollection diff --git a/examples/usb/superspeed/vendor_request.py b/examples/usb/superspeed/vendor_request.py index 0e8e51078..4c223a3d6 100755 --- a/examples/usb/superspeed/vendor_request.py +++ b/examples/usb/superspeed/vendor_request.py @@ -6,7 +6,6 @@ # SPDX-License-Identifier: BSD-3-Clause from amaranth import * -from amaranth.hdl.ast import Fell from usb_protocol.types import USBRequestType from usb_protocol.emitters import SuperSpeedDeviceDescriptorCollection diff --git a/luna/gateware/debug/ila.py b/luna/gateware/debug/ila.py index edfc68bf5..3081b2f2b 100644 --- a/luna/gateware/debug/ila.py +++ b/luna/gateware/debug/ila.py @@ -17,7 +17,6 @@ from abc import ABCMeta, abstractmethod from amaranth import Signal, Module, Cat, Elaboratable, Memory, ClockDomain, DomainRenamer -from amaranth.hdl.ast import Rose from amaranth.lib.cdc import FFSynchronizer from amaranth.lib.fifo import AsyncFIFOBuffered from vcd import VCDWriter @@ -376,7 +375,10 @@ def elaborate(self, platform): m = Module() m.submodules.ila = self.ila - transaction_start = Rose(self.spi.cs) + # Keep track of the rising edge of the CS signal + past_spi_cs = Signal() + m.d.sync += past_spi_cs.eq(self.spi.cs) + transaction_start = ~past_spi_cs & self.spi.cs # Connect up our SPI transciever to our public interface. interface = SPIDeviceInterface( diff --git a/luna/gateware/interface/gateware_phy/phy.py b/luna/gateware/interface/gateware_phy/phy.py index 950871276..106c56547 100644 --- a/luna/gateware/interface/gateware_phy/phy.py +++ b/luna/gateware/interface/gateware_phy/phy.py @@ -6,7 +6,6 @@ import logging from amaranth import Signal, Module, Cat, Elaboratable, ClockSignal -from amaranth.hdl.ast import Rose, Past from .receiver import RxPipeline from .transmitter import TxPipeline diff --git a/luna/gateware/interface/gateware_phy/receiver.py b/luna/gateware/interface/gateware_phy/receiver.py index 40b7f0e9c..298fde3cc 100644 --- a/luna/gateware/interface/gateware_phy/receiver.py +++ b/luna/gateware/interface/gateware_phy/receiver.py @@ -34,7 +34,6 @@ from amaranth import Elaboratable, Module, Signal, Cat, Const, ClockSignal from amaranth.lib.fifo import AsyncFIFOBuffered -from amaranth.hdl.ast import Past from amaranth.hdl.xfrm import ResetInserter from ...utils.cdc import synchronize @@ -622,10 +621,12 @@ def elaborate(self, platform): # 1bit->8bit (1byte) gearing # m.submodules.shifter = shifter = RxShifter(width=8) + past_o_pkt_active = Signal() + m.d.usb_io += past_o_pkt_active.eq(detect.o_pkt_active) m.d.comb += [ shifter.reset.eq(detect.o_pkt_end), shifter.i_data.eq(bitstuff.o_data), - shifter.i_valid.eq(~bitstuff.o_stall & Past(detect.o_pkt_active, domain="usb_io")), + shifter.i_valid.eq(~bitstuff.o_stall & past_o_pkt_active), ] # diff --git a/luna/gateware/interface/spi.py b/luna/gateware/interface/spi.py index ead2b44d6..693dc0962 100644 --- a/luna/gateware/interface/spi.py +++ b/luna/gateware/interface/spi.py @@ -9,7 +9,6 @@ import unittest from amaranth import Signal, Module, Cat, Elaboratable, Record -from amaranth.hdl.ast import Rose, Fell from amaranth.hdl.rec import DIR_FANIN, DIR_FANOUT from ..test.utils import LunaGatewareTestCase, sync_test_case @@ -85,8 +84,10 @@ def spi_edge_detectors(self, m): # Generate the leading and trailing edge detectors. # Note that we use rising and falling edge detectors, but call these leading and # trailing edges, as our clock here may have been inverted. - leading_edge = Rose(serial_clock, domain="sync") - trailing_edge = Fell(serial_clock, domain="sync") + past_clk = Signal() + m.d.sync += past_clk.eq(serial_clock) + leading_edge = ~past_clk & serial_clock + trailing_edge = past_clk & ~serial_clock # Determine the sample and output edges based on the SPI clock phase. sample_edge = trailing_edge if self.clock_phase else leading_edge @@ -336,7 +337,10 @@ def elaborate(self, platform): m = Module() spi = self.spi - sample_edge = Fell(spi.sck, domain="sync") + # Detect falling edge of SPI clock + past_sck = Signal() + m.d.sync += past_sck.eq(spi.sck) + sample_edge = past_sck & ~spi.sck # Bit counter: counts the number of bits received. max_bit_count = max(self.word_size, self.command_size) diff --git a/luna/gateware/interface/ulpi.py b/luna/gateware/interface/ulpi.py index e3cb30c09..d4da0be66 100644 --- a/luna/gateware/interface/ulpi.py +++ b/luna/gateware/interface/ulpi.py @@ -11,7 +11,6 @@ from amaranth import Signal, Module, Cat, Elaboratable, ClockSignal, \ Record, ResetSignal, Const -from amaranth.hdl.ast import Rose, Fell, Past from amaranth.hdl.rec import Record, DIR_FANIN, DIR_FANOUT, DIR_NONE from ..utils.io import delay @@ -1296,7 +1295,9 @@ def elaborate(self, platform): # A transmission starts when DIR goes high with NXT, or when an RxEvent indicates # a switch from RxActive = 0 to RxActive = 1. A transmission stops when DIR drops low, # or when the RxEvent RxActive bit drops from 1 to 0, or an error occurs.A - dir_rising_edge = Rose(self.ulpi.dir.i, domain="usb") + past_dir = Signal.like(self.ulpi.dir.i) + m.d.usb += past_dir.eq(self.ulpi.dir.i) + dir_rising_edge = ~past_dir & self.ulpi.dir.i dir_based_start = dir_rising_edge & self.ulpi.nxt diff --git a/luna/gateware/usb/usb2/endpoint.py b/luna/gateware/usb/usb2/endpoint.py index c7143d53d..d2d0ddddf 100644 --- a/luna/gateware/usb/usb2/endpoint.py +++ b/luna/gateware/usb/usb2/endpoint.py @@ -9,8 +9,7 @@ import functools import operator -from amaranth import Signal, Elaboratable, Module -from amaranth.hdl.ast import Past +from amaranth import Signal, Elaboratable, Module, Cat from .packet import DataCRCInterface, InterpacketTimerInterface, TokenDetectorInterface from .packet import HandshakeExchangeInterface @@ -264,8 +263,10 @@ def elaborate(self, platform): conditional = m.If # We'll connect our PID toggle to whichever interface has a valid transmission going. - for interface in self._interfaces: - with conditional(interface.tx.valid | Past(interface.tx.valid, domain="usb")): + past_valid = Signal(len(self._interfaces)) + m.d.usb += past_valid.eq(Cat(interface.tx.valid for interface in self._interfaces)) + for i, interface in enumerate(self._interfaces): + with conditional(interface.tx.valid | past_valid[i]): m.d.comb += shared.tx_pid_toggle.eq(interface.tx_pid_toggle) conditional = m.Elif diff --git a/luna/gateware/usb/usb3/link/command.py b/luna/gateware/usb/usb3/link/command.py index b94daf9e8..a3e3b4275 100644 --- a/luna/gateware/usb/usb3/link/command.py +++ b/luna/gateware/usb/usb3/link/command.py @@ -11,7 +11,6 @@ from enum import IntEnum from amaranth import * -from amaranth.hdl.ast import Past from .crc import compute_usb_crc5 from ..physical.coding import SLC, EPF, stream_matches_symbols, get_word_for_symbols diff --git a/luna/gateware/usb/usb3/link/idle.py b/luna/gateware/usb/usb3/link/idle.py index 598ab6770..1a35debd5 100644 --- a/luna/gateware/usb/usb3/link/idle.py +++ b/luna/gateware/usb/usb3/link/idle.py @@ -6,7 +6,6 @@ """ Logical idle detection / polling gateware. """ from amaranth import * -from amaranth.hdl.ast import Past from ...stream import USBRawSuperSpeedStream @@ -57,8 +56,12 @@ def elaborate(self, platform): ctrl_word = self.sink.ctrl # Capture the previous data word; so we have a record of eight consecutive signals. - last_word = Past(self.sink.data) - last_ctrl = Past(self.sink.ctrl) + last_word = Signal.like(data_word) + last_ctrl = Signal.like(ctrl_word) + m.d.ss += [ + last_word.eq(data_word), + last_ctrl.eq(ctrl_word), + ] # Logical idle descrambles to the raw data value zero; so we only need to validate that # the last and current words are both zeroes. diff --git a/luna/gateware/usb/usb3/link/receiver.py b/luna/gateware/usb/usb3/link/receiver.py index cebf8ca1e..912d0e0dc 100644 --- a/luna/gateware/usb/usb3/link/receiver.py +++ b/luna/gateware/usb/usb3/link/receiver.py @@ -8,7 +8,6 @@ import unittest from amaranth import * -from amaranth.hdl.ast import Fell from usb_protocol.types.superspeed import LinkCommand @@ -425,6 +424,9 @@ def elaborate(self, platform): with m.If(self.acknowledge_power_state): m.d.ss += lpma_pending.eq(1) + # Keep track of the last value of the enable signal + last_enable = Signal() + m.d.ss += last_enable.eq(self.enable) # # Header Packet Buffers @@ -600,7 +602,7 @@ def elaborate(self, platform): # Once we've become disabled, we'll want to prepare for our next enable. # This means preparing for our advertisement, by: - with m.If(Fell(self.enable) | self.usb_reset): + with m.If((last_enable & ~self.enable) | self.usb_reset): m.d.ss += [ # -Resetting our pending ACKs to 1, so we perform an sequence number advertisement # when we're next enabled. diff --git a/luna/gateware/usb/usb3/physical/alignment.py b/luna/gateware/usb/usb3/physical/alignment.py index 0a9d181e9..d31928436 100644 --- a/luna/gateware/usb/usb3/physical/alignment.py +++ b/luna/gateware/usb/usb3/physical/alignment.py @@ -9,7 +9,6 @@ """ Code for USB3 physical-layer encoding. """ from amaranth import * -from amaranth.hdl.ast import Past from .coding import COM, SHP, SLC, EPF, get_word_for_symbols from ...stream import USBRawSuperSpeedStream diff --git a/luna/gateware/usb/usb3/physical/power.py b/luna/gateware/usb/usb3/physical/power.py index 2ff0041a8..d5694b6d8 100644 --- a/luna/gateware/usb/usb3/physical/power.py +++ b/luna/gateware/usb/usb3/physical/power.py @@ -9,7 +9,6 @@ from amaranth import * from amaranth.lib.cdc import PulseSynchronizer, FFSynchronizer -from amaranth.hdl.ast import Rose class PHYResetController(Elaboratable): @@ -156,6 +155,10 @@ def elaborate(self, platform): # after a detection completes. PARTNER_PRESENT_STATUS = 0b011 + # Keep track of the previous value of the request detection strobe + past_request_detection = Signal() + m.d.ss += past_request_detection.eq(self.request_detection) + with m.FSM(domain="ss"): # IDLE_P2 -- our post-startup state; represents when we're IDLE but in P2. @@ -211,7 +214,8 @@ def elaborate(self, platform): # We can only perform detections from P2; so, when the user requests a detection, we'll # need to move back to P2. - with m.If(Rose(self.request_detection)): + request_detection_rose = ~past_request_detection & self.request_detection + with m.If(request_detection_rose): m.next = "MOVE_TO_P2"