forked from M-Labs/artiq
drtio: implement per-destination underflow margins
This commit is contained in:
parent
62642957cd
commit
142c952e3d
|
@ -30,6 +30,18 @@ impl RoutingTable {
|
||||||
pub fn default_empty() -> RoutingTable {
|
pub fn default_empty() -> RoutingTable {
|
||||||
RoutingTable([[INVALID_HOP; MAX_HOPS]; DEST_COUNT])
|
RoutingTable([[INVALID_HOP; MAX_HOPS]; DEST_COUNT])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hop_count(&self, destination: u8) -> u8 {
|
||||||
|
let mut count = 0;
|
||||||
|
for i in 0..MAX_HOPS {
|
||||||
|
if self.0[destination as usize][i] == INVALID_HOP {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for RoutingTable {
|
impl fmt::Display for RoutingTable {
|
||||||
|
|
|
@ -54,6 +54,12 @@ pub mod drtio {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio_transceiver::stable_clkin_write(1);
|
csr::drtio_transceiver::stable_clkin_write(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let routing_table = routing_table.borrow();
|
||||||
|
program_underflow_margins(&routing_table);
|
||||||
|
}
|
||||||
|
|
||||||
let aux_mutex = aux_mutex.clone();
|
let aux_mutex = aux_mutex.clone();
|
||||||
let routing_table = routing_table.clone();
|
let routing_table = routing_table.clone();
|
||||||
let up_destinations = up_destinations.clone();
|
let up_destinations = up_destinations.clone();
|
||||||
|
@ -63,6 +69,23 @@ pub mod drtio {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn program_underflow_margins(routing_table: &drtio_routing::RoutingTable) {
|
||||||
|
for destination in 0..drtio_routing::DEST_COUNT {
|
||||||
|
let hop_count = routing_table.hop_count(destination as u8);
|
||||||
|
if hop_count > 1 {
|
||||||
|
let underflow_margin = (hop_count as u16 - 1)*300;
|
||||||
|
info!("[DEST#{}] setting underflow margin to {}", destination, underflow_margin);
|
||||||
|
let linkno = (routing_table.0[destination][0] - 1) as usize;
|
||||||
|
unsafe {
|
||||||
|
(csr::DRTIO[linkno].destination_write)(destination as u8);
|
||||||
|
(csr::DRTIO[linkno].force_destination_write)(1);
|
||||||
|
(csr::DRTIO[linkno].set_underflow_margin_write)(underflow_margin);
|
||||||
|
(csr::DRTIO[linkno].force_destination_write)(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn link_rx_up(linkno: u8) -> bool {
|
fn link_rx_up(linkno: u8) -> bool {
|
||||||
let linkno = linkno as usize;
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -17,11 +17,13 @@ class _CSRs(AutoCSR):
|
||||||
self.protocol_error = CSR(3)
|
self.protocol_error = CSR(3)
|
||||||
|
|
||||||
self.set_time = CSR()
|
self.set_time = CSR()
|
||||||
self.underflow_margin = CSRStorage(16, reset=300)
|
|
||||||
|
|
||||||
self.force_destination = CSRStorage()
|
self.force_destination = CSRStorage()
|
||||||
self.destination = CSRStorage(8)
|
self.destination = CSRStorage(8)
|
||||||
|
|
||||||
|
self.set_underflow_margin = CSRStorage(16)
|
||||||
|
self.dbg_underflow_margin = CSRStatus(16)
|
||||||
|
|
||||||
self.o_get_buffer_space = CSR()
|
self.o_get_buffer_space = CSR()
|
||||||
self.o_dbg_buffer_space = CSRStatus(16)
|
self.o_dbg_buffer_space = CSRStatus(16)
|
||||||
self.o_dbg_buffer_space_req_cnt = CSRStatus(32)
|
self.o_dbg_buffer_space_req_cnt = CSRStatus(32)
|
||||||
|
@ -116,9 +118,19 @@ class RTController(Module):
|
||||||
timeout_counter = WaitTimer(8191)
|
timeout_counter = WaitTimer(8191)
|
||||||
self.submodules += timeout_counter
|
self.submodules += timeout_counter
|
||||||
|
|
||||||
|
underflow_margin = Memory(16, 256, init=[100]*256)
|
||||||
|
underflow_margin_port = underflow_margin.get_port(write_capable=True)
|
||||||
|
self.specials += underflow_margin, underflow_margin_port
|
||||||
|
self.comb += [
|
||||||
|
underflow_margin_port.adr.eq(chan_sel[16:]),
|
||||||
|
underflow_margin_port.dat_w.eq(self.csrs.set_underflow_margin.storage),
|
||||||
|
underflow_margin_port.we.eq(self.csrs.set_underflow_margin.re),
|
||||||
|
self.csrs.dbg_underflow_margin.status.eq(underflow_margin_port.dat_r)
|
||||||
|
]
|
||||||
|
|
||||||
cond_underflow = Signal()
|
cond_underflow = Signal()
|
||||||
self.comb += cond_underflow.eq((self.cri.timestamp[tsc.glbl_fine_ts_width:]
|
self.comb += cond_underflow.eq((self.cri.timestamp[tsc.glbl_fine_ts_width:]
|
||||||
- self.csrs.underflow_margin.storage[tsc.glbl_fine_ts_width:]) < tsc.coarse_ts_sys)
|
- underflow_margin_port.dat_r[tsc.glbl_fine_ts_width:]) < tsc.coarse_ts_sys)
|
||||||
|
|
||||||
# buffer space
|
# buffer space
|
||||||
buffer_space = Memory(16, 256)
|
buffer_space = Memory(16, 256)
|
||||||
|
|
|
@ -89,7 +89,6 @@ class OutputsTestbench:
|
||||||
self.now = 0
|
self.now = 0
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
yield from self.dut.master.rt_controller.csrs.underflow_margin.write(100)
|
|
||||||
while not (yield from self.dut.master.link_layer.rx_up.read()):
|
while not (yield from self.dut.master.link_layer.rx_up.read()):
|
||||||
yield
|
yield
|
||||||
yield from self.get_buffer_space()
|
yield from self.get_buffer_space()
|
||||||
|
@ -228,7 +227,7 @@ class TestFullStack(unittest.TestCase):
|
||||||
yield from tb.init()
|
yield from tb.init()
|
||||||
errors = yield from saterr.protocol_error.read()
|
errors = yield from saterr.protocol_error.read()
|
||||||
self.assertEqual(errors, 0)
|
self.assertEqual(errors, 0)
|
||||||
yield from csrs.underflow_margin.write(0)
|
yield from csrs.set_underflow_margin.write(0)
|
||||||
tb.delay(100)
|
tb.delay(100)
|
||||||
yield from tb.write(42, 1)
|
yield from tb.write(42, 1)
|
||||||
for i in range(12):
|
for i in range(12):
|
||||||
|
|
|
@ -70,7 +70,6 @@ class Testbench:
|
||||||
self.now = 0
|
self.now = 0
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
yield from self.dut.master.rt_controller.csrs.underflow_margin.write(100)
|
|
||||||
while not (yield from self.dut.master.link_layer.rx_up.read()):
|
while not (yield from self.dut.master.link_layer.rx_up.read()):
|
||||||
yield
|
yield
|
||||||
yield from self.get_buffer_space()
|
yield from self.get_buffer_space()
|
||||||
|
|
Loading…
Reference in New Issue