forked from M-Labs/artiq
allow toggling SED spread with flash config key
This commit is contained in:
parent
8a178a628a
commit
af99a06919
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
)
|
||||||
)
|
]
|
||||||
]
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
Loading…
Reference in New Issue