forked from M-Labs/artiq
rtio/sed: fix lane spreading and enable by default
This commit is contained in:
parent
8cfe2ec53a
commit
1b61442bc3
|
@ -21,7 +21,7 @@ def layout_lane_io(seqn_width, layout_payload):
|
||||||
# 3. check status
|
# 3. check status
|
||||||
|
|
||||||
class LaneDistributor(Module):
|
class LaneDistributor(Module):
|
||||||
def __init__(self, lane_count, fifo_size, layout_payload, fine_ts_width, enable_spread=False):
|
def __init__(self, lane_count, fifo_size, layout_payload, fine_ts_width, enable_spread=True):
|
||||||
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")
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ class LaneDistributor(Module):
|
||||||
timestamp_above_min = Signal()
|
timestamp_above_min = Signal()
|
||||||
timestamp_above_laneA_min = Signal()
|
timestamp_above_laneA_min = Signal()
|
||||||
timestamp_above_laneB_min = Signal()
|
timestamp_above_laneB_min = Signal()
|
||||||
|
force_laneB = Signal()
|
||||||
use_laneB = Signal()
|
use_laneB = Signal()
|
||||||
use_lanen = Signal(max=lane_count)
|
use_lanen = Signal(max=lane_count)
|
||||||
current_lane_plus_one = Signal(max=lane_count)
|
current_lane_plus_one = Signal(max=lane_count)
|
||||||
|
@ -75,7 +76,7 @@ class LaneDistributor(Module):
|
||||||
timestamp_above_min.eq(coarse_timestamp > self.minimum_coarse_timestamp),
|
timestamp_above_min.eq(coarse_timestamp > self.minimum_coarse_timestamp),
|
||||||
timestamp_above_laneA_min.eq(coarse_timestamp > last_lane_coarse_timestamps[current_lane]),
|
timestamp_above_laneA_min.eq(coarse_timestamp > last_lane_coarse_timestamps[current_lane]),
|
||||||
timestamp_above_laneB_min.eq(coarse_timestamp > last_lane_coarse_timestamps[current_lane_plus_one]),
|
timestamp_above_laneB_min.eq(coarse_timestamp > last_lane_coarse_timestamps[current_lane_plus_one]),
|
||||||
If(coarse_timestamp <= last_coarse_timestamp,
|
If(force_laneB | (coarse_timestamp <= last_coarse_timestamp),
|
||||||
use_lanen.eq(current_lane + 1),
|
use_lanen.eq(current_lane + 1),
|
||||||
use_laneB.eq(1)
|
use_laneB.eq(1)
|
||||||
).Else(
|
).Else(
|
||||||
|
@ -118,10 +119,13 @@ class LaneDistributor(Module):
|
||||||
|
|
||||||
# current lane has been full, spread events by switching to the next.
|
# current lane has been full, spread events by switching to the next.
|
||||||
if enable_spread:
|
if enable_spread:
|
||||||
current_lane_writable_r = Signal()
|
current_lane_writable_r = Signal(reset=1)
|
||||||
self.sync += [
|
self.sync += [
|
||||||
current_lane_writable_r.eq(current_lane_writable),
|
current_lane_writable_r.eq(current_lane_writable),
|
||||||
If(~current_lane_writable_r & current_lane_writable,
|
If(~current_lane_writable_r & current_lane_writable,
|
||||||
current_lane.eq(current_lane + 1)
|
force_laneB.eq(1)
|
||||||
|
),
|
||||||
|
If(do_write,
|
||||||
|
force_laneB.eq(0)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,7 +9,7 @@ from artiq.gateware.rtio.sed import lane_distributor
|
||||||
LANE_COUNT = 8
|
LANE_COUNT = 8
|
||||||
|
|
||||||
|
|
||||||
def simulate(input_events):
|
def simulate(input_events, wait=True):
|
||||||
dut = lane_distributor.LaneDistributor(LANE_COUNT, 16, [("channel", 8), ("timestamp", 32)], 3)
|
dut = lane_distributor.LaneDistributor(LANE_COUNT, 16, [("channel", 8), ("timestamp", 32)], 3)
|
||||||
|
|
||||||
output = []
|
output = []
|
||||||
|
@ -59,12 +59,13 @@ def simulate(input_events):
|
||||||
|
|
||||||
generators = [gen()]
|
generators = [gen()]
|
||||||
for n, lio in enumerate(dut.lane_io):
|
for n, lio in enumerate(dut.lane_io):
|
||||||
|
lio.writable.reset = 1
|
||||||
|
wait_time = 0
|
||||||
|
if wait:
|
||||||
if n == 6:
|
if n == 6:
|
||||||
wait_time = 1
|
wait_time = 1
|
||||||
elif n == 7:
|
elif n == 7:
|
||||||
wait_time = 4
|
wait_time = 4
|
||||||
else:
|
|
||||||
wait_time = 0
|
|
||||||
generators.append(monitor_lane(n, lio, wait_time))
|
generators.append(monitor_lane(n, lio, wait_time))
|
||||||
run_simulation(dut, generators)
|
run_simulation(dut, generators)
|
||||||
|
|
||||||
|
@ -89,7 +90,7 @@ class TestLaneDistributor(unittest.TestCase):
|
||||||
|
|
||||||
def test_lane_switch(self):
|
def test_lane_switch(self):
|
||||||
N = 32
|
N = 32
|
||||||
output, access_results = simulate([(42+n, n+8) for n in range(N)])
|
output, access_results = simulate([(42+n, n+8) for n in range(N)], wait=False)
|
||||||
self.assertEqual(output, [((n-n//8) % LANE_COUNT, n, 42+n, n+8) for n in range(N)])
|
self.assertEqual(output, [((n-n//8) % LANE_COUNT, n, 42+n, n+8) for n in range(N)])
|
||||||
self.assertEqual([ar[0] for ar in access_results], ["ok"]*N)
|
self.assertEqual([ar[0] for ar in access_results], ["ok"]*N)
|
||||||
|
|
||||||
|
@ -112,3 +113,12 @@ class TestLaneDistributor(unittest.TestCase):
|
||||||
self.assertEqual(access_results[N-2][0], "underflow")
|
self.assertEqual(access_results[N-2][0], "underflow")
|
||||||
self.assertEqual(output[N-2], (0, N-2, 42+N-2, N*8))
|
self.assertEqual(output[N-2], (0, N-2, 42+N-2, N*8))
|
||||||
self.assertEqual(access_results[N-1][0], "ok")
|
self.assertEqual(access_results[N-1][0], "ok")
|
||||||
|
|
||||||
|
def test_spread(self):
|
||||||
|
# get to lane 6
|
||||||
|
input_events = [(42+n, 8) for n in range(7)]
|
||||||
|
input_events.append((100, 16))
|
||||||
|
input_events.append((100, 32))
|
||||||
|
output, access_results = simulate(input_events)
|
||||||
|
self.assertEqual([o[0] for o in output], [x % LANE_COUNT for x in range(9)])
|
||||||
|
self.assertEqual([ar[0] for ar in access_results], ["ok"]*9)
|
||||||
|
|
Loading…
Reference in New Issue