2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-19 00:16:29 +08:00

drtio: handle link restarts at transceiver level

This commit is contained in:
Sebastien Bourdeauducq 2016-11-19 10:46:56 +08:00
parent ba94ed8f4b
commit 381e58434f
5 changed files with 16 additions and 50 deletions

View File

@ -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)

View File

@ -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)
) )

View File

@ -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)
] ]

View File

@ -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")

View File

@ -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();
} }
} }