From 17efc28dbe8664cb0dd7f2f767ef3ae8636b0c7e Mon Sep 17 00:00:00 2001 From: Spaqin Date: Sat, 17 Dec 2022 15:39:54 +0800 Subject: [PATCH] DRTIO: RTIO/SYS clock merge --- artiq/firmware/runtime/rtio_clocking.rs | 51 +++++++----- artiq/firmware/satman/main.rs | 34 ++++++-- artiq/gateware/drtio/aux_controller.py | 31 +++---- artiq/gateware/drtio/core.py | 19 ++--- artiq/gateware/drtio/link_layer.py | 24 ++---- artiq/gateware/drtio/rt_controller_master.py | 2 +- .../gateware/drtio/rt_controller_repeater.py | 12 +-- artiq/gateware/drtio/rt_packet_master.py | 55 +++++-------- artiq/gateware/drtio/rt_packet_repeater.py | 28 +++---- artiq/gateware/drtio/rx_synchronizer.py | 4 +- artiq/gateware/drtio/siphaser.py | 19 ++--- .../drtio/transceiver/clock_aligner.py | 6 +- .../gateware/drtio/transceiver/gtp_7series.py | 38 +++------ artiq/gateware/drtio/wrpll/core.py | 2 +- artiq/gateware/rtio/phy/phaser.py | 4 +- artiq/gateware/targets/kasli.py | 82 ++++++++++++------- .../test/drtio/test_aux_controller.py | 2 +- artiq/gateware/test/drtio/test_full_stack.py | 8 +- .../test/drtio/test_rt_packet_repeater.py | 2 +- artiq/gateware/test/drtio/test_switching.py | 6 +- 20 files changed, 210 insertions(+), 219 deletions(-) diff --git a/artiq/firmware/runtime/rtio_clocking.rs b/artiq/firmware/runtime/rtio_clocking.rs index 8c44cca4f..6af4ea3e9 100644 --- a/artiq/firmware/runtime/rtio_clocking.rs +++ b/artiq/firmware/runtime/rtio_clocking.rs @@ -1,10 +1,7 @@ use board_misoc::config; #[cfg(si5324_as_synthesizer)] use board_artiq::si5324; -#[cfg(any(soc_platform = "kasli", has_drtio))] -use board_misoc::csr; -#[cfg(has_drtio)] -use board_misoc::clock; +use board_misoc::{csr, clock}; #[derive(Debug, PartialEq)] #[allow(non_camel_case_types)] @@ -212,15 +209,12 @@ fn setup_si5324_as_synthesizer(cfg: RtioClock) { #[cfg(si5324_as_synthesizer)] fn setup_si5324(clock_cfg: RtioClock) { - #[cfg(soc_platform = "kasli")] - { - let switched = unsafe { - csr::crg::switch_done_read() - }; - if switched == 1 { - info!("Clocking has already been set up."); - return; - } + let switched = unsafe { + csr::crg::switch_done_read() + }; + if switched == 1 { + info!("Clocking has already been set up."); + return; } #[cfg(all(soc_platform = "kasli", hw_rev = "v2.0"))] let si5324_ext_input = si5324::Input::Ckin1; @@ -239,12 +233,14 @@ fn setup_si5324(clock_cfg: RtioClock) { } // switch sysclk source to si5324 - #[cfg(soc_platform = "kasli")] + #[cfg(not(has_drtio))] { - // excessive dots will be cut off by the reboot - info!("Switching sys clock, rebooting.................."); + info!("Switching sys clock, rebooting..."); + // delay for clean UART log, wait until UART FIFO is empty + clock::spin_us(1300); unsafe { csr::crg::clock_sel_write(1); + loop {} } } } @@ -257,15 +253,28 @@ pub fn init() { #[cfg(has_drtio)] { - unsafe { - csr::drtio_transceiver::stable_clkin_write(1); + let switched = unsafe { + csr::crg::switch_done_read() + }; + if switched == 0 { + info!("Switching sys clock, rebooting..."); + clock::spin_us(500); // delay for clean UART log + unsafe { + // clock switch and reboot will begin after TX is initialized + // and TX will be initialized after this + csr::drtio_transceiver::stable_clkin_write(1); + } + loop {} } - clock::spin_us(1500); // wait for CPLL/QPLL lock - unsafe { - csr::drtio_transceiver::txenable_write(0xffffffffu32 as _); + else { + // enable TX after the reboot, with stable clock + unsafe { + csr::drtio_transceiver::txenable_write(0xffffffffu32 as _); + } } } + #[cfg(has_rtio_crg)] { #[cfg(has_rtio_clock_switch)] diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 10beb6695..7ac232827 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -465,6 +465,30 @@ const SI5324_SETTINGS: si5324::FrequencySettings crystal_ref: true }; +fn sysclk_setup() { + let switched = unsafe { + csr::crg::switch_done_read() + }; + if switched == 1 { + info!("Clocking has already been set up."); + return; + } + else { + #[cfg(has_si5324)] + si5324::setup(&SI5324_SETTINGS, si5324::Input::Ckin1).expect("cannot initialize Si5324"); + #[cfg(has_wrpll)] + wrpll::init(); + info!("Switching sys clock, rebooting..."); + // delay for clean UART log, wait until UART FIFO is empty + clock::spin_us(1300); + unsafe { + csr::drtio_transceiver::stable_clkin_write(1); + } + loop {} + } +} + + #[no_mangle] pub extern fn main() -> i32 { extern { @@ -517,21 +541,15 @@ pub extern fn main() -> i32 { io_expander1.service().unwrap(); } - #[cfg(has_si5324)] - si5324::setup(&SI5324_SETTINGS, si5324::Input::Ckin1).expect("cannot initialize Si5324"); - #[cfg(has_wrpll)] - wrpll::init(); + sysclk_setup(); - unsafe { - csr::drtio_transceiver::stable_clkin_write(1); - } - clock::spin_us(1500); // wait for CPLL/QPLL lock #[cfg(not(has_jdcg))] unsafe { csr::drtio_transceiver::txenable_write(0xffffffffu32 as _); } #[cfg(has_wrpll)] wrpll::diagnostics(); + init_rtio_crg(); #[cfg(has_hmc830_7043)] diff --git a/artiq/gateware/drtio/aux_controller.py b/artiq/gateware/drtio/aux_controller.py index 051a03a20..5f91b1f45 100644 --- a/artiq/gateware/drtio/aux_controller.py +++ b/artiq/gateware/drtio/aux_controller.py @@ -22,8 +22,7 @@ class Transmitter(Module, AutoCSR): self.aux_tx = CSR() self.specials.mem = Memory(mem_dw, max_packet//(mem_dw//8)) - converter = ClockDomainsRenamer("rtio")( - stream.Converter(mem_dw, ll_dw)) + converter = stream.Converter(mem_dw, ll_dw) self.submodules += converter # when continuously fed, the Converter outputs data continuously @@ -36,7 +35,7 @@ class Transmitter(Module, AutoCSR): seen_eop_rst = Signal() frame_r = Signal() seen_eop = Signal() - self.sync.rtio += [ + self.sync += [ If(link_layer.tx_aux_ack, frame_r.eq(link_layer.tx_aux_frame), If(frame_r & ~link_layer.tx_aux_frame, seen_eop.eq(1)) @@ -44,13 +43,9 @@ class Transmitter(Module, AutoCSR): If(seen_eop_rst, seen_eop.eq(0)) ] - mem_port = self.mem.get_port(clock_domain="rtio") + mem_port = self.mem.get_port() self.specials += mem_port - self.aux_tx_length.storage.attr.add("no_retiming") - tx_length = Signal(bits_for(max_packet)) - self.specials += MultiReg(self.aux_tx_length.storage, tx_length, "rtio") - frame_counter_nbits = bits_for(max_packet) - log2_int(mem_dw//8) frame_counter = Signal(frame_counter_nbits) frame_counter_next = Signal(frame_counter_nbits) @@ -66,35 +61,33 @@ class Transmitter(Module, AutoCSR): mem_port.adr.eq(frame_counter_next), converter.sink.data.eq(mem_port.dat_r) ] - self.sync.rtio += frame_counter.eq(frame_counter_next) - start_tx = PulseSynchronizer("sys", "rtio") - tx_done = PulseSynchronizer("rtio", "sys") - self.submodules += start_tx, tx_done - self.comb += start_tx.i.eq(self.aux_tx.re) + tx_done = Signal() self.sync += [ - If(tx_done.o, self.aux_tx.w.eq(0)), - If(self.aux_tx.re, self.aux_tx.w.eq(1)) + frame_counter.eq(frame_counter_next), + If(self.aux_tx.re, self.aux_tx.w.eq(1)), + If(tx_done, self.aux_tx.w.eq(0)) ] - fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="IDLE")) + fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", frame_counter_rst.eq(1), seen_eop_rst.eq(1), - If(start_tx.o, NextState("TRANSMIT")) + If(self.aux_tx.re, NextState("TRANSMIT")) ) fsm.act("TRANSMIT", converter.sink.stb.eq(1), If(converter.sink.ack, frame_counter_ce.eq(1) ), - If(frame_counter_next == tx_length, NextState("WAIT_INTERFRAME")) + If(frame_counter_next == self.aux_tx_length.storage, + NextState("WAIT_INTERFRAME")) ) fsm.act("WAIT_INTERFRAME", If(seen_eop, - tx_done.i.eq(1), + tx_done.eq(1), NextState("IDLE") ) ) diff --git a/artiq/gateware/drtio/core.py b/artiq/gateware/drtio/core.py index 6311456e4..e8ca07e3f 100644 --- a/artiq/gateware/drtio/core.py +++ b/artiq/gateware/drtio/core.py @@ -2,7 +2,6 @@ from types import SimpleNamespace from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.genlib.cdc import PulseSynchronizer from misoc.interconnect.csr import * from artiq.gateware.rtio import cri, rtlink @@ -31,7 +30,6 @@ class TransceiverInterface(AutoCSR): def __init__(self, channel_interfaces): self.stable_clkin = CSRStorage() self.txenable = CSRStorage(len(channel_interfaces)) - self.clock_domains.cd_rtio = ClockDomain() for i in range(len(channel_interfaces)): name = "rtio_rx" + str(i) setattr(self.clock_domains, "cd_"+name, ClockDomain(name=name)) @@ -65,7 +63,7 @@ class SyncRTIO(Module): enable_spread=False, report_buffer_space=True, interface=self.cri)) self.comb += self.outputs.coarse_timestamp.eq(tsc.coarse_ts) - self.sync.rtio += self.outputs.minimum_coarse_timestamp.eq(tsc.coarse_ts + 16) + self.sync += self.outputs.minimum_coarse_timestamp.eq(tsc.coarse_ts + 16) self.submodules.inputs = ClockDomainsRenamer("rio")( InputCollector(tsc, channels, "sync", interface=self.cri)) @@ -86,8 +84,8 @@ class DRTIOSatellite(Module): self.clock_domains.cd_rio = ClockDomain() self.clock_domains.cd_rio_phy = ClockDomain() self.comb += [ - self.cd_rio.clk.eq(ClockSignal("rtio")), - self.cd_rio_phy.clk.eq(ClockSignal("rtio")) + self.cd_rio.clk.eq(ClockSignal("sys")), + self.cd_rio_phy.clk.eq(ClockSignal("sys")) ] reset = Signal() reset_phy = Signal() @@ -125,9 +123,9 @@ class DRTIOSatellite(Module): 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) ) - self.submodules.link_stats = link_layer.LinkLayerStats(link_layer_sync, "rtio") - self.submodules.rt_packet = ClockDomainsRenamer("rtio")( - rt_packet_satellite.RTPacketSatellite(link_layer_sync, interface=self.cri)) + self.submodules.link_stats = link_layer.LinkLayerStats(link_layer_sync, "sys") + self.submodules.rt_packet = rt_packet_satellite.RTPacketSatellite( + link_layer_sync, interface=self.cri) self.comb += self.rt_packet.reset.eq(self.cd_rio.rst) self.comb += [ @@ -135,12 +133,9 @@ class DRTIOSatellite(Module): tsc.load_value.eq(self.rt_packet.tsc_load_value) ] - ps_tsc_load = PulseSynchronizer("rtio", "sys") - self.submodules += ps_tsc_load - self.comb += ps_tsc_load.i.eq(self.rt_packet.tsc_load) self.sync += [ If(self.tsc_loaded.re, self.tsc_loaded.w.eq(0)), - If(ps_tsc_load.o, self.tsc_loaded.w.eq(1)) + If(self.rt_packet.tsc_load, self.tsc_loaded.w.eq(1)) ] self.submodules.rt_errors = rt_errors_satellite.RTErrorsSatellite( diff --git a/artiq/gateware/drtio/link_layer.py b/artiq/gateware/drtio/link_layer.py index a4779e912..367830067 100644 --- a/artiq/gateware/drtio/link_layer.py +++ b/artiq/gateware/drtio/link_layer.py @@ -232,7 +232,7 @@ class LinkLayer(Module, AutoCSR): # receiver locked, comma aligned, receiving valid 8b10b symbols self.rx_ready = Signal() - tx = ClockDomainsRenamer("rtio")(LinkLayerTX(encoder)) + tx = LinkLayerTX(encoder) rx = ClockDomainsRenamer("rtio_rx")(LinkLayerRX(decoders)) self.submodules += tx, rx @@ -256,31 +256,23 @@ class LinkLayer(Module, AutoCSR): rx_up = Signal() rx_up_r = Signal() - self.sync.rtio += rx_up_r.eq(rx_up) + self.sync += rx_up_r.eq(rx_up) rx_up_rx = Signal() rx_up_r.attr.add("no_retiming") self.specials += [ MultiReg(rx_up_r, rx_up_rx, "rtio_rx"), MultiReg(rx_up_r, self.rx_up.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 += [ - tx.aux_frame.eq(self.tx_aux_frame | tx_force_aux_zero_rtio), - tx.aux_data.eq(Mux(tx_force_aux_zero_rtio, 0, self.tx_aux_data)), + tx.aux_frame.eq(self.tx_aux_frame | self.tx_force_aux_zero.storage), + tx.aux_data.eq(Mux(self.tx_force_aux_zero.storage, 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)) + tx.rt_frame.eq(self.tx_rt_frame | self.tx_force_rt_zero.storage), + tx.rt_data.eq(Mux(self.tx_force_rt_zero.storage, 0, self.tx_rt_data)) ] # we register those to improve timing margins, as the data may need # to be recaptured by RXSynchronizer. @@ -294,10 +286,10 @@ class LinkLayer(Module, AutoCSR): self.rx_rt_data.eq(rx.rt_data) ] - wait_scrambler = ClockDomainsRenamer("rtio")(WaitTimer(15)) + wait_scrambler = WaitTimer(15) self.submodules += wait_scrambler - fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="WAIT_RX_READY")) + fsm = FSM(reset_state="WAIT_RX_READY") self.submodules += fsm fsm.act("WAIT_RX_READY", diff --git a/artiq/gateware/drtio/rt_controller_master.py b/artiq/gateware/drtio/rt_controller_master.py index fdd340be8..3ed22dbe7 100644 --- a/artiq/gateware/drtio/rt_controller_master.py +++ b/artiq/gateware/drtio/rt_controller_master.py @@ -108,7 +108,7 @@ class RTController(Module): cond_underflow = Signal() self.comb += cond_underflow.eq((self.cri.o_timestamp[tsc.glbl_fine_ts_width:] - - self.csrs.underflow_margin.storage[tsc.glbl_fine_ts_width:]) < tsc.coarse_ts_sys) + - self.csrs.underflow_margin.storage[tsc.glbl_fine_ts_width:]) < tsc.coarse_ts) # buffer space buffer_space = Memory(16, 256) diff --git a/artiq/gateware/drtio/rt_controller_repeater.py b/artiq/gateware/drtio/rt_controller_repeater.py index 0fe10d1de..53b2b1b07 100644 --- a/artiq/gateware/drtio/rt_controller_repeater.py +++ b/artiq/gateware/drtio/rt_controller_repeater.py @@ -15,15 +15,11 @@ class RTController(Module, AutoCSR): self.command_missed_chan_sel = CSRStatus(24) self.buffer_space_timeout_dest = CSRStatus(8) - self.specials += MultiReg(self.reset.storage, rt_packet.reset, "rtio") + self.sync += rt_packet.reset.eq(self.reset.storage) set_time_stb = Signal() - set_time_ack = Signal() - self.submodules += CrossDomainRequest("rtio", - set_time_stb, set_time_ack, None, - rt_packet.set_time_stb, rt_packet.set_time_ack, None) self.sync += [ - If(set_time_ack, set_time_stb.eq(0)), + If(rt_packet.set_time_stb, set_time_stb.eq(0)), If(self.set_time.re, set_time_stb.eq(1)) ] self.comb += self.set_time.w.eq(set_time_stb) @@ -31,10 +27,10 @@ class RTController(Module, AutoCSR): errors = [ (rt_packet.err_unknown_packet_type, "rtio_rx", None, None), (rt_packet.err_packet_truncated, "rtio_rx", None, None), - (rt_packet.err_command_missed, "rtio", + (rt_packet.err_command_missed, "sys", Cat(rt_packet.command_missed_cmd, rt_packet.command_missed_chan_sel), Cat(self.command_missed_cmd.status, self.command_missed_chan_sel.status)), - (rt_packet.err_buffer_space_timeout, "rtio", + (rt_packet.err_buffer_space_timeout, "sys", rt_packet.buffer_space_destination, self.buffer_space_timeout_dest.status) ] diff --git a/artiq/gateware/drtio/rt_packet_master.py b/artiq/gateware/drtio/rt_packet_master.py index 4fd26f85d..70d44ecaf 100644 --- a/artiq/gateware/drtio/rt_packet_master.py +++ b/artiq/gateware/drtio/rt_packet_master.py @@ -2,7 +2,7 @@ from migen import * from migen.genlib.fsm import * -from migen.genlib.fifo import AsyncFIFO +from migen.genlib.fifo import SyncFIFO from migen.genlib.cdc import BlindTransfer from artiq.gateware.rtio.cdc import GrayCodeTransfer @@ -76,8 +76,8 @@ class RTPacketMaster(Module): assert len(link_layer.tx_rt_data) % 8 == 0 ws = len(link_layer.tx_rt_data) tx_plm = get_m2s_layouts(ws) - tx_dp = ClockDomainsRenamer("rtio")(TransmitDatapath( - link_layer.tx_rt_frame, link_layer.tx_rt_data, tx_plm)) + tx_dp = TransmitDatapath( + link_layer.tx_rt_frame, link_layer.tx_rt_data, tx_plm) self.submodules += tx_dp rx_plm = get_s2m_layouts(ws) rx_dp = ClockDomainsRenamer("rtio_rx")(ReceiveDatapath( @@ -85,8 +85,7 @@ class RTPacketMaster(Module): self.submodules += rx_dp # Write FIFO and extra data count - sr_fifo = ClockDomainsRenamer({"write": "sys", "read": "rtio"})( - AsyncFIFO(1+64+24+8+512, sr_fifo_depth)) + sr_fifo = SyncFIFO(1+64+24+8+512, sr_fifo_depth) self.submodules += sr_fifo sr_notwrite_d = Signal() sr_timestamp_d = Signal(64) @@ -106,7 +105,7 @@ class RTPacketMaster(Module): sr_buf_re = Signal() self.comb += sr_fifo.re.eq(sr_fifo.readable & (~sr_buf_readable | sr_buf_re)) - self.sync.rtio += \ + self.sync += \ If(sr_fifo.re, sr_buf_readable.eq(1), ).Elif(sr_buf_re, @@ -120,7 +119,7 @@ class RTPacketMaster(Module): sr_extra_data_cnt = Signal(8) sr_data = Signal(512) - self.sync.rtio += If(sr_fifo.re, + self.sync += If(sr_fifo.re, sr_notwrite.eq(sr_notwrite_d), sr_timestamp.eq(sr_timestamp_d), sr_chan_sel.eq(sr_chan_sel_d), @@ -131,11 +130,11 @@ class RTPacketMaster(Module): sr_extra_data_d = Signal(512) self.comb += sr_extra_data_d.eq(sr_data_d[short_data_len:]) for i in range(512//ws): - self.sync.rtio += If(sr_fifo.re, + self.sync += If(sr_fifo.re, If(sr_extra_data_d[ws*i:ws*(i+1)] != 0, sr_extra_data_cnt.eq(i+1))) sr_extra_data = Signal(512) - self.sync.rtio += If(sr_fifo.re, sr_extra_data.eq(sr_extra_data_d)) + self.sync += If(sr_fifo.re, sr_extra_data.eq(sr_extra_data_d)) extra_data_ce = Signal() extra_data_last = Signal() @@ -146,7 +145,7 @@ class RTPacketMaster(Module): for i in range(512//ws)}), extra_data_last.eq(extra_data_counter == sr_extra_data_cnt) ] - self.sync.rtio += \ + self.sync += \ If(extra_data_ce, extra_data_counter.eq(extra_data_counter + 1), ).Else( @@ -160,18 +159,6 @@ class RTPacketMaster(Module): buffer_space_not, buffer_space, self.buffer_space_not, self.buffer_space_not_ack, self.buffer_space) - set_time_stb = Signal() - set_time_ack = Signal() - self.submodules += CrossDomainRequest("rtio", - self.set_time_stb, self.set_time_ack, None, - set_time_stb, set_time_ack, None) - - echo_stb = Signal() - echo_ack = Signal() - self.submodules += CrossDomainRequest("rtio", - self.echo_stb, self.echo_ack, None, - echo_stb, echo_ack, None) - read_not = Signal() read_no_event = Signal() read_is_overflow = Signal() @@ -199,14 +186,14 @@ class RTPacketMaster(Module): ] # TX FSM - tx_fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="IDLE")) + tx_fsm = FSM(reset_state="IDLE") self.submodules += tx_fsm echo_sent_now = Signal() - self.sync.rtio += self.echo_sent_now.eq(echo_sent_now) + self.sync += self.echo_sent_now.eq(echo_sent_now) tsc_value = Signal(64) tsc_value_load = Signal() - self.sync.rtio += If(tsc_value_load, tsc_value.eq(self.tsc_value)) + self.sync += If(tsc_value_load, tsc_value.eq(self.tsc_value)) tx_fsm.act("IDLE", # Ensure 2 cycles between frames on the link. @@ -223,10 +210,10 @@ class RTPacketMaster(Module): NextState("WRITE") ) ).Else( - If(echo_stb, + If(self.echo_stb, echo_sent_now.eq(1), NextState("ECHO") - ).Elif(set_time_stb, + ).Elif(self.set_time_stb, tsc_value_load.eq(1), NextState("SET_TIME") ) @@ -273,14 +260,14 @@ class RTPacketMaster(Module): tx_fsm.act("ECHO", tx_dp.send("echo_request"), If(tx_dp.packet_last, - echo_ack.eq(1), + self.echo_ack.eq(1), NextState("IDLE") ) ) tx_fsm.act("SET_TIME", tx_dp.send("set_time", timestamp=tsc_value), If(tx_dp.packet_last, - set_time_ack.eq(1), + self.set_time_ack.eq(1), NextState("IDLE") ) ) @@ -334,16 +321,14 @@ class RTPacketMaster(Module): # packet counters tx_frame_r = Signal() packet_cnt_tx = Signal(32) - self.sync.rtio += [ + self.sync += [ tx_frame_r.eq(link_layer.tx_rt_frame), If(link_layer.tx_rt_frame & ~tx_frame_r, packet_cnt_tx.eq(packet_cnt_tx + 1)) ] - cdc_packet_cnt_tx = GrayCodeTransfer(32) - self.submodules += cdc_packet_cnt_tx + self.comb += [ - cdc_packet_cnt_tx.i.eq(packet_cnt_tx), - self.packet_cnt_tx.eq(cdc_packet_cnt_tx.o) + self.packet_cnt_tx.eq(packet_cnt_tx) ] rx_frame_r = Signal() @@ -353,7 +338,7 @@ class RTPacketMaster(Module): If(link_layer.rx_rt_frame & ~rx_frame_r, packet_cnt_rx.eq(packet_cnt_rx + 1)) ] - cdc_packet_cnt_rx = ClockDomainsRenamer({"rtio": "rtio_rx"})( + cdc_packet_cnt_rx = ClockDomainsRenamer({"rtio": "sys", "sys": "rtio_rx"})( GrayCodeTransfer(32)) self.submodules += cdc_packet_cnt_rx self.comb += [ diff --git a/artiq/gateware/drtio/rt_packet_repeater.py b/artiq/gateware/drtio/rt_packet_repeater.py index 9374d1a18..728c24ae8 100644 --- a/artiq/gateware/drtio/rt_packet_repeater.py +++ b/artiq/gateware/drtio/rt_packet_repeater.py @@ -38,8 +38,8 @@ class RTPacketRepeater(Module): assert len(link_layer.tx_rt_data) % 8 == 0 ws = len(link_layer.tx_rt_data) tx_plm = get_m2s_layouts(ws) - tx_dp = ClockDomainsRenamer("rtio")(TransmitDatapath( - link_layer.tx_rt_frame, link_layer.tx_rt_data, tx_plm)) + tx_dp = TransmitDatapath( + link_layer.tx_rt_frame, link_layer.tx_rt_data, tx_plm) self.submodules += tx_dp rx_plm = get_s2m_layouts(ws) rx_dp = ClockDomainsRenamer("rtio_rx")(ReceiveDatapath( @@ -49,7 +49,7 @@ class RTPacketRepeater(Module): # TSC sync tsc_value = Signal(64) tsc_value_load = Signal() - self.sync.rtio += If(tsc_value_load, tsc_value.eq(tsc.coarse_ts)) + self.sync += If(tsc_value_load, tsc_value.eq(tsc.coarse_ts)) # CRI buffer stage 1 cb0_loaded = Signal() @@ -60,7 +60,7 @@ class RTPacketRepeater(Module): cb0_chan_sel = Signal(24) cb0_o_address = Signal(8) cb0_o_data = Signal(512) - self.sync.rtio += [ + self.sync += [ If(self.reset | cb0_ack, cb0_loaded.eq(0), cb0_cmd.eq(cri.commands["nop"]) @@ -91,7 +91,7 @@ class RTPacketRepeater(Module): cb_chan_sel = Signal(24) cb_o_address = Signal(8) cb_o_data = Signal(512) - self.sync.rtio += [ + self.sync += [ If(self.reset | cb_ack, cb_loaded.eq(0), cb_cmd.eq(cri.commands["nop"]) @@ -112,11 +112,11 @@ class RTPacketRepeater(Module): wb_extra_data_a = Signal(512) self.comb += wb_extra_data_a.eq(self.cri.o_data[short_data_len:]) for i in range(512//ws): - self.sync.rtio += If(self.cri.cmd == cri.commands["write"], + self.sync += If(self.cri.cmd == cri.commands["write"], If(wb_extra_data_a[ws*i:ws*(i+1)] != 0, wb_extra_data_cnt.eq(i+1))) wb_extra_data = Signal(512) - self.sync.rtio += If(self.cri.cmd == cri.commands["write"], + self.sync += If(self.cri.cmd == cri.commands["write"], wb_extra_data.eq(wb_extra_data_a)) extra_data_ce = Signal() @@ -128,7 +128,7 @@ class RTPacketRepeater(Module): for i in range(512//ws)}), extra_data_last.eq(extra_data_counter == wb_extra_data_cnt) ] - self.sync.rtio += \ + self.sync += \ If(extra_data_ce, extra_data_counter.eq(extra_data_counter + 1), ).Else( @@ -136,19 +136,19 @@ class RTPacketRepeater(Module): ) # Buffer space - self.sync.rtio += If(self.cri.cmd == cri.commands["get_buffer_space"], + self.sync += If(self.cri.cmd == cri.commands["get_buffer_space"], self.buffer_space_destination.eq(self.cri.chan_sel[16:])) rx_buffer_space_not = Signal() rx_buffer_space = Signal(16) buffer_space_not = Signal() buffer_space_not_ack = Signal() - self.submodules += CrossDomainNotification("rtio_rx", "rtio", + self.submodules += CrossDomainNotification("rtio_rx", "sys", rx_buffer_space_not, rx_buffer_space, buffer_space_not, buffer_space_not_ack, self.cri.o_buffer_space) - timeout_counter = ClockDomainsRenamer("rtio")(WaitTimer(8191)) + timeout_counter = WaitTimer(8191) self.submodules += timeout_counter # Read @@ -163,7 +163,7 @@ class RTPacketRepeater(Module): rtio_read_is_overflow = Signal() rtio_read_data = Signal(32) rtio_read_timestamp = Signal(64) - self.submodules += CrossDomainNotification("rtio_rx", "rtio", + self.submodules += CrossDomainNotification("rtio_rx", "sys", read_not, Cat(read_no_event, read_is_overflow, read_data, read_timestamp), @@ -183,7 +183,7 @@ class RTPacketRepeater(Module): i_status_wait_event, i_status_overflow, cb0_loaded | cb_loaded)) load_read_reply = Signal() - self.sync.rtio += [ + self.sync += [ If(load_read_reply, i_status_wait_event.eq(0), i_status_overflow.eq(0), @@ -200,7 +200,7 @@ class RTPacketRepeater(Module): ] # TX and CRI FSM - tx_fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="IDLE")) + tx_fsm = FSM(reset_state="IDLE") self.submodules += tx_fsm tx_fsm.act("IDLE", diff --git a/artiq/gateware/drtio/rx_synchronizer.py b/artiq/gateware/drtio/rx_synchronizer.py index 90fddb97c..055d1d70b 100644 --- a/artiq/gateware/drtio/rx_synchronizer.py +++ b/artiq/gateware/drtio/rx_synchronizer.py @@ -17,7 +17,7 @@ class GenericRXSynchronizer(Module): return synchronized def do_finalize(self): - eb = ElasticBuffer(sum(len(s[0]) for s in self.signals), 4, "rtio_rx", "rtio") + eb = ElasticBuffer(sum(len(s[0]) for s in self.signals), 4, "rtio_rx", "sys") self.submodules += eb self.comb += [ eb.din.eq(Cat(*[s[0] for s in self.signals])), @@ -57,6 +57,6 @@ class XilinxRXSynchronizer(Module): self.specials += [ Instance("FD", i_C=ClockSignal("rtio_rx"), i_D=din[i], o_Q=inter[i], attr={hu_set, ("RLOC", "X0Y{}".format(i))}), - Instance("FD", i_C=ClockSignal("rtio"), i_D=inter[i], o_Q=dout[i], + Instance("FD", i_C=ClockSignal("sys"), i_D=inter[i], o_Q=dout[i], attr={hu_set, ("RLOC", "X1Y{}".format(i))}) ] diff --git a/artiq/gateware/drtio/siphaser.py b/artiq/gateware/drtio/siphaser.py index 5237b7453..c4054c127 100644 --- a/artiq/gateware/drtio/siphaser.py +++ b/artiq/gateware/drtio/siphaser.py @@ -1,23 +1,23 @@ from migen import * -from migen.genlib.cdc import MultiReg, PulseSynchronizer +from migen.genlib.cdc import MultiReg from misoc.interconnect.csr import * -# This code assumes 125/62.5MHz reference clock and 100MHz, 125MHz or 150MHz RTIO +# This code assumes 125/62.5MHz reference clock and 100MHz or 125MHz RTIO # frequency. class SiPhaser7Series(Module, AutoCSR): def __init__(self, si5324_clkin, rx_synchronizer, - ref_clk=None, ref_div2=False, ultrascale=False, rtio_clk_freq=150e6): + ref_clk=None, ref_div2=False, ultrascale=False, rtio_clk_freq=125e6): self.switch_clocks = CSRStorage() self.phase_shift = CSR() self.phase_shift_done = CSRStatus(reset=1) self.error = CSR() - assert rtio_clk_freq in (100e6, 125e6, 150e6) + assert rtio_clk_freq in (100e6, 125e6) - # 125MHz/62.5MHz reference clock to 100MHz/125MHz/150MHz. VCO @ 750MHz. + # 125MHz/62.5MHz reference clock to 100MHz/125MHz. VCO @ 750MHz. # Used to provide a startup clock to the transceiver through the Si, # we do not use the crystal reference so that the PFD (f3) frequency # can be high. @@ -97,17 +97,14 @@ class SiPhaser7Series(Module, AutoCSR): toggle_out = rx_synchronizer.resync(toggle_in) toggle_out_expected = Signal() - self.sync.rtio += toggle_out_expected.eq(~toggle_out) + self.sync += toggle_out_expected.eq(~toggle_out) error = Signal() - error_clear = PulseSynchronizer("sys", "rtio") - self.submodules += error_clear - self.sync.rtio += [ + self.sync += [ If(toggle_out != toggle_out_expected, error.eq(1)), - If(error_clear.o, error.eq(0)) + If(self.error.re, error.eq(0)) ] self.specials += MultiReg(error, self.error.w) - self.comb += error_clear.i.eq(self.error.re) # expose MMCM outputs - used for clock constraints self.mmcm_freerun_output = mmcm_freerun_output diff --git a/artiq/gateware/drtio/transceiver/clock_aligner.py b/artiq/gateware/drtio/transceiver/clock_aligner.py index 9d17d2b77..b0649a148 100644 --- a/artiq/gateware/drtio/transceiver/clock_aligner.py +++ b/artiq/gateware/drtio/transceiver/clock_aligner.py @@ -33,7 +33,7 @@ class BruteforceClockAligner(Module): check_counter = Signal(max=check_max_val+1) check = Signal() reset_check_counter = Signal() - self.sync.rtio_tx += [ + self.sync += [ check.eq(0), If(reset_check_counter, check_counter.eq(check_max_val) @@ -47,7 +47,7 @@ class BruteforceClockAligner(Module): ) ] - checks_reset = PulseSynchronizer("rtio_tx", "rtio_rx") + checks_reset = PulseSynchronizer("sys", "rtio_rx") self.submodules += checks_reset comma_n = ~comma & 0b1111111111 @@ -76,7 +76,7 @@ class BruteforceClockAligner(Module): ) ] - fsm = ClockDomainsRenamer("rtio_tx")(FSM(reset_state="WAIT_COMMA")) + fsm = FSM(reset_state="WAIT_COMMA") self.submodules += fsm fsm.act("WAIT_COMMA", diff --git a/artiq/gateware/drtio/transceiver/gtp_7series.py b/artiq/gateware/drtio/transceiver/gtp_7series.py index 5da42b22b..75c31a486 100644 --- a/artiq/gateware/drtio/transceiver/gtp_7series.py +++ b/artiq/gateware/drtio/transceiver/gtp_7series.py @@ -20,8 +20,7 @@ class GTPSingle(Module): self.stable_clkin = Signal() self.txenable = Signal() - self.submodules.encoder = encoder = ClockDomainsRenamer("rtio_tx")( - Encoder(2, True)) + self.submodules.encoder = encoder = Encoder(2, True) self.submodules.decoders = decoders = [ClockDomainsRenamer("rtio_rx")( (Decoder(True))) for _ in range(2)] self.rx_ready = Signal() @@ -33,10 +32,11 @@ class GTPSingle(Module): # # # - # TX generates RTIO clock, init must be in system domain - self.submodules.tx_init = tx_init = GTPTXInit(sys_clk_freq, mode) - # RX receives restart commands from RTIO domain - rx_init = ClockDomainsRenamer("rtio_tx")(GTPRXInit(rtio_clk_freq)) + # TX generates RTIO clock, init must be in bootstrap domain + self.submodules.tx_init = tx_init = ClockDomainsRenamer("bootstrap")( + GTPTXInit(125e6, mode)) + # RX receives restart commands from SYS domain + rx_init = GTPRXInit(rtio_clk_freq) self.submodules += rx_init self.comb += [ @@ -367,7 +367,7 @@ class GTPSingle(Module): # Channel - DRP Ports i_DRPADDR=rx_init.drpaddr, - i_DRPCLK=ClockSignal("rtio_tx"), + i_DRPCLK=ClockSignal("sys"), i_DRPDI=rx_init.drpdi, o_DRPDO=rx_init.drpdo, i_DRPEN=rx_init.drpen, @@ -566,8 +566,8 @@ class GTPSingle(Module): i_PMARSVDIN1 =0b0, # Transmit Ports - FPGA TX Interface Ports i_TXDATA =Cat(txdata[:8], txdata[10:18]), - i_TXUSRCLK =ClockSignal("rtio_tx"), - i_TXUSRCLK2 =ClockSignal("rtio_tx"), + i_TXUSRCLK =ClockSignal("sys"), + i_TXUSRCLK2 =ClockSignal("sys"), # Transmit Ports - PCI Express Ports i_TXELECIDLE =0, @@ -665,19 +665,10 @@ class GTPSingle(Module): raise ValueError self.specials += Instance("GTPE2_CHANNEL", **gtp_params) - # tx clocking - tx_reset_deglitched = Signal() - tx_reset_deglitched.attr.add("no_retiming") - self.sync += tx_reset_deglitched.eq(~tx_init.done) - self.clock_domains.cd_rtio_tx = ClockDomain() - if mode == "master" or mode == "single": - self.specials += Instance("BUFG", i_I=self.txoutclk, o_O=self.cd_rtio_tx.clk) - self.specials += AsyncResetSynchronizer(self.cd_rtio_tx, tx_reset_deglitched) - # rx clocking rx_reset_deglitched = Signal() rx_reset_deglitched.attr.add("no_retiming") - self.sync.rtio_tx += rx_reset_deglitched.eq(~rx_init.done) + self.sync += rx_reset_deglitched.eq(~rx_init.done) self.clock_domains.cd_rtio_rx = ClockDomain() self.specials += [ Instance("BUFG", i_I=self.rxoutclk, o_O=self.cd_rtio_rx.clk), @@ -727,7 +718,6 @@ class GTP(Module, TransceiverInterface): # # # - rtio_tx_clk = Signal() channel_interfaces = [] for i in range(nchannels): if nchannels == 1: @@ -735,10 +725,6 @@ class GTP(Module, TransceiverInterface): else: mode = "master" if i == master else "slave" gtp = GTPSingle(qpll_channel, data_pads[i], sys_clk_freq, rtio_clk_freq, mode) - if mode == "slave": - self.comb += gtp.cd_rtio_tx.clk.eq(rtio_tx_clk) - else: - self.comb += rtio_tx_clk.eq(gtp.cd_rtio_tx.clk) self.gtps.append(gtp) setattr(self.submodules, "gtp"+str(i), gtp) channel_interface = ChannelInterface(gtp.encoder, gtp.decoders) @@ -754,10 +740,6 @@ class GTP(Module, TransceiverInterface): gtp.txenable.eq(self.txenable.storage[n]) ] - self.comb += [ - self.cd_rtio.clk.eq(self.gtps[master].cd_rtio_tx.clk), - self.cd_rtio.rst.eq(reduce(or_, [gtp.cd_rtio_tx.rst for gtp in self.gtps])) - ] for i in range(nchannels): self.comb += [ getattr(self, "cd_rtio_rx" + str(i)).clk.eq(self.gtps[i].cd_rtio_rx.clk), diff --git a/artiq/gateware/drtio/wrpll/core.py b/artiq/gateware/drtio/wrpll/core.py index 52bc91ab7..3003d4848 100644 --- a/artiq/gateware/drtio/wrpll/core.py +++ b/artiq/gateware/drtio/wrpll/core.py @@ -9,7 +9,7 @@ from artiq.gateware.drtio.wrpll import thls, filters class FrequencyCounter(Module, AutoCSR): - def __init__(self, timer_width=23, counter_width=23, domains=["helper", "rtio", "rtio_rx0"]): + def __init__(self, timer_width=23, counter_width=23, domains=["helper", "sys", "rtio_rx0"]): for domain in domains: name = "counter_" + domain counter = CSRStatus(counter_width, name=name) diff --git a/artiq/gateware/rtio/phy/phaser.py b/artiq/gateware/rtio/phy/phaser.py index 94a5400d5..d4771d9ed 100644 --- a/artiq/gateware/rtio/phy/phaser.py +++ b/artiq/gateware/rtio/phy/phaser.py @@ -105,7 +105,7 @@ class MiqroChannel(Module): self.pulse.eq(pulse), self.rtlink.o.busy.eq(stb & ~self.ack), ] - self.sync.rtio += [ + self.sync += [ If(~stb, dt.eq(dt + 2), ), @@ -162,7 +162,7 @@ class Miqro(Module): ] re_dly = Signal(3) # stage, send, respond - self.sync.rtio += [ + self.sync += [ header.type.eq(3), # body type is miqro pulse data If(self.serializer.stb, header.we.eq(0), diff --git a/artiq/gateware/targets/kasli.py b/artiq/gateware/targets/kasli.py index f080b4fd0..9adfac0a2 100755 --- a/artiq/gateware/targets/kasli.py +++ b/artiq/gateware/targets/kasli.py @@ -17,7 +17,7 @@ from misoc.integration.builder import builder_args, builder_argdict from artiq.gateware.amp import AMPSoC from artiq.gateware import rtio from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, edge_counter -from artiq.gateware.rtio.xilinx_clocking import RTIOClockMultiplier, fix_serdes_timing_path +from artiq.gateware.rtio.xilinx_clocking import fix_serdes_timing_path from artiq.gateware import eem from artiq.gateware.drtio.transceiver import gtp_7series from artiq.gateware.drtio.siphaser import SiPhaser7Series @@ -76,6 +76,23 @@ class StandaloneBase(MiniSoC, AMPSoC): self.platform.request("error_led"))) self.csr_devices.append("error_led") self.submodules += SMAClkinForward(self.platform) + cdr_clk_out = self.platform.request("cdr_clk_clean") + else: + cdr_clk_out = self.platform.request("si5324_clkout") + + cdr_clk = Signal() + cdr_clk_buf = Signal() + self.platform.add_period_constraint(cdr_clk_out, 8.) + + self.specials += [ + Instance("IBUFDS_GTE2", + i_CEB=0, + i_I=cdr_clk_out.p, i_IB=cdr_clk_out.n, + o_O=cdr_clk), + Instance("BUFG", i_I=cdr_clk, o_O=cdr_clk_buf) + ] + + self.crg.configure(cdr_clk_buf) i2c = self.platform.request("i2c") self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda]) @@ -218,6 +235,8 @@ class MasterBase(MiniSoC, AMPSoC): integrated_sram_size=8192, ethmac_nrxslots=4, ethmac_ntxslots=4, + clk_freq=rtio_clk_freq, + rtio_sys_merge=True, **kwargs) AMPSoC.__init__(self) add_identifier(self, gateware_identifier_str=gateware_identifier_str) @@ -256,8 +275,6 @@ class MasterBase(MiniSoC, AMPSoC): sys_clk_freq=self.clk_freq, rtio_clk_freq=rtio_clk_freq) self.csr_devices.append("drtio_transceiver") - self.sync += self.disable_cdr_clk_ibuf.eq( - ~self.drtio_transceiver.stable_clkin.storage) if enable_sata: sfp_channels = self.drtio_transceiver.channels[1:] @@ -307,8 +324,14 @@ class MasterBase(MiniSoC, AMPSoC): rtio_clk_period = 1e9/rtio_clk_freq gtp = self.drtio_transceiver.gtps[0] + + txout_buf = Signal() + self.specials += Instance("BUFG", i_I=gtp.txoutclk, o_O=txout_buf) + self.crg.configure(txout_buf, clk_sw=gtp.tx_init.done) + platform.add_period_constraint(gtp.txoutclk, rtio_clk_period) platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period) + platform.add_false_path_constraints( self.crg.cd_sys.clk, gtp.txoutclk, gtp.rxoutclk) @@ -317,8 +340,6 @@ class MasterBase(MiniSoC, AMPSoC): platform.add_false_path_constraints( self.crg.cd_sys.clk, gtp.rxoutclk) - self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq) - self.csr_devices.append("rtio_crg") fix_serdes_timing_path(platform) def add_rtio(self, rtio_channels, sed_lanes=8): @@ -350,19 +371,18 @@ class MasterBase(MiniSoC, AMPSoC): # Never running out of stupid features, GTs on A7 make you pack # unrelated transceiver PLLs into one GTPE2_COMMON yourself. def create_qpll(self): - # The GTP acts up if you send any glitch to its - # clock input, even while the PLL is held in reset. - self.disable_cdr_clk_ibuf = Signal(reset=1) - self.disable_cdr_clk_ibuf.attr.add("no_retiming") if self.platform.hw_rev == "v2.0": - cdr_clk_clean = self.platform.request("cdr_clk_clean") + cdr_clk_out = self.platform.request("cdr_clk_clean") else: - cdr_clk_clean = self.platform.request("si5324_clkout") - cdr_clk_clean_buf = Signal() + cdr_clk_out = self.platform.request("si5324_clkout") + + cdr_clk = Signal() + self.platform.add_period_constraint(cdr_clk_out, 8.) + self.specials += Instance("IBUFDS_GTE2", - i_CEB=self.disable_cdr_clk_ibuf, - i_I=cdr_clk_clean.p, i_IB=cdr_clk_clean.n, - o_O=cdr_clk_clean_buf) + i_CEB=0, + i_I=cdr_clk_out.p, i_IB=cdr_clk_out.n, + o_O=cdr_clk) # Note precisely the rules Xilinx made up: # refclksel=0b001 GTREFCLK0 selected # refclksel=0b010 GTREFCLK1 selected @@ -377,7 +397,8 @@ class MasterBase(MiniSoC, AMPSoC): fbdiv=4, fbdiv_45=5, refclk_div=1) - qpll = QPLL(cdr_clk_clean_buf, qpll_drtio_settings, + + qpll = QPLL(cdr_clk, qpll_drtio_settings, self.crg.clk125_buf, qpll_eth_settings) self.submodules += qpll self.drtio_qpll_channel, self.ethphy_qpll_channel = qpll.channels @@ -400,6 +421,8 @@ class SatelliteBase(BaseSoC): cpu_bus_width=cpu_bus_width, sdram_controller_type="minicon", l2_size=128*1024, + clk_freq=rtio_clk_freq, + rtio_sys_merge=True, **kwargs) add_identifier(self, gateware_identifier_str=gateware_identifier_str) @@ -410,23 +433,24 @@ class SatelliteBase(BaseSoC): self.platform.request("error_led"))) self.csr_devices.append("error_led") - disable_cdr_clk_ibuf = Signal(reset=1) - disable_cdr_clk_ibuf.attr.add("no_retiming") if self.platform.hw_rev == "v2.0": - cdr_clk_clean = self.platform.request("cdr_clk_clean") + cdr_clk_out = self.platform.request("cdr_clk_clean") else: - cdr_clk_clean = self.platform.request("si5324_clkout") - cdr_clk_clean_buf = Signal() + cdr_clk_out = self.platform.request("si5324_clkout") + + cdr_clk = Signal() + self.platform.add_period_constraint(cdr_clk_out, 8.) + self.specials += Instance("IBUFDS_GTE2", - i_CEB=disable_cdr_clk_ibuf, - i_I=cdr_clk_clean.p, i_IB=cdr_clk_clean.n, - o_O=cdr_clk_clean_buf) + i_CEB=0, + i_I=cdr_clk_out.p, i_IB=cdr_clk_out.n, + o_O=cdr_clk) qpll_drtio_settings = QPLLSettings( refclksel=0b001, fbdiv=4, fbdiv_45=5, refclk_div=1) - qpll = QPLL(cdr_clk_clean_buf, qpll_drtio_settings) + qpll = QPLL(cdr_clk, qpll_drtio_settings) self.submodules += qpll drtio_data_pads = [] @@ -445,8 +469,6 @@ class SatelliteBase(BaseSoC): sys_clk_freq=self.clk_freq, rtio_clk_freq=rtio_clk_freq) self.csr_devices.append("drtio_transceiver") - self.sync += disable_cdr_clk_ibuf.eq( - ~self.drtio_transceiver.stable_clkin.storage) if enable_sata: sfp_channels = self.drtio_transceiver.channels[1:] @@ -542,6 +564,10 @@ class SatelliteBase(BaseSoC): self.config["SI5324_SOFT_RESET"] = None gtp = self.drtio_transceiver.gtps[0] + txout_buf = Signal() + self.specials += Instance("BUFG", i_I=gtp.txoutclk, o_O=txout_buf) + self.crg.configure(txout_buf, clk_sw=gtp.tx_init.done) + platform.add_period_constraint(gtp.txoutclk, rtio_clk_period) platform.add_period_constraint(gtp.rxoutclk, rtio_clk_period) platform.add_false_path_constraints( @@ -555,8 +581,6 @@ class SatelliteBase(BaseSoC): platform.add_false_path_constraints( self.crg.cd_sys.clk, gtp.rxoutclk) - self.submodules.rtio_crg = RTIOClockMultiplier(rtio_clk_freq) - self.csr_devices.append("rtio_crg") fix_serdes_timing_path(platform) def add_rtio(self, rtio_channels, sed_lanes=8): diff --git a/artiq/gateware/test/drtio/test_aux_controller.py b/artiq/gateware/test/drtio/test_aux_controller.py index 68c9f3bbd..6c65307ed 100644 --- a/artiq/gateware/test/drtio/test_aux_controller.py +++ b/artiq/gateware/test/drtio/test_aux_controller.py @@ -36,7 +36,7 @@ class TB(Module): def __init__(self, nwords, dw): self.submodules.link_layer = Loopback(nwords) self.submodules.aux_controller = ClockDomainsRenamer( - {"rtio": "sys", "rtio_rx": "sys"})(DRTIOAuxController(self.link_layer, dw)) + {"rtio_rx": "sys"})(DRTIOAuxController(self.link_layer, dw)) class TestAuxController(unittest.TestCase): diff --git a/artiq/gateware/test/drtio/test_full_stack.py b/artiq/gateware/test/drtio/test_full_stack.py index 02535b7e6..7cafe16a1 100644 --- a/artiq/gateware/test/drtio/test_full_stack.py +++ b/artiq/gateware/test/drtio/test_full_stack.py @@ -144,7 +144,7 @@ class OutputsTestbench: class TestFullStack(unittest.TestCase): - clocks = {"sys": 8, "rtio": 5, "rtio_rx": 5, + clocks = {"sys": 8, "rtio_rx": 5, "rio": 5, "rio_phy": 5} def test_pulses(self): @@ -169,7 +169,7 @@ class TestFullStack(unittest.TestCase): yield from tb.sync() run_simulation(tb.dut, - {"sys": test(), "rtio": tb.check_ttls(ttl_changes)}, self.clocks) + {"sys": test()}, self.clocks) self.assertEqual(ttl_changes, correct_ttl_changes) def test_underflow(self): @@ -214,7 +214,7 @@ class TestFullStack(unittest.TestCase): yield from tb.sync() run_simulation(tb.dut, - {"sys": test(), "rtio": tb.check_ttls(ttl_changes)}, self.clocks) + {"sys": test()}, self.clocks) self.assertEqual(ttl_changes, correct_ttl_changes) def test_write_underflow(self): @@ -284,7 +284,7 @@ class TestFullStack(unittest.TestCase): yield dut.phy2.rtlink.i.stb.eq(0) run_simulation(dut, - {"sys": test(), "rtio": generate_input()}, self.clocks) + {"sys": test()}, self.clocks) def test_echo(self): dut = DUT(2) diff --git a/artiq/gateware/test/drtio/test_rt_packet_repeater.py b/artiq/gateware/test/drtio/test_rt_packet_repeater.py index 9c73af625..21a28ae47 100644 --- a/artiq/gateware/test/drtio/test_rt_packet_repeater.py +++ b/artiq/gateware/test/drtio/test_rt_packet_repeater.py @@ -12,7 +12,7 @@ def create_dut(nwords): pt = PacketInterface("s2m", nwords*8) pr = PacketInterface("m2s", nwords*8) ts = Signal(64) - dut = ClockDomainsRenamer({"rtio": "sys", "rtio_rx": "sys"})( + dut = ClockDomainsRenamer({"rtio_rx": "sys"})( RTPacketRepeater( SimpleNamespace(coarse_ts=ts), SimpleNamespace( diff --git a/artiq/gateware/test/drtio/test_switching.py b/artiq/gateware/test/drtio/test_switching.py index dddfb9bd2..1f7876ade 100644 --- a/artiq/gateware/test/drtio/test_switching.py +++ b/artiq/gateware/test/drtio/test_switching.py @@ -130,7 +130,7 @@ class Testbench: class TestSwitching(unittest.TestCase): - clocks = {"sys": 8, "rtio": 5, "rtio_rx": 5, + clocks = {"sys": 8, "rtio_rx": 5, "rio": 5, "rio_phy": 5} def test_outputs(self): @@ -183,7 +183,7 @@ class TestSwitching(unittest.TestCase): current_request = (packet_type, field_dict, trailer) run_simulation(tb.dut, - {"sys": test(), "rtio": tb.dut.pr.receive(receive), "rtio_rx": send_replies()}, self.clocks) + {"sys": test(), "sys": tb.dut.pr.receive(receive), "rtio_rx": send_replies()}, self.clocks) def test_inputs(self): @@ -244,4 +244,4 @@ class TestSwitching(unittest.TestCase): current_request = (packet_type, field_dict, trailer) run_simulation(tb.dut, - {"sys": test(), "rtio": tb.dut.pr.receive(receive), "rtio_rx": send_replies()}, self.clocks) + {"sys": test(), "sys": tb.dut.pr.receive(receive), "rtio_rx": send_replies()}, self.clocks)