allow toggling SED spread with flash config key

This commit is contained in:
mwojcik 2024-07-09 11:30:10 +08:00 committed by Sebastien Bourdeauducq
parent 05d02f3f00
commit 60b1edaf6b
10 changed files with 76 additions and 21 deletions

View File

@ -710,11 +710,30 @@ fn read_device_map() -> DeviceMap {
device_map device_map
} }
fn toggle_sed_spread(val: u8) {
unsafe { csr::rtio_core::sed_spread_enable_write(val); }
}
fn setup_sed_spread() {
config::read_str("sed_spread_enable", |r| {
match r {
Ok("1") => { info!("SED spreading enabled"); toggle_sed_spread(1); },
Ok("0") => { info!("SED spreading disabled"); toggle_sed_spread(0); },
Ok(_) => {
warn!("sed_spread_enable value not supported (only 1, 0 allowed), disabling by default");
toggle_sed_spread(0);
},
Err(_) => { info!("SED spreading disabled by default"); toggle_sed_spread(0) },
}
});
}
pub fn startup(io: &Io, aux_mutex: &Mutex, pub fn startup(io: &Io, aux_mutex: &Mutex,
routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>,
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>, up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
ddma_mutex: &Mutex, subkernel_mutex: &Mutex) { ddma_mutex: &Mutex, subkernel_mutex: &Mutex) {
set_device_map(read_device_map()); set_device_map(read_device_map());
setup_sed_spread();
drtio::startup(io, aux_mutex, routing_table, up_destinations, ddma_mutex, subkernel_mutex); drtio::startup(io, aux_mutex, routing_table, up_destinations, ddma_mutex, subkernel_mutex);
unsafe { unsafe {
csr::rtio_core::reset_phy_write(1); csr::rtio_core::reset_phy_write(1);

View File

@ -14,7 +14,7 @@ extern crate io;
extern crate eh; extern crate eh;
use core::convert::TryFrom; use core::convert::TryFrom;
use board_misoc::{csr, ident, clock, uart_logger, i2c, pmp}; use board_misoc::{csr, ident, clock, config, uart_logger, i2c, pmp};
#[cfg(has_si5324)] #[cfg(has_si5324)]
use board_artiq::si5324; use board_artiq::si5324;
#[cfg(has_si549)] #[cfg(has_si549)]
@ -70,6 +70,10 @@ fn drtiosat_tsc_loaded() -> bool {
} }
} }
fn toggle_sed_spread(val: u8) {
unsafe { csr::drtiosat::sed_spread_enable_write(val); }
}
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum RtioMaster { pub enum RtioMaster {
Drtio, Drtio,
@ -754,6 +758,18 @@ pub extern fn main() -> i32 {
init_rtio_crg(); init_rtio_crg();
config::read_str("sed_spread_enable", |r| {
match r {
Ok("1") => { info!("SED spreading enabled"); toggle_sed_spread(1); },
Ok("0") => { info!("SED spreading disabled"); toggle_sed_spread(0); },
Ok(_) => {
warn!("sed_spread_enable value not supported (only 1, 0 allowed), disabling by default");
toggle_sed_spread(0);
},
Err(_) => { info!("SED spreading disabled by default"); toggle_sed_spread(0) },
}
});
#[cfg(has_drtio_eem)] #[cfg(has_drtio_eem)]
drtio_eem::init(); drtio_eem::init();

View File

@ -1,6 +1,7 @@
from types import SimpleNamespace from types import SimpleNamespace
from migen import * from migen import *
from migen.genlib.cdc import MultiReg
from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.resetsync import AsyncResetSynchronizer
from misoc.interconnect.csr import * from misoc.interconnect.csr import *
@ -51,6 +52,7 @@ class SyncRTIO(Module):
def __init__(self, tsc, channels, lane_count=8, fifo_depth=128): def __init__(self, tsc, channels, lane_count=8, fifo_depth=128):
self.cri = cri.Interface() self.cri = cri.Interface()
self.async_errors = Record(async_errors_layout) self.async_errors = Record(async_errors_layout)
self.sed_spread_enable = Signal()
chan_fine_ts_width = max(max(rtlink.get_fine_ts_width(channel.interface.o) chan_fine_ts_width = max(max(rtlink.get_fine_ts_width(channel.interface.o)
for channel in channels), for channel in channels),
@ -61,10 +63,11 @@ class SyncRTIO(Module):
self.submodules.outputs = ClockDomainsRenamer("rio")( self.submodules.outputs = ClockDomainsRenamer("rio")(
SED(channels, tsc.glbl_fine_ts_width, SED(channels, tsc.glbl_fine_ts_width,
lane_count=lane_count, fifo_depth=fifo_depth, lane_count=lane_count, fifo_depth=fifo_depth,
enable_spread=True, fifo_high_watermark=0.75, fifo_high_watermark=0.75, report_buffer_space=True,
report_buffer_space=True, interface=self.cri)) interface=self.cri))
self.comb += self.outputs.coarse_timestamp.eq(tsc.coarse_ts) self.comb += self.outputs.coarse_timestamp.eq(tsc.coarse_ts)
self.sync += self.outputs.minimum_coarse_timestamp.eq(tsc.coarse_ts + 16) self.sync += self.outputs.minimum_coarse_timestamp.eq(tsc.coarse_ts + 16)
self.specials += MultiReg(self.sed_spread_enable, self.outputs.enable_spread, "rio")
self.submodules.inputs = ClockDomainsRenamer("rio")( self.submodules.inputs = ClockDomainsRenamer("rio")(
InputCollector(tsc, channels, interface=self.cri)) InputCollector(tsc, channels, interface=self.cri))
@ -78,6 +81,7 @@ class DRTIOSatellite(Module):
self.reset = CSRStorage(reset=1) self.reset = CSRStorage(reset=1)
self.reset_phy = CSRStorage(reset=1) self.reset_phy = CSRStorage(reset=1)
self.tsc_loaded = CSR() self.tsc_loaded = CSR()
self.sed_spread_enable = CSRStorage()
# master interface in the sys domain # master interface in the sys domain
self.cri = cri.Interface() self.cri = cri.Interface()
self.async_errors = Record(async_errors_layout) self.async_errors = Record(async_errors_layout)
@ -143,7 +147,7 @@ class DRTIOSatellite(Module):
self.rt_packet, tsc, self.async_errors) self.rt_packet, tsc, self.async_errors)
def get_csrs(self): def get_csrs(self):
return ([self.reset, self.reset_phy, self.tsc_loaded] + return ([self.reset, self.sed_spread_enable, self.reset_phy, self.tsc_loaded] +
self.link_layer.get_csrs() + self.link_stats.get_csrs() + self.link_layer.get_csrs() + self.link_stats.get_csrs() +
self.rt_errors.get_csrs()) self.rt_errors.get_csrs())

View File

@ -3,7 +3,7 @@ from operator import and_
from migen import * from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.genlib.cdc import BlindTransfer from migen.genlib.cdc import MultiReg, BlindTransfer
from misoc.interconnect.csr import * from misoc.interconnect.csr import *
from artiq.gateware.rtio import cri from artiq.gateware.rtio import cri
@ -18,6 +18,7 @@ class Core(Module, AutoCSR):
self.cri = cri.Interface() self.cri = cri.Interface()
self.reset = CSR() self.reset = CSR()
self.reset_phy = CSR() self.reset_phy = CSR()
self.sed_spread_enable = CSRStorage()
self.async_error = CSR(3) self.async_error = CSR(3)
self.collision_channel = CSRStatus(16) self.collision_channel = CSRStatus(16)
self.busy_channel = CSRStatus(16) self.busy_channel = CSRStatus(16)
@ -67,6 +68,7 @@ class Core(Module, AutoCSR):
self.submodules += outputs self.submodules += outputs
self.comb += outputs.coarse_timestamp.eq(tsc.coarse_ts) self.comb += outputs.coarse_timestamp.eq(tsc.coarse_ts)
self.sync += outputs.minimum_coarse_timestamp.eq(tsc.coarse_ts + 12) self.sync += outputs.minimum_coarse_timestamp.eq(tsc.coarse_ts + 12)
self.specials += MultiReg(self.sed_spread_enable.storage, outputs.enable_spread, "rio")
inputs = ClockDomainsRenamer("rio")(InputCollector(tsc, channels, inputs = ClockDomainsRenamer("rio")(InputCollector(tsc, channels,
quash_channels=quash_channels, quash_channels=quash_channels,

View File

@ -12,7 +12,7 @@ __all__ = ["SED"]
class SED(Module): class SED(Module):
def __init__(self, channels, glbl_fine_ts_width, def __init__(self, channels, glbl_fine_ts_width,
lane_count=8, fifo_depth=128, fifo_high_watermark=1.0, enable_spread=True, lane_count=8, fifo_depth=128, fifo_high_watermark=1.0,
quash_channels=[], report_buffer_space=False, interface=None): quash_channels=[], report_buffer_space=False, interface=None):
seqn_width = layouts.seqn_width(lane_count, fifo_depth) seqn_width = layouts.seqn_width(lane_count, fifo_depth)
@ -23,7 +23,6 @@ class SED(Module):
layouts.fifo_payload(channels), layouts.fifo_payload(channels),
[channel.interface.o.delay for channel in channels], [channel.interface.o.delay for channel in channels],
glbl_fine_ts_width, glbl_fine_ts_width,
enable_spread=enable_spread,
quash_channels=quash_channels, quash_channels=quash_channels,
interface=interface) interface=interface)
self.submodules.fifos = FIFOs(lane_count, fifo_depth, fifo_high_watermark, self.submodules.fifos = FIFOs(lane_count, fifo_depth, fifo_high_watermark,
@ -47,6 +46,10 @@ class SED(Module):
self.cri.o_buffer_space.eq(self.fifos.buffer_space) self.cri.o_buffer_space.eq(self.fifos.buffer_space)
] ]
@property
def enable_spread(self):
return self.lane_dist.enable_spread
@property @property
def cri(self): def cri(self):
return self.lane_dist.cri return self.lane_dist.cri

View File

@ -10,7 +10,7 @@ __all__ = ["LaneDistributor"]
class LaneDistributor(Module): class LaneDistributor(Module):
def __init__(self, lane_count, seqn_width, layout_payload, def __init__(self, lane_count, seqn_width, layout_payload,
compensation, glbl_fine_ts_width, compensation, glbl_fine_ts_width,
enable_spread=True, quash_channels=[], interface=None): quash_channels=[], interface=None):
if lane_count & (lane_count - 1): if lane_count & (lane_count - 1):
raise NotImplementedError("lane count must be a power of 2") raise NotImplementedError("lane count must be a power of 2")
@ -28,6 +28,8 @@ class LaneDistributor(Module):
self.output = [Record(layouts.fifo_ingress(seqn_width, layout_payload)) self.output = [Record(layouts.fifo_ingress(seqn_width, layout_payload))
for _ in range(lane_count)] for _ in range(lane_count)]
self.enable_spread = Signal()
# # # # # #
o_status_wait = Signal() o_status_wait = Signal()
@ -173,12 +175,11 @@ class LaneDistributor(Module):
] ]
# current lane has reached high watermark, spread events by switching to the next. # current lane has reached high watermark, spread events by switching to the next.
if enable_spread: self.sync += [
self.sync += [ If(self.enable_spread & (current_lane_high_watermark | ~current_lane_writable),
If(current_lane_high_watermark | ~current_lane_writable, force_laneB.eq(1)
force_laneB.eq(1) ),
), If(do_write,
If(do_write, force_laneB.eq(0)
force_laneB.eq(0) )
) ]
]

View File

@ -217,7 +217,10 @@ class Satellite(BaseSoC, AMPSoC):
# satellite (master-controlled) RTIO # satellite (master-controlled) RTIO
self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels, lane_count=sed_lanes) self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels, lane_count=sed_lanes)
self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors) self.comb += [
self.drtiosat.async_errors.eq(self.local_io.async_errors),
self.local_io.sed_spread_enable.eq(self.drtiosat.sed_spread_enable.storage)
]
# subkernel RTIO # subkernel RTIO
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc)

View File

@ -597,7 +597,10 @@ class SatelliteBase(BaseSoC, AMPSoC):
# satellite (master-controlled) RTIO # satellite (master-controlled) RTIO
self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels, lane_count=sed_lanes) self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels, lane_count=sed_lanes)
self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors) self.comb += [
self.drtiosat.async_errors.eq(self.local_io.async_errors),
self.local_io.sed_spread_enable.eq(self.drtiosat.sed_spread_enable.storage)
]
# subkernel RTIO # subkernel RTIO
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc)

View File

@ -468,7 +468,10 @@ class _SatelliteBase(BaseSoC, AMPSoC):
# DRTIO # DRTIO
self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels) self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels)
self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors) self.comb += [
self.drtiosat.async_errors.eq(self.local_io.async_errors),
self.local_io.sed_spread_enable.eq(self.drtiosat.sed_spread_enable.storage)
]
# subkernel RTIO # subkernel RTIO
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc)

View File

@ -27,6 +27,7 @@ class DUT(Module):
self.sed.coarse_timestamp.eq(self.sed.coarse_timestamp + 1), self.sed.coarse_timestamp.eq(self.sed.coarse_timestamp + 1),
self.sed.minimum_coarse_timestamp.eq(self.sed.coarse_timestamp + 16) self.sed.minimum_coarse_timestamp.eq(self.sed.coarse_timestamp + 16)
] ]
self.comb += self.sed.enable_spread.eq(0)
def simulate(input_events, **kwargs): def simulate(input_events, **kwargs):
@ -110,6 +111,6 @@ class TestSED(unittest.TestCase):
input_events += [(now, 1), (now, 0)] input_events += [(now, 1), (now, 0)]
ttl_changes, access_results = simulate(input_events, ttl_changes, access_results = simulate(input_events,
lane_count=2, fifo_depth=2, enable_spread=False) lane_count=2, fifo_depth=2)
self.assertEqual([r[0] for r in access_results], ["ok"]*len(input_events)) self.assertEqual([r[0] for r in access_results], ["ok"]*len(input_events))
self.assertEqual(ttl_changes, list(range(40, 40+40*20, 10))) self.assertEqual(ttl_changes, list(range(40, 40+40*20, 10)))