Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de18e62024 | ||
|
|
14738c1dae | ||
|
|
3d43812c7b | ||
|
|
008d903bb9 | ||
|
|
0bd66da868 |
@@ -172,6 +172,10 @@ class EthMacTx(Reset):
|
||||
self.log.info(" tuser width: %d bits", len(self.bus.tuser))
|
||||
else:
|
||||
self.log.info(" tuser: not present")
|
||||
if self.ptp_time:
|
||||
self.log.info(" ptp_time width: %d bits", len(self.ptp_time))
|
||||
else:
|
||||
self.log.info(" ptp_time: not present")
|
||||
|
||||
if self.bus.tready is None:
|
||||
raise ValueError("tready is required")
|
||||
@@ -378,6 +382,10 @@ class EthMacRx(Reset):
|
||||
self.log.info(" tuser width: %d bits", len(self.bus.tuser))
|
||||
else:
|
||||
self.log.info(" tuser: not present")
|
||||
if self.ptp_time:
|
||||
self.log.info(" ptp_time width: %d bits", len(self.ptp_time))
|
||||
else:
|
||||
self.log.info(" ptp_time: not present")
|
||||
|
||||
if self.byte_size != 8:
|
||||
raise ValueError("Byte size must be 8")
|
||||
@@ -462,6 +470,7 @@ class EthMacRx(Reset):
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
frame_offset = 0
|
||||
tuser = 0
|
||||
self.active = False
|
||||
|
||||
@@ -477,6 +486,7 @@ class EthMacRx(Reset):
|
||||
frame.sim_time_sfd = None
|
||||
frame.sim_time_end = None
|
||||
self.log.info("TX frame: %s", frame)
|
||||
frame_offset = 0
|
||||
|
||||
# wait for preamble time
|
||||
await Timer(self.time_scale*8*8//self.speed, 'step')
|
||||
@@ -499,11 +509,12 @@ class EthMacRx(Reset):
|
||||
cycle.tuser = tuser
|
||||
|
||||
for offset in range(self.byte_lanes):
|
||||
cycle.tdata |= (frame.data.pop(0) & self.byte_mask) << (offset * self.byte_size)
|
||||
cycle.tdata |= (frame.data[frame_offset] & self.byte_mask) << (offset * self.byte_size)
|
||||
cycle.tkeep |= 1 << offset
|
||||
byte_count += 1
|
||||
frame_offset += 1
|
||||
|
||||
if len(frame.data) == 0:
|
||||
if frame_offset >= len(frame.data):
|
||||
cycle.tlast = 1
|
||||
frame.sim_time_end = get_sim_time()
|
||||
frame.handle_tx_complete()
|
||||
|
||||
@@ -258,6 +258,9 @@ class GmiiSource(Reset):
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
frame_offset = 0
|
||||
frame_data = None
|
||||
frame_error = None
|
||||
ifg_cnt = 0
|
||||
self.active = False
|
||||
|
||||
@@ -286,28 +289,32 @@ class GmiiSource(Reset):
|
||||
self.mii_mode = bool(self.mii_select.value.integer)
|
||||
|
||||
if self.mii_mode:
|
||||
mii_data = []
|
||||
mii_error = []
|
||||
# convert to MII
|
||||
frame_data = []
|
||||
frame_error = []
|
||||
for b, e in zip(frame.data, frame.error):
|
||||
mii_data.append(b & 0x0F)
|
||||
mii_data.append(b >> 4)
|
||||
mii_error.append(e)
|
||||
mii_error.append(e)
|
||||
frame.data = mii_data
|
||||
frame.error = mii_error
|
||||
frame_data.append(b & 0x0F)
|
||||
frame_data.append(b >> 4)
|
||||
frame_error.append(e)
|
||||
frame_error.append(e)
|
||||
else:
|
||||
frame_data = frame.data
|
||||
frame_error = frame.error
|
||||
|
||||
self.active = True
|
||||
frame_offset = 0
|
||||
|
||||
if frame is not None:
|
||||
d = frame.data.pop(0)
|
||||
d = frame_data[frame_offset]
|
||||
if frame.sim_time_sfd is None and d in (EthPre.SFD, 0xD):
|
||||
frame.sim_time_sfd = get_sim_time()
|
||||
self.data <= d
|
||||
if self.er is not None:
|
||||
self.er <= frame.error.pop(0)
|
||||
self.er <= frame_error[frame_offset]
|
||||
self.dv <= 1
|
||||
frame_offset += 1
|
||||
|
||||
if not frame.data:
|
||||
if frame_offset >= len(frame_data):
|
||||
ifg_cnt = max(self.ifg, 1)
|
||||
frame.sim_time_end = get_sim_time()
|
||||
frame.handle_tx_complete()
|
||||
|
||||
@@ -159,6 +159,9 @@ class MiiSource(Reset):
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
frame_offset = 0
|
||||
frame_data = None
|
||||
frame_error = None
|
||||
ifg_cnt = 0
|
||||
self.active = False
|
||||
|
||||
@@ -183,28 +186,29 @@ class MiiSource(Reset):
|
||||
self.log.info("TX frame: %s", frame)
|
||||
frame.normalize()
|
||||
|
||||
mii_data = []
|
||||
mii_error = []
|
||||
# convert to MII
|
||||
frame_data = []
|
||||
frame_error = []
|
||||
for b, e in zip(frame.data, frame.error):
|
||||
mii_data.append(b & 0x0F)
|
||||
mii_data.append(b >> 4)
|
||||
mii_error.append(e)
|
||||
mii_error.append(e)
|
||||
frame.data = mii_data
|
||||
frame.error = mii_error
|
||||
frame_data.append(b & 0x0F)
|
||||
frame_data.append(b >> 4)
|
||||
frame_error.append(e)
|
||||
frame_error.append(e)
|
||||
|
||||
self.active = True
|
||||
frame_offset = 0
|
||||
|
||||
if frame is not None:
|
||||
d = frame.data.pop(0)
|
||||
d = frame_data[frame_offset]
|
||||
if frame.sim_time_sfd is None and d == 0xD:
|
||||
frame.sim_time_sfd = get_sim_time()
|
||||
self.data <= d
|
||||
if self.er is not None:
|
||||
self.er <= frame.error.pop(0)
|
||||
self.er <= frame_error[frame_offset]
|
||||
self.dv <= 1
|
||||
frame_offset += 1
|
||||
|
||||
if not frame.data:
|
||||
if frame_offset >= len(frame_data):
|
||||
ifg_cnt = max(self.ifg, 1)
|
||||
frame.sim_time_end = get_sim_time()
|
||||
frame.handle_tx_complete()
|
||||
|
||||
@@ -157,6 +157,9 @@ class RgmiiSource(Reset):
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
frame_offset = 0
|
||||
frame_data = None
|
||||
frame_error = None
|
||||
ifg_cnt = 0
|
||||
self.active = False
|
||||
d = 0
|
||||
@@ -192,27 +195,31 @@ class RgmiiSource(Reset):
|
||||
self.mii_mode = bool(self.mii_select.value.integer)
|
||||
|
||||
if self.mii_mode:
|
||||
mii_data = []
|
||||
mii_error = []
|
||||
# convert to MII
|
||||
frame_data = []
|
||||
frame_error = []
|
||||
for b, e in zip(frame.data, frame.error):
|
||||
mii_data.append((b & 0x0F)*0x11)
|
||||
mii_data.append((b >> 4)*0x11)
|
||||
mii_error.append(e)
|
||||
mii_error.append(e)
|
||||
frame.data = mii_data
|
||||
frame.error = mii_error
|
||||
frame_data.append((b & 0x0F)*0x11)
|
||||
frame_data.append((b >> 4)*0x11)
|
||||
frame_error.append(e)
|
||||
frame_error.append(e)
|
||||
else:
|
||||
frame_data = frame.data
|
||||
frame_error = frame.error
|
||||
|
||||
self.active = True
|
||||
frame_offset = 0
|
||||
|
||||
if frame is not None:
|
||||
d = frame.data.pop(0)
|
||||
er = frame.error.pop(0)
|
||||
d = frame_data[frame_offset]
|
||||
er = frame_error[frame_offset]
|
||||
en = 1
|
||||
frame_offset += 1
|
||||
|
||||
if frame.sim_time_sfd is None and d in (EthPre.SFD, 0xD, 0xDD):
|
||||
frame.sim_time_sfd = get_sim_time()
|
||||
|
||||
if not frame.data:
|
||||
if frame_offset >= len(frame_data):
|
||||
ifg_cnt = max(self.ifg, 1)
|
||||
frame.sim_time_end = get_sim_time()
|
||||
frame.handle_tx_complete()
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.1.12"
|
||||
__version__ = "0.1.14"
|
||||
|
||||
@@ -170,14 +170,19 @@ class XgmiiSource(Reset):
|
||||
self.queue_occupancy_limit_frames = -1
|
||||
|
||||
self.width = len(self.data)
|
||||
self.byte_width = len(self.ctrl)
|
||||
self.byte_size = 8
|
||||
self.byte_lanes = len(self.ctrl)
|
||||
|
||||
assert self.width == self.byte_width * 8
|
||||
assert self.width == self.byte_lanes * self.byte_size
|
||||
|
||||
self.log.info("XGMII source model configuration")
|
||||
self.log.info(" Byte size: %d bits", self.byte_size)
|
||||
self.log.info(" Data width: %d bits (%d bytes)", self.width, self.byte_lanes)
|
||||
|
||||
self.idle_d = 0
|
||||
self.idle_c = 0
|
||||
|
||||
for k in range(self.byte_width):
|
||||
for k in range(self.byte_lanes):
|
||||
self.idle_d |= XgmiiCtrl.IDLE << k*8
|
||||
self.idle_c |= 1 << k
|
||||
|
||||
@@ -262,6 +267,7 @@ class XgmiiSource(Reset):
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
frame_offset = 0
|
||||
ifg_cnt = 0
|
||||
deficit_idle_cnt = 0
|
||||
self.active = False
|
||||
@@ -270,9 +276,9 @@ class XgmiiSource(Reset):
|
||||
await RisingEdge(self.clock)
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
if ifg_cnt + deficit_idle_cnt > self.byte_width-1 or (not self.enable_dic and ifg_cnt > 4):
|
||||
if ifg_cnt + deficit_idle_cnt > self.byte_lanes-1 or (not self.enable_dic and ifg_cnt > 4):
|
||||
# in IFG
|
||||
ifg_cnt = ifg_cnt - self.byte_width
|
||||
ifg_cnt = ifg_cnt - self.byte_lanes
|
||||
if ifg_cnt < 0:
|
||||
if self.enable_dic:
|
||||
deficit_idle_cnt = max(deficit_idle_cnt+ifg_cnt, 0)
|
||||
@@ -306,7 +312,7 @@ class XgmiiSource(Reset):
|
||||
else:
|
||||
min_ifg = 0
|
||||
|
||||
if self.byte_width > 4 and (ifg_cnt > min_ifg or self.force_offset_start):
|
||||
if self.byte_lanes > 4 and (ifg_cnt > min_ifg or self.force_offset_start):
|
||||
ifg_cnt = ifg_cnt-4
|
||||
frame.start_lane = 4
|
||||
frame.data = bytearray([XgmiiCtrl.IDLE]*4)+frame.data
|
||||
@@ -316,6 +322,7 @@ class XgmiiSource(Reset):
|
||||
deficit_idle_cnt = max(deficit_idle_cnt+ifg_cnt, 0)
|
||||
ifg_cnt = 0
|
||||
self.active = True
|
||||
frame_offset = 0
|
||||
else:
|
||||
# clear counters
|
||||
deficit_idle_cnt = 0
|
||||
@@ -325,16 +332,17 @@ class XgmiiSource(Reset):
|
||||
d_val = 0
|
||||
c_val = 0
|
||||
|
||||
for k in range(self.byte_width):
|
||||
for k in range(self.byte_lanes):
|
||||
if frame is not None:
|
||||
d = frame.data.pop(0)
|
||||
d = frame.data[frame_offset]
|
||||
if frame.sim_time_sfd is None and d == EthPre.SFD:
|
||||
frame.sim_time_sfd = get_sim_time()
|
||||
d_val |= d << k*8
|
||||
c_val |= frame.ctrl.pop(0) << k
|
||||
c_val |= frame.ctrl[frame_offset] << k
|
||||
frame_offset += 1
|
||||
|
||||
if not frame.data:
|
||||
ifg_cnt = max(self.ifg - (self.byte_width-k), 0)
|
||||
if frame_offset >= len(frame.data):
|
||||
ifg_cnt = max(self.ifg - (self.byte_lanes-k), 0)
|
||||
frame.sim_time_end = get_sim_time()
|
||||
frame.handle_tx_complete()
|
||||
frame = None
|
||||
@@ -377,9 +385,14 @@ class XgmiiSink(Reset):
|
||||
self.queue_occupancy_frames = 0
|
||||
|
||||
self.width = len(self.data)
|
||||
self.byte_width = len(self.ctrl)
|
||||
self.byte_size = 8
|
||||
self.byte_lanes = len(self.ctrl)
|
||||
|
||||
assert self.width == self.byte_width * 8
|
||||
assert self.width == self.byte_lanes * self.byte_size
|
||||
|
||||
self.log.info("XGMII sink model configuration")
|
||||
self.log.info(" Byte size: %d bits", self.byte_size)
|
||||
self.log.info(" Data width: %d bits (%d bytes)", self.width, self.byte_lanes)
|
||||
|
||||
self._run_cr = None
|
||||
|
||||
@@ -447,7 +460,7 @@ class XgmiiSink(Reset):
|
||||
await RisingEdge(self.clock)
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
for offset in range(self.byte_width):
|
||||
for offset in range(self.byte_lanes):
|
||||
d_val = (self.data.value.integer >> (offset*8)) & 0xff
|
||||
c_val = (self.ctrl.value.integer >> offset) & 1
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ async def run_test_alignment(dut, payload_data=None, ifg=12, enable_dic=True,
|
||||
|
||||
tb = TB(dut)
|
||||
|
||||
byte_width = tb.source.width // 8
|
||||
byte_lanes = tb.source.byte_lanes
|
||||
|
||||
tb.source.ifg = ifg
|
||||
tb.source.enable_dic = enable_dic
|
||||
@@ -164,23 +164,23 @@ async def run_test_alignment(dut, payload_data=None, ifg=12, enable_dic=True,
|
||||
for test_data in test_frames:
|
||||
if ifg == 0:
|
||||
lane = 0
|
||||
if force_offset_start and byte_width > 4:
|
||||
if force_offset_start and byte_lanes > 4:
|
||||
lane = 4
|
||||
|
||||
start_lane_ref.append(lane)
|
||||
lane = (lane + len(test_data)+4+ifg) % byte_width
|
||||
lane = (lane + len(test_data)+4+ifg) % byte_lanes
|
||||
|
||||
if enable_dic:
|
||||
offset = lane % 4
|
||||
if deficit_idle_count+offset >= 4:
|
||||
offset += 4
|
||||
lane = (lane - offset) % byte_width
|
||||
lane = (lane - offset) % byte_lanes
|
||||
deficit_idle_count = (deficit_idle_count + offset) % 4
|
||||
else:
|
||||
offset = lane % 4
|
||||
if offset > 0:
|
||||
offset += 4
|
||||
lane = (lane - offset) % byte_width
|
||||
lane = (lane - offset) % byte_lanes
|
||||
|
||||
tb.log.info("start_lane_ref: %s", start_lane_ref)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user