drtio: implement per-destination buffer space

This commit is contained in:
Sebastien Bourdeauducq 2018-09-13 16:16:32 +08:00
parent e95638e0a7
commit 1ef39a98a7
2 changed files with 44 additions and 18 deletions

View File

@ -83,16 +83,6 @@ pub mod drtio {
} }
} }
fn init_buffer_space(linkno: u8) {
let linkidx = linkno as usize;
unsafe {
(csr::DRTIO[linkidx].o_get_buffer_space_write)(1);
while (csr::DRTIO[linkidx].o_wait_read)() == 1 {}
info!("[LINK#{}] buffer space is {}",
linkno, (csr::DRTIO[linkidx].o_dbg_buffer_space_read)());
}
}
fn ping_remote(linkno: u8, io: &Io) -> u32 { fn ping_remote(linkno: u8, io: &Io) -> u32 {
let mut count = 0; let mut count = 0;
loop { loop {
@ -172,6 +162,19 @@ pub mod drtio {
Ok(()) Ok(())
} }
fn init_buffer_space(destination: u8, linkno: u8) {
let linkno = linkno as usize;
unsafe {
(csr::DRTIO[linkno].destination_write)(destination);
(csr::DRTIO[linkno].force_destination_write)(1);
(csr::DRTIO[linkno].o_get_buffer_space_write)(1);
while (csr::DRTIO[linkno].o_wait_read)() == 1 {}
info!("[DEST#{}] buffer space is {}",
destination, (csr::DRTIO[linkno].o_dbg_buffer_space_read)());
(csr::DRTIO[linkno].force_destination_write)(0);
}
}
fn process_unsolicited_aux(linkno: u8) { fn process_unsolicited_aux(linkno: u8) {
match drtioaux::recv_link(linkno) { match drtioaux::recv_link(linkno) {
Ok(Some(packet)) => warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet), Ok(Some(packet)) => warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet),
@ -248,7 +251,7 @@ pub mod drtio {
Ok(drtioaux::Packet::DestinationOkReply) => { Ok(drtioaux::Packet::DestinationOkReply) => {
info!("[DEST#{}] destination is up", destination); info!("[DEST#{}] destination is up", destination);
up_destinations[destination] = true; up_destinations[destination] = true;
/* TODO: get buffer space */ init_buffer_space(destination as u8, linkno);
}, },
Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet), Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet),
Err(e) => error!("[DEST#{}] communication failed ({})", destination, e) Err(e) => error!("[DEST#{}] communication failed ({})", destination, e)
@ -281,7 +284,6 @@ pub mod drtio {
if ping_count > 0 { if ping_count > 0 {
info!("[LINK#{}] remote replied after {} packets", linkno, ping_count); info!("[LINK#{}] remote replied after {} packets", linkno, ping_count);
set_link_up(linkno, true); set_link_up(linkno, true);
init_buffer_space(linkno);
if let Err(e) = sync_tsc(&io, linkno) { if let Err(e) = sync_tsc(&io, linkno) {
error!("[LINK#{}] failed to sync TSC ({})", linkno, e); error!("[LINK#{}] failed to sync TSC ({})", linkno, e);
} }

View File

@ -19,6 +19,9 @@ class _CSRs(AutoCSR):
self.set_time = CSR() self.set_time = CSR()
self.underflow_margin = CSRStorage(16, reset=300) self.underflow_margin = CSRStorage(16, reset=300)
self.force_destination = CSRStorage()
self.destination = CSRStorage(8)
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)
@ -71,11 +74,17 @@ class RTController(Module):
If(self.csrs.set_time.re, rt_packet.set_time_stb.eq(1)) If(self.csrs.set_time.re, rt_packet.set_time_stb.eq(1))
] ]
# chan_sel forcing
chan_sel = Signal(24)
self.comb += chan_sel.eq(Mux(self.csrs.force_destination.storage,
self.csrs.destination.storage << 16,
self.cri.chan_sel))
# common packet fields # common packet fields
rt_packet_buffer_request = Signal() rt_packet_buffer_request = Signal()
rt_packet_read_request = Signal() rt_packet_read_request = Signal()
self.comb += [ self.comb += [
rt_packet.sr_chan_sel.eq(self.cri.chan_sel), rt_packet.sr_chan_sel.eq(chan_sel),
rt_packet.sr_address.eq(self.cri.o_address), rt_packet.sr_address.eq(self.cri.o_address),
rt_packet.sr_data.eq(self.cri.o_data), rt_packet.sr_data.eq(self.cri.o_data),
rt_packet.sr_timestamp.eq(self.cri.timestamp), rt_packet.sr_timestamp.eq(self.cri.timestamp),
@ -112,7 +121,22 @@ class RTController(Module):
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) - self.csrs.underflow_margin.storage[tsc.glbl_fine_ts_width:]) < tsc.coarse_ts_sys)
buffer_space = Signal(16) # buffer space
buffer_space = Memory(16, 256)
buffer_space_port = buffer_space.get_port(write_capable=True)
self.specials += buffer_space, buffer_space_port
buffer_space_load = Signal()
buffer_space_dec = Signal()
self.comb += [
buffer_space_port.adr.eq(chan_sel[16:]),
buffer_space_port.we.eq(buffer_space_load | buffer_space_dec),
If(buffer_space_load,
buffer_space_port.dat_w.eq(rt_packet.buffer_space)
).Else(
buffer_space_port.dat_w.eq(buffer_space_port.dat_r - 1)
)
]
# input status # input status
i_status_wait_event = Signal() i_status_wait_event = Signal()
@ -158,8 +182,8 @@ class RTController(Module):
o_status_wait.eq(1), o_status_wait.eq(1),
rt_packet.sr_stb.eq(1), rt_packet.sr_stb.eq(1),
If(rt_packet.sr_ack, If(rt_packet.sr_ack,
NextValue(buffer_space, buffer_space - 1), buffer_space_dec.eq(1),
If(buffer_space <= 1, If(buffer_space_port.dat_r <= 1,
NextState("GET_BUFFER_SPACE") NextState("GET_BUFFER_SPACE")
).Else( ).Else(
NextState("IDLE") NextState("IDLE")
@ -177,7 +201,7 @@ class RTController(Module):
) )
fsm.act("GET_BUFFER_SPACE_REPLY", fsm.act("GET_BUFFER_SPACE_REPLY",
o_status_wait.eq(1), o_status_wait.eq(1),
NextValue(buffer_space, rt_packet.buffer_space), buffer_space_load.eq(1),
rt_packet.buffer_space_not_ack.eq(1), rt_packet.buffer_space_not_ack.eq(1),
If(rt_packet.buffer_space_not, If(rt_packet.buffer_space_not,
If(rt_packet.buffer_space != 0, If(rt_packet.buffer_space != 0,
@ -211,7 +235,7 @@ class RTController(Module):
) )
# debug CSRs # debug CSRs
self.comb += self.csrs.o_dbg_buffer_space.status.eq(buffer_space), self.comb += self.csrs.o_dbg_buffer_space.status.eq(buffer_space_port.dat_r),
self.sync += \ self.sync += \
If((rt_packet.sr_stb & rt_packet.sr_ack & rt_packet_buffer_request), If((rt_packet.sr_stb & rt_packet.sr_ack & rt_packet_buffer_request),
self.csrs.o_dbg_buffer_space_req_cnt.status.eq( self.csrs.o_dbg_buffer_space_req_cnt.status.eq(