forked from M-Labs/artiq
1
0
Fork 0

rtio/sed: fix lane spreading and enable by default

This commit is contained in:
Sebastien Bourdeauducq 2017-09-13 22:48:10 +08:00
parent 8cfe2ec53a
commit 1b61442bc3
2 changed files with 26 additions and 12 deletions

View File

@ -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)
) )
] ]

View File

@ -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):
if n == 6: lio.writable.reset = 1
wait_time = 1 wait_time = 0
elif n == 7: if wait:
wait_time = 4 if n == 6:
else: wait_time = 1
wait_time = 0 elif n == 7:
wait_time = 4
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)