Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: bb047aabe996
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4d07974a3409
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Nov 18, 2016

  1. Copy the full SHA
    f040e27 View commit details
  2. Copy the full SHA
    4d07974 View commit details
Showing with 59 additions and 30 deletions.
  1. +24 −17 artiq/gateware/drtio/link_layer.py
  2. +20 −5 artiq/gateware/drtio/rt_controller.py
  3. +15 −8 artiq/runtime.rs/src/drtio.rs
41 changes: 24 additions & 17 deletions artiq/gateware/drtio/link_layer.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

from migen import *
from migen.genlib.fsm import *
from migen.genlib.cdc import MultiReg
from migen.genlib.cdc import MultiReg, PulseSynchronizer
from migen.genlib.misc import WaitTimer

from misoc.interconnect.csr import *
@@ -223,10 +223,8 @@ def __init__(self, decoders):
class LinkLayer(Module, AutoCSR):
def __init__(self, encoder, decoders):
self.link_status = CSRStatus()
self.link_reset = CSR()

# control signals, in rtio clock domain
self.reset = Signal()
self.ready = Signal()
# pulsed to reset receiver, rx_ready must immediately go low
self.rx_reset = Signal()
# receiver locked including comma alignment
@@ -252,37 +250,46 @@ def __init__(self, encoder, decoders):

# # #

ready_r = Signal()
ready = Signal()
reset_ps = PulseSynchronizer("sys", "rtio")
done_ps = PulseSynchronizer("rtio", "sys")
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()
self.sync.rtio += ready_r.eq(self.ready)
ready_r.attr.add("no_retiming")
self.specials += MultiReg(ready_r, ready_rx, "rtio_rx")
ready.attr.add("no_retiming")
self.specials += MultiReg(ready, ready_rx, "rtio_rx")
self.comb += [
self.rx_aux_frame.eq(rx.aux_frame & ready_rx),
self.rx_rt_frame.eq(rx.rt_frame & ready_rx),
]
self.specials += MultiReg(ready_r, self.link_status.status)

wait_scrambler = WaitTimer(15)
wait_scrambler = ClockDomainsRenamer("rtio")(WaitTimer(15))
self.submodules += wait_scrambler

fsm = ClockDomainsRenamer("rtio")(
ResetInserter()(FSM(reset_state="RESET_RX")))
fsm = ClockDomainsRenamer("rtio")(FSM(reset_state="RESET_RX"))
self.submodules += fsm

self.comb += fsm.reset.eq(self.reset)

fsm.act("RESET_RX",
self.rx_reset.eq(1),
NextState("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",
wait_scrambler.wait.eq(1),
If(wait_scrambler.done, NextState("READY")),
If(wait_scrambler.done,
done_ps.i.eq(1),
NextState("READY")
),
)
fsm.act("READY",
self.ready.eq(1)
If(reset_ps.o, NextState("RESET_RX"))
)
25 changes: 20 additions & 5 deletions artiq/gateware/drtio/rt_controller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from migen import *
from migen.genlib.cdc import MultiReg
from migen.genlib.misc import WaitTimer

from misoc.interconnect.csr import *

@@ -21,6 +22,7 @@ def __init__(self):
self.o_dbg_last_timestamp = CSRStatus(64)
self.o_reset_channel_status = CSR()
self.o_wait = CSRStatus()
self.o_fifo_space_timeout = CSR()


class RTController(Module):
@@ -96,6 +98,14 @@ def __init__(self, rt_packets, channel_count, fine_ts_width):
If(sequence_error_set, status_sequence_error.eq(1)),
]

signal_fifo_space_timeout = Signal()
self.sync += [
If(self.csrs.o_fifo_space_timeout.re, self.csrs.o_fifo_space_timeout.w.eq(0)),
If(signal_fifo_space_timeout, self.csrs.o_fifo_space_timeout.w.eq(1))
]
timeout_counter = WaitTimer(8191)
self.submodules += timeout_counter

# TODO: collision, replace, busy
cond_sequence_error = self.kcsrs.o_timestamp.storage < last_timestamps.dat_r
cond_underflow = ((self.kcsrs.o_timestamp.storage[fine_ts_width:]
@@ -154,6 +164,11 @@ def __init__(self, rt_packets, channel_count, fine_ts_width):
).Else(
NextState("GET_FIFO_SPACE")
)
),
timeout_counter.wait.eq(1),
If(timeout_counter.done,
signal_fifo_space_timeout.eq(1),
NextState("IDLE")
)
)

@@ -180,8 +195,8 @@ class RTManager(Module, AutoCSR):
def __init__(self, rt_packets):
self.request_echo = CSR()

self.err_present = CSR()
self.err_code = CSRStatus(8)
self.packet_err_present = CSR()
self.packet_err_code = CSRStatus(8)

self.update_packet_cnt = CSR()
self.packet_cnt_tx = CSRStatus(32)
@@ -196,9 +211,9 @@ def __init__(self, rt_packets):
]

self.comb += [
self.err_present.w.eq(rt_packets.error_not),
rt_packets.error_not_ack.eq(self.err_present.re),
self.err_code.status.eq(rt_packets.error_code)
self.packet_err_present.w.eq(rt_packets.error_not),
rt_packets.error_not_ack.eq(self.packet_err_present.re),
self.packet_err_code.status.eq(rt_packets.error_code)
]

self.sync += \
23 changes: 15 additions & 8 deletions artiq/runtime.rs/src/drtio.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,12 @@ fn drtio_link_is_up() -> bool {
}
}

fn drtio_reset_link() {
unsafe {
csr::drtio::link_reset_write(1)
}
}

fn drtio_sync_tsc() {
unsafe {
csr::drtio::set_time_write(1);
@@ -33,7 +39,7 @@ pub fn link_thread(waiter: Waiter, _spawner: Spawner) {
waiter.until(drtio_link_is_up).unwrap();
info!("link RX is up");

waiter.sleep(300);
waiter.sleep(300).unwrap();
info!("wait for remote side done");

drtio_sync_tsc();
@@ -48,23 +54,24 @@ pub fn link_thread(waiter: Waiter, _spawner: Spawner) {
}
}

fn drtio_error_present() -> bool {
fn drtio_packet_error_present() -> bool {
unsafe {
csr::drtio::err_present_read() != 0
csr::drtio::packet_err_present_read() != 0
}
}

fn drtio_get_error() -> u8 {
fn drtio_get_packet_error() -> u8 {
unsafe {
let err = csr::drtio::err_code_read();
csr::drtio::err_present_write(1);
let err = csr::drtio::packet_err_code_read();
csr::drtio::packet_err_present_write(1);
err
}
}

pub fn error_thread(waiter: Waiter, _spawner: Spawner) {
loop {
waiter.until(drtio_error_present).unwrap();
error!("DRTIO error {}", drtio_get_error());
waiter.until(drtio_packet_error_present).unwrap();
error!("DRTIO packet error {}", drtio_get_packet_error());
drtio_reset_link();
}
}