drtio: link layer debugging CSRs

This commit is contained in:
Sebastien Bourdeauducq 2016-12-07 23:03:14 +08:00
parent b311830fc4
commit 4c3717932e
2 changed files with 90 additions and 14 deletions

View File

@ -20,10 +20,13 @@ class DRTIOSatellite(Module):
rx_aux_stb=rx_synchronizer.resync(self.link_layer.rx_aux_stb), rx_aux_stb=rx_synchronizer.resync(self.link_layer.rx_aux_stb),
rx_aux_frame=rx_synchronizer.resync(self.link_layer.rx_aux_frame), rx_aux_frame=rx_synchronizer.resync(self.link_layer.rx_aux_frame),
rx_aux_frame_perm=rx_synchronizer.resync(self.link_layer.rx_aux_frame_perm),
rx_aux_data=rx_synchronizer.resync(self.link_layer.rx_aux_data), rx_aux_data=rx_synchronizer.resync(self.link_layer.rx_aux_data),
rx_rt_frame=rx_synchronizer.resync(self.link_layer.rx_rt_frame), rx_rt_frame=rx_synchronizer.resync(self.link_layer.rx_rt_frame),
rx_rt_frame_perm=rx_synchronizer.resync(self.link_layer.rx_rt_frame_perm),
rx_rt_data=rx_synchronizer.resync(self.link_layer.rx_rt_data) rx_rt_data=rx_synchronizer.resync(self.link_layer.rx_rt_data)
) )
self.submodules.link_stats = link_layer.LinkLayerStats(link_layer_sync, "rtio")
self.submodules.rt_packets = ClockDomainsRenamer("rtio")( self.submodules.rt_packets = ClockDomainsRenamer("rtio")(
rt_packets.RTPacketSatellite(link_layer_sync)) rt_packets.RTPacketSatellite(link_layer_sync))
@ -43,7 +46,8 @@ class DRTIOSatellite(Module):
self.link_layer) self.link_layer)
def get_csrs(self): def get_csrs(self):
return self.aux_controller.get_csrs() return (self.link_layer.get_csrs() + self.link_stats.get_csrs() +
self.aux_controller.get_csrs())
class DRTIOMaster(Module): class DRTIOMaster(Module):
@ -52,6 +56,7 @@ class DRTIOMaster(Module):
transceiver.encoder, transceiver.decoders) transceiver.encoder, transceiver.decoders)
self.comb += self.link_layer.rx_ready.eq(transceiver.rx_ready) self.comb += self.link_layer.rx_ready.eq(transceiver.rx_ready)
self.submodules.link_stats = link_layer.LinkLayerStats(self.link_layer, "rtio_rx")
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)
@ -63,6 +68,7 @@ class DRTIOMaster(Module):
def get_csrs(self): def get_csrs(self):
return (self.link_layer.get_csrs() + return (self.link_layer.get_csrs() +
self.link_stats.get_csrs() +
self.rt_controller.get_csrs() + self.rt_controller.get_csrs() +
self.rt_manager.get_csrs() + self.rt_manager.get_csrs() +
self.aux_controller.get_csrs()) self.aux_controller.get_csrs())

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 from migen.genlib.cdc import MultiReg, GrayCounter, GrayDecoder
from migen.genlib.misc import WaitTimer from migen.genlib.misc import WaitTimer
from misoc.interconnect.csr import * from misoc.interconnect.csr import *
@ -223,6 +223,9 @@ 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.rx_disable = CSRStorage()
self.tx_force_aux_zero = CSRStorage()
self.tx_force_rt_zero = CSRStorage()
# receiver locked, comma aligned, receiving valid 8b10b symbols # receiver locked, comma aligned, receiving valid 8b10b symbols
self.rx_ready = Signal() self.rx_ready = Signal()
@ -232,18 +235,20 @@ class LinkLayer(Module, AutoCSR):
self.submodules += tx, rx self.submodules += tx, rx
# in rtio clock domain # in rtio clock domain
self.tx_aux_frame = tx.aux_frame self.tx_aux_frame = Signal()
self.tx_aux_data = tx.aux_data self.tx_aux_data = Signal(len(tx.aux_data))
self.tx_aux_ack = tx.aux_ack self.tx_aux_ack = Signal()
self.tx_rt_frame = tx.rt_frame self.tx_rt_frame = Signal()
self.tx_rt_data = tx.rt_data self.tx_rt_data = Signal(len(tx.rt_data))
# in rtio_rx clock domain # in rtio_rx clock domain
self.rx_aux_stb = rx.aux_stb self.rx_aux_stb = Signal()
self.rx_aux_frame = Signal() self.rx_aux_frame = Signal()
self.rx_aux_data = rx.aux_data self.rx_aux_frame_perm = Signal()
self.rx_aux_data = Signal(len(rx.aux_data))
self.rx_rt_frame = Signal() self.rx_rt_frame = Signal()
self.rx_rt_data = rx.rt_data self.rx_rt_frame_perm = Signal()
self.rx_rt_data = Signal(len(rx.rt_data))
# # # # # #
@ -252,12 +257,40 @@ class LinkLayer(Module, AutoCSR):
self.sync.rtio += ready_r.eq(ready) self.sync.rtio += ready_r.eq(ready)
ready_rx = Signal() ready_rx = Signal()
ready_r.attr.add("no_retiming") ready_r.attr.add("no_retiming")
self.specials += MultiReg(ready_r, ready_rx, "rtio_rx") self.specials += [
MultiReg(ready_r, ready_rx, "rtio_rx"),
MultiReg(ready_r, self.link_status.status)]
tx_force_aux_zero_rtio = Signal()
tx_force_rt_zero_rtio = Signal()
self.tx_force_aux_zero.storage.attr.add("no_retiming")
self.tx_force_rt_zero.storage.attr.add("no_retiming")
self.specials += [
MultiReg(self.tx_force_aux_zero.storage, tx_force_aux_zero_rtio, "rtio"),
MultiReg(self.tx_force_rt_zero.storage, tx_force_rt_zero_rtio, "rtio")]
rx_disable_rx = Signal()
self.rx_disable.storage.attr.add("no_retiming")
self.specials += MultiReg(self.rx_disable.storage, rx_disable_rx, "rtio_rx")
self.comb += [ self.comb += [
self.rx_aux_frame.eq(rx.aux_frame & ready_rx), tx.aux_frame.eq(self.tx_aux_frame | tx_force_aux_zero_rtio),
self.rx_rt_frame.eq(rx.rt_frame & ready_rx), tx.aux_data.eq(Mux(tx_force_aux_zero_rtio, 0, self.tx_aux_data)),
self.tx_aux_ack.eq(tx.aux_ack),
tx.rt_frame.eq(self.tx_rt_frame | tx_force_rt_zero_rtio),
tx.rt_data.eq(Mux(tx_force_rt_zero_rtio, 0, self.tx_rt_data))
]
# we register those to improve timing margins, as the data may need
# to be recaptured by RXSynchronizer.
self.sync.rtio_rx += [
self.rx_aux_stb.eq(rx.aux_stb),
self.rx_aux_frame.eq(rx.aux_frame & ready_rx & ~rx_disable_rx),
self.rx_aux_frame_perm.eq(rx.aux_frame & ready_rx),
self.rx_aux_data.eq(rx.aux_data),
self.rx_rt_frame.eq(rx.rt_frame & ready_rx & ~rx_disable_rx),
self.rx_rt_frame_perm.eq(rx.rt_frame & ready_rx),
self.rx_rt_data.eq(rx.rt_data)
] ]
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
@ -276,3 +309,40 @@ class LinkLayer(Module, AutoCSR):
ready.eq(1), ready.eq(1),
If(~self.rx_ready, NextState("WAIT_RX_READY")) If(~self.rx_ready, NextState("WAIT_RX_READY"))
) )
# Zero word count is used with the "force zero" TX modes to implement
# PRBS tests.
class LinkLayerStats(Module, AutoCSR):
def __init__(self, link_layer, rx_clock_domain):
self.aux_word_cnt = CSRStatus(64)
self.aux_zword_cnt = CSRStatus(64)
self.rt_word_cnt = CSRStatus(64)
self.rt_zword_cnt = CSRStatus(64)
self.update_link_stats = CSR()
# # #
aux_word = Signal()
aux_zword = Signal()
rt_word = Signal()
rt_zword = Signal()
sync = getattr(self.sync, rx_clock_domain)
sync += [
aux_word.eq(link_layer.rx_aux_frame_perm),
aux_zword.eq(link_layer.rx_aux_frame_perm & (link_layer.rx_aux_data == 0)),
rt_word.eq(link_layer.rx_rt_frame_perm),
rt_zword.eq(link_layer.rx_rt_frame_perm & (link_layer.rx_aux_data == 0))
]
for trigger, csr in [(aux_word, self.aux_word_cnt),
(aux_zword, self.aux_zword_cnt),
(rt_word, self.rt_word_cnt),
(rt_zword, self.rt_zword_cnt)]:
counter = ClockDomainsRenamer(rx_clock_domain)(GrayCounter(64))
decoder = GrayDecoder(64)
self.submodules += counter, decoder
counter.q.attr.add("no_retiming")
self.specials += MultiReg(counter.q, decoder.i)
self.comb += counter.ce.eq(trigger)
self.sync += If(self.update_link_stats.re, csr.status.eq(decoder.o))