mirror of
https://github.com/fpganinja/taxi.git
synced 2026-08-08 16:31:31 -07:00
eth: Fix offset start in BASE-R model
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -223,6 +223,7 @@ class BaseRSerdesSource():
|
||||
frame_offset = 0
|
||||
sof = False
|
||||
in_pre = False
|
||||
in_term = False
|
||||
ifg_cnt = 0
|
||||
deficit_idle_cnt = 0
|
||||
scrambler_state = 0
|
||||
@@ -299,106 +300,92 @@ class BaseRSerdesSource():
|
||||
|
||||
continue
|
||||
|
||||
if rep_cnt != 0:
|
||||
# scale IFG
|
||||
pass
|
||||
elif ifg_cnt + deficit_idle_cnt > 8-1 or (not self.enable_dic and ifg_cnt > 4):
|
||||
# in IFG
|
||||
ifg_cnt = ifg_cnt - 8
|
||||
if ifg_cnt < 0:
|
||||
if self.enable_dic:
|
||||
deficit_idle_cnt = max(deficit_idle_cnt+ifg_cnt, 0)
|
||||
ifg_cnt = 0
|
||||
|
||||
elif frame is None:
|
||||
# idle
|
||||
if not self.queue.empty():
|
||||
# send frame
|
||||
frame = self.queue.get_nowait()
|
||||
self.dequeue_event.set()
|
||||
self.queue_occupancy_bytes -= len(frame)
|
||||
self.queue_occupancy_frames -= 1
|
||||
self.current_frame = frame
|
||||
frame.sim_time_start = sim_time - gbx_delay
|
||||
frame.sim_time_sfd = None
|
||||
frame.sim_time_end = None
|
||||
self.log.info("TX frame: %s", frame)
|
||||
frame.normalize()
|
||||
frame.start_lane = 0
|
||||
assert frame.data[0] == EthPre.PRE
|
||||
assert frame.ctrl[0] == 0
|
||||
frame.data[0] = XgmiiCtrl.START
|
||||
frame.ctrl[0] = 1
|
||||
frame.data.append(XgmiiCtrl.TERM)
|
||||
frame.ctrl.append(1)
|
||||
|
||||
# offset start
|
||||
if self.enable_dic:
|
||||
min_ifg = 3 - deficit_idle_cnt
|
||||
else:
|
||||
min_ifg = 0
|
||||
|
||||
if ifg_cnt > min_ifg or self.force_offset_start:
|
||||
ifg_cnt = ifg_cnt-4
|
||||
frame.start_lane = 4
|
||||
frame.sim_time_start = sim_time + (clk_period // self.byte_lanes * 4) - gbx_delay
|
||||
frame.data = bytearray([XgmiiCtrl.IDLE]*4)+frame.data
|
||||
frame.ctrl = [1]*4+frame.ctrl
|
||||
|
||||
if self.enable_dic:
|
||||
deficit_idle_cnt = max(deficit_idle_cnt+ifg_cnt, 0)
|
||||
ifg_cnt = 0
|
||||
self.active = True
|
||||
frame_offset = -1
|
||||
sof = True
|
||||
in_pre = True
|
||||
else:
|
||||
# clear counters
|
||||
deficit_idle_cnt = 0
|
||||
ifg_cnt = 0
|
||||
self.active = False
|
||||
self.idle_event.set()
|
||||
|
||||
dl = bytearray()
|
||||
cl = []
|
||||
|
||||
for k in range(8):
|
||||
if frame is not None:
|
||||
frame_offset += 1
|
||||
if rep_cnt == 0:
|
||||
pass
|
||||
elif k == 0 or k == 4:
|
||||
frame_offset = max(0, frame_offset-4)
|
||||
d = frame.data[frame_offset]
|
||||
c = frame.ctrl[frame_offset]
|
||||
if frame.sim_time_sfd is None and not in_pre:
|
||||
frame.sim_time_sfd = sim_time + (clk_period // self.byte_lanes * k) - gbx_delay
|
||||
if d == EthPre.SFD and (not self.xgmii_rep_count or rep_cnt == 1):
|
||||
in_pre = False
|
||||
if c and d == XgmiiCtrl.START:
|
||||
if sof:
|
||||
sof = False
|
||||
else:
|
||||
d = 0xAA
|
||||
c = 0
|
||||
dl.append(d)
|
||||
cl.append(c)
|
||||
if k % 4 != 0 or rep_cnt != 0 or (self.force_offset_start and k == 0):
|
||||
pass
|
||||
elif ifg_cnt + deficit_idle_cnt > 4-1 or (not self.enable_dic and ifg_cnt > 4) or in_term:
|
||||
# in IFG
|
||||
ifg_cnt = ifg_cnt - 4
|
||||
if ifg_cnt < 0:
|
||||
if self.enable_dic:
|
||||
deficit_idle_cnt = max(deficit_idle_cnt+ifg_cnt, 0)
|
||||
ifg_cnt = 0
|
||||
elif frame is None:
|
||||
# idle
|
||||
if not self.queue.empty():
|
||||
# send frame
|
||||
frame = self.queue.get_nowait()
|
||||
self.dequeue_event.set()
|
||||
self.queue_occupancy_bytes -= len(frame)
|
||||
self.queue_occupancy_frames -= 1
|
||||
self.current_frame = frame
|
||||
frame.sim_time_start = None
|
||||
frame.sim_time_sfd = None
|
||||
frame.sim_time_end = None
|
||||
self.log.info("TX frame: %s", frame)
|
||||
frame.normalize()
|
||||
frame.start_lane = 0
|
||||
assert frame.data[0] == EthPre.PRE
|
||||
assert frame.ctrl[0] == 0
|
||||
|
||||
if frame_offset >= len(frame.data)-1:
|
||||
if self.enable_dic:
|
||||
deficit_idle_cnt = max(deficit_idle_cnt+ifg_cnt, 0)
|
||||
ifg_cnt = 0
|
||||
self.active = True
|
||||
frame_offset = 0
|
||||
sof = True
|
||||
in_pre = True
|
||||
else:
|
||||
# clear counters
|
||||
deficit_idle_cnt = 0
|
||||
ifg_cnt = 0
|
||||
self.active = False
|
||||
self.idle_event.set()
|
||||
|
||||
d = XgmiiCtrl.IDLE
|
||||
c = 1
|
||||
if frame is not None:
|
||||
if sof:
|
||||
sof = False
|
||||
d = XgmiiCtrl.START
|
||||
c = 1
|
||||
frame.start_lane = k
|
||||
frame.sim_time_start = sim_time + (clk_period // self.byte_lanes * k) - gbx_delay
|
||||
elif frame_offset >= len(frame.data):
|
||||
d = XgmiiCtrl.TERM
|
||||
c = 1
|
||||
in_term = True
|
||||
ifg_cnt = max(self.ifg - (8-k), 0)
|
||||
frame.sim_time_end = sim_time + (clk_period // self.byte_lanes * k) - gbx_delay
|
||||
frame.handle_tx_complete()
|
||||
frame = None
|
||||
self.current_frame = None
|
||||
else:
|
||||
dl.append(XgmiiCtrl.IDLE)
|
||||
cl.append(1)
|
||||
else:
|
||||
d = frame.data[frame_offset]
|
||||
c = frame.ctrl[frame_offset]
|
||||
if frame.sim_time_sfd is None and not in_pre:
|
||||
frame.sim_time_sfd = sim_time + (clk_period // self.byte_lanes * k) - gbx_delay
|
||||
if d == EthPre.SFD and (not self.xgmii_rep_count or rep_cnt == 1):
|
||||
in_pre = False
|
||||
if frame_offset == 0:
|
||||
d = 0xAA
|
||||
c = 0
|
||||
|
||||
if k == 3 or k == 7:
|
||||
dl.append(d)
|
||||
cl.append(c)
|
||||
|
||||
frame_offset += 1
|
||||
if k % 4 == 3:
|
||||
if rep_cnt > 0:
|
||||
rep_cnt -= 1
|
||||
elif self.xgmii_rep_count:
|
||||
rep_cnt = self.xgmii_rep_count
|
||||
if self.xgmii_rep_count % 2 == 0 or (k != 3 if self.force_offset_start else k == 3):
|
||||
rep_cnt = self.xgmii_rep_count
|
||||
if rep_cnt > 0:
|
||||
frame_offset -= 4
|
||||
|
||||
# replace idles with ordered sets
|
||||
if self.os is not None:
|
||||
@@ -413,6 +400,8 @@ class BaseRSerdesSource():
|
||||
dl[k+1:k+4] = self.os.to_bytes(3, 'big')
|
||||
cl[k+1:k+4] = [0, 0, 0]
|
||||
|
||||
in_term = False
|
||||
|
||||
# remap control characters
|
||||
ctrl = sum(xgmii_ctrl_to_baser_mapping.get(d, BaseRCtrl.ERROR) << i*7 for i, d in enumerate(dl))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user