Skip to content

Commit

Permalink
phy/rmii/LiteEthPHYRMIIRX: Avoid FSM, simplify and add comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
enjoy-digital committed Sep 23, 2024
1 parent 5438ff0 commit f252eed
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions liteeth/phy/rmii.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def __init__(self, pads):
for i in range(2):
self.specials += SDROutput(i=converter.source.data[i], o=pads.tx_data[i])


# LiteEth PHY RMII RX ------------------------------------------------------------------------------

class LiteEthPHYRMIIRX(LiteXModule):
Expand All @@ -62,38 +63,39 @@ def __init__(self, pads):

# Delay.
# ------
# Add a delay to align the data with the frame boundaries since the end-of-frame condition
# (2 consecutive `crs_dv` signals low) is detected with a few cycles delay.
self.delay = delay = stream.Delay(layout=[("data", 8)], n=2)

# Frame Delimitation.
# -------------------
crs_dv_d = Signal()
crs_first = Signal()
crs_last = Signal()
crs_run = Signal()
self.sync += crs_dv_d.eq(crs_dv)
self.comb += [
crs_first.eq(crs_dv & (rx_data != 0b00)), # Start of frame on crs_dv at 1 and non-null data.
crs_last.eq(~crs_dv & ~crs_dv_d), # End of frame on 2 consecutives crs_dv at 0.
crs_first.eq(crs_dv & (rx_data != 0b00)), # Start of frame on crs_dv high and non-null data.
crs_last.eq(~crs_dv & ~crs_dv_d), # End of frame on 2 consecutive crs_dv low.
]
self.sync += [
If(crs_first, crs_run.eq(1)),
If(crs_last, crs_run.eq(0)),
]

self.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE",
delay.source.ready.eq(1),
If(crs_first,
delay.sink.valid.eq(1),
delay.sink.data.eq(rx_data),
NextState("RECEIVE")
)
)
fsm.act("RECEIVE",
delay.sink.valid.eq(1),
# Datapath: Input -> Delay -> Converter -> Source.
# ------------------------------------------------
self.comb += [
delay.source.ready.eq(1), # Ready by default to flush pipeline.
delay.sink.valid.eq(crs_first | crs_run),
delay.sink.data.eq(rx_data),
delay.source.connect(converter.sink),
If(crs_last,
converter.sink.last.eq(1),
NextState("IDLE")
)
)
self.comb += converter.source.connect(source)
If(crs_run,
converter.sink.last.eq(crs_last),
delay.source.connect(converter.sink, keep={"valid", "ready", "data"})
),
converter.source.connect(source),
]


# LiteEth PHY RMII CRG -----------------------------------------------------------------------------

Expand Down

0 comments on commit f252eed

Please sign in to comment.