forked from M-Labs/artiq
drtio: handle link restarts at transceiver level
This commit is contained in:
parent
ba94ed8f4b
commit
381e58434f
|
@ -9,10 +9,7 @@ class DRTIOSatellite(Module):
|
||||||
def __init__(self, transceiver, rx_synchronizer, channels, fine_ts_width=3, full_ts_width=63):
|
def __init__(self, transceiver, rx_synchronizer, channels, fine_ts_width=3, full_ts_width=63):
|
||||||
self.submodules.link_layer = link_layer.LinkLayer(
|
self.submodules.link_layer = link_layer.LinkLayer(
|
||||||
transceiver.encoder, transceiver.decoders)
|
transceiver.encoder, transceiver.decoders)
|
||||||
self.comb += [
|
self.comb += self.link_layer.rx_ready.eq(transceiver.rx_ready)
|
||||||
transceiver.rx_reset.eq(self.link_layer.rx_reset),
|
|
||||||
self.link_layer.rx_ready.eq(transceiver.rx_ready)
|
|
||||||
]
|
|
||||||
|
|
||||||
link_layer_sync = SimpleNamespace(
|
link_layer_sync = SimpleNamespace(
|
||||||
tx_aux_frame=self.link_layer.tx_aux_frame,
|
tx_aux_frame=self.link_layer.tx_aux_frame,
|
||||||
|
@ -54,10 +51,8 @@ class DRTIOMaster(Module):
|
||||||
def __init__(self, transceiver, channel_count=1024, fine_ts_width=3):
|
def __init__(self, transceiver, channel_count=1024, fine_ts_width=3):
|
||||||
self.submodules.link_layer = link_layer.LinkLayer(
|
self.submodules.link_layer = link_layer.LinkLayer(
|
||||||
transceiver.encoder, transceiver.decoders)
|
transceiver.encoder, transceiver.decoders)
|
||||||
self.comb += [
|
self.comb += self.link_layer.rx_ready.eq(transceiver.rx_ready)
|
||||||
transceiver.rx_reset.eq(self.link_layer.rx_reset),
|
|
||||||
self.link_layer.rx_ready.eq(transceiver.rx_ready)
|
|
||||||
]
|
|
||||||
self.submodules.rt_packets = rt_packets.RTPacketMaster(self.link_layer)
|
self.submodules.rt_packets = rt_packets.RTPacketMaster(self.link_layer)
|
||||||
self.submodules.rt_controller = rt_controller.RTController(
|
self.submodules.rt_controller = rt_controller.RTController(
|
||||||
self.rt_packets, channel_count, fine_ts_width)
|
self.rt_packets, channel_count, fine_ts_width)
|
||||||
|
|
|
@ -3,7 +3,7 @@ from operator import xor, or_
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.fsm import *
|
from migen.genlib.fsm import *
|
||||||
from migen.genlib.cdc import MultiReg, PulseSynchronizer
|
from migen.genlib.cdc import MultiReg
|
||||||
from migen.genlib.misc import WaitTimer
|
from migen.genlib.misc import WaitTimer
|
||||||
|
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
|
@ -223,11 +223,8 @@ class LinkLayerRX(Module):
|
||||||
class LinkLayer(Module, AutoCSR):
|
class LinkLayer(Module, AutoCSR):
|
||||||
def __init__(self, encoder, decoders):
|
def __init__(self, encoder, decoders):
|
||||||
self.link_status = CSRStatus()
|
self.link_status = CSRStatus()
|
||||||
self.link_reset = CSR()
|
|
||||||
|
|
||||||
# pulsed to reset receiver, rx_ready must immediately go low
|
# receiver locked, comma aligned, receiving valid 8b10b symbols
|
||||||
self.rx_reset = Signal()
|
|
||||||
# receiver locked including comma alignment
|
|
||||||
self.rx_ready = Signal()
|
self.rx_ready = Signal()
|
||||||
|
|
||||||
tx = ClockDomainsRenamer("rtio")(LinkLayerTX(encoder))
|
tx = ClockDomainsRenamer("rtio")(LinkLayerTX(encoder))
|
||||||
|
@ -251,45 +248,30 @@ class LinkLayer(Module, AutoCSR):
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
ready = Signal()
|
ready = Signal()
|
||||||
reset_ps = PulseSynchronizer("sys", "rtio")
|
ready_r = Signal()
|
||||||
done_ps = PulseSynchronizer("rtio", "sys")
|
self.sync.rtio += ready_r.eq(ready)
|
||||||
self.submodules += reset_ps, done_ps
|
|
||||||
self.comb += reset_ps.i.eq(self.link_reset.re)
|
|
||||||
self.sync += [
|
|
||||||
If(done_ps.o, ready.eq(1)),
|
|
||||||
If(reset_ps.i, ready.eq(0)),
|
|
||||||
]
|
|
||||||
self.comb += self.link_status.status.eq(ready)
|
|
||||||
|
|
||||||
ready_rx = Signal()
|
ready_rx = Signal()
|
||||||
ready.attr.add("no_retiming")
|
ready_r.attr.add("no_retiming")
|
||||||
self.specials += MultiReg(ready, ready_rx, "rtio_rx")
|
self.specials += MultiReg(ready_r, ready_rx, "rtio_rx")
|
||||||
self.comb += [
|
self.comb += [
|
||||||
self.rx_aux_frame.eq(rx.aux_frame & ready_rx),
|
self.rx_aux_frame.eq(rx.aux_frame & ready_rx),
|
||||||
self.rx_rt_frame.eq(rx.rt_frame & ready_rx),
|
self.rx_rt_frame.eq(rx.rt_frame & ready_rx),
|
||||||
]
|
]
|
||||||
|
self.specials += MultiReg(ready_r, self.link_status.status)
|
||||||
|
|
||||||
wait_scrambler = ClockDomainsRenamer("rtio")(WaitTimer(15))
|
wait_scrambler = ClockDomainsRenamer("rtio")(WaitTimer(15))
|
||||||
self.submodules += wait_scrambler
|
self.submodules += wait_scrambler
|
||||||
|
|
||||||
fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="RESET_RX"))
|
fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="WAIT_RX_READY"))
|
||||||
self.submodules += fsm
|
self.submodules += fsm
|
||||||
|
|
||||||
fsm.act("RESET_RX",
|
|
||||||
self.rx_reset.eq(1),
|
|
||||||
NextState("WAIT_RX_READY")
|
|
||||||
)
|
|
||||||
fsm.act("WAIT_RX_READY",
|
fsm.act("WAIT_RX_READY",
|
||||||
If(self.rx_ready, NextState("WAIT_SCRAMBLER_SYNC")),
|
If(self.rx_ready, NextState("WAIT_SCRAMBLER_SYNC"))
|
||||||
If(reset_ps.o, NextState("RESET_RX"))
|
|
||||||
)
|
)
|
||||||
fsm.act("WAIT_SCRAMBLER_SYNC",
|
fsm.act("WAIT_SCRAMBLER_SYNC",
|
||||||
wait_scrambler.wait.eq(1),
|
wait_scrambler.wait.eq(1),
|
||||||
If(wait_scrambler.done,
|
If(wait_scrambler.done, NextState("READY"))
|
||||||
done_ps.i.eq(1),
|
|
||||||
NextState("READY")
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
fsm.act("READY",
|
fsm.act("READY",
|
||||||
If(reset_ps.o, NextState("RESET_RX"))
|
ready.eq(1)
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,7 +20,6 @@ class GTX_1000BASE_BX10(Module):
|
||||||
Decoder(True)) for _ in range(2)]
|
Decoder(True)) for _ in range(2)]
|
||||||
self.submodules += self.decoders
|
self.submodules += self.decoders
|
||||||
|
|
||||||
self.rx_reset = Signal()
|
|
||||||
self.rx_ready = Signal()
|
self.rx_ready = Signal()
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
@ -49,8 +48,7 @@ class GTX_1000BASE_BX10(Module):
|
||||||
GTXInit(self.rtio_clk_freq, True))
|
GTXInit(self.rtio_clk_freq, True))
|
||||||
self.submodules += tx_init, rx_init
|
self.submodules += tx_init, rx_init
|
||||||
self.comb += tx_init.cplllock.eq(cplllock), \
|
self.comb += tx_init.cplllock.eq(cplllock), \
|
||||||
rx_init.cplllock.eq(cplllock), \
|
rx_init.cplllock.eq(cplllock)
|
||||||
rx_init.restart.eq(self.rx_reset)
|
|
||||||
|
|
||||||
txoutclk = Signal()
|
txoutclk = Signal()
|
||||||
txdata = Signal(20)
|
txdata = Signal(20)
|
||||||
|
@ -190,7 +188,6 @@ class GTX_1000BASE_BX10(Module):
|
||||||
self.comb += [
|
self.comb += [
|
||||||
clock_aligner.rxdata.eq(rxdata),
|
clock_aligner.rxdata.eq(rxdata),
|
||||||
rx_init.restart.eq(clock_aligner.restart),
|
rx_init.restart.eq(clock_aligner.restart),
|
||||||
clock_aligner.reset.eq(self.rx_reset),
|
|
||||||
self.rx_ready.eq(clock_aligner.ready)
|
self.rx_ready.eq(clock_aligner.ready)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,6 @@ class BruteforceClockAligner(Module):
|
||||||
self.rxdata = Signal(20)
|
self.rxdata = Signal(20)
|
||||||
self.restart = Signal()
|
self.restart = Signal()
|
||||||
|
|
||||||
self.reset = Signal()
|
|
||||||
self.ready = Signal()
|
self.ready = Signal()
|
||||||
|
|
||||||
check_max_val = ceil(check_period*rtio_clk_freq)
|
check_max_val = ceil(check_period*rtio_clk_freq)
|
||||||
|
@ -219,7 +218,7 @@ class BruteforceClockAligner(Module):
|
||||||
fsm.act("READY",
|
fsm.act("READY",
|
||||||
reset_check_counter.eq(1),
|
reset_check_counter.eq(1),
|
||||||
self.ready.eq(1),
|
self.ready.eq(1),
|
||||||
If(self.reset,
|
If(error_seen,
|
||||||
checks_reset.i.eq(1),
|
checks_reset.i.eq(1),
|
||||||
self.restart.eq(1),
|
self.restart.eq(1),
|
||||||
NextState("WAIT_COMMA")
|
NextState("WAIT_COMMA")
|
||||||
|
|
|
@ -7,12 +7,6 @@ fn drtio_link_is_up() -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drtio_reset_link() {
|
|
||||||
unsafe {
|
|
||||||
csr::drtio::link_reset_write(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn drtio_sync_tsc() {
|
fn drtio_sync_tsc() {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::set_time_write(1);
|
csr::drtio::set_time_write(1);
|
||||||
|
@ -72,6 +66,5 @@ pub fn error_thread(waiter: Waiter, _spawner: Spawner) {
|
||||||
loop {
|
loop {
|
||||||
waiter.until(drtio_packet_error_present).unwrap();
|
waiter.until(drtio_packet_error_present).unwrap();
|
||||||
error!("DRTIO packet error {}", drtio_get_packet_error());
|
error!("DRTIO packet error {}", drtio_get_packet_error());
|
||||||
drtio_reset_link();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue