Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bfe8a0e50 | ||
|
|
9c88b0440e | ||
|
|
37b23c358b | ||
|
|
dd35d734f9 | ||
|
|
45ee1193cb | ||
|
|
5caafbb9e7 | ||
|
|
2d4450e048 | ||
|
|
c5d28182c4 | ||
|
|
79991205b5 | ||
|
|
a22123649c | ||
|
|
b5ba332ecc | ||
|
|
eb62e43fd1 | ||
|
|
5c4ef258ac | ||
|
|
6c5845fad3 | ||
|
|
32f6e449c0 | ||
|
|
2af7852006 | ||
|
|
3325568406 | ||
|
|
6a35c31b4b | ||
|
|
73fe54705f | ||
|
|
448451e274 | ||
|
|
21c2c05c57 | ||
|
|
ab84a3b100 | ||
|
|
0f3060b9ba |
6
.github/workflows/regression-tests.yml
vendored
6
.github/workflows/regression-tests.yml
vendored
@@ -9,13 +9,13 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
|
||||
@@ -42,12 +42,12 @@ class XgmiiCtrl(enum.IntEnum):
|
||||
TERM = 0xfd
|
||||
ERROR = 0xfe
|
||||
SEQ_OS = 0x9c
|
||||
RES0 = 0x1c
|
||||
RES1 = 0x3c
|
||||
RES2 = 0x7c
|
||||
RES3 = 0xbc
|
||||
RES4 = 0xdc
|
||||
RES5 = 0xf7
|
||||
RES_0 = 0x1c
|
||||
RES_1 = 0x3c
|
||||
RES_2 = 0x7c
|
||||
RES_3 = 0xbc
|
||||
RES_4 = 0xdc
|
||||
RES_5 = 0xf7
|
||||
SIG_OS = 0x5c
|
||||
|
||||
|
||||
@@ -93,3 +93,41 @@ class BaseRBlockType(enum.IntEnum):
|
||||
TERM_5 = 0xd2 # C7 C6 D4 D3 D2 D1 D0 BT
|
||||
TERM_6 = 0xe1 # C7 D5 D4 D3 D2 D1 D0 BT
|
||||
TERM_7 = 0xff # D6 D5 D4 D3 D2 D1 D0 BT
|
||||
|
||||
|
||||
xgmii_ctrl_to_baser_mapping = {
|
||||
XgmiiCtrl.IDLE: BaseRCtrl.IDLE,
|
||||
XgmiiCtrl.LPI: BaseRCtrl.LPI,
|
||||
XgmiiCtrl.ERROR: BaseRCtrl.ERROR,
|
||||
XgmiiCtrl.RES_0: BaseRCtrl.RES_0,
|
||||
XgmiiCtrl.RES_1: BaseRCtrl.RES_1,
|
||||
XgmiiCtrl.RES_2: BaseRCtrl.RES_2,
|
||||
XgmiiCtrl.RES_3: BaseRCtrl.RES_3,
|
||||
XgmiiCtrl.RES_4: BaseRCtrl.RES_4,
|
||||
XgmiiCtrl.RES_5: BaseRCtrl.RES_5,
|
||||
}
|
||||
|
||||
|
||||
baser_ctrl_to_xgmii_mapping = {
|
||||
BaseRCtrl.IDLE: XgmiiCtrl.IDLE,
|
||||
BaseRCtrl.LPI: XgmiiCtrl.LPI,
|
||||
BaseRCtrl.ERROR: XgmiiCtrl.ERROR,
|
||||
BaseRCtrl.RES_0: XgmiiCtrl.RES_0,
|
||||
BaseRCtrl.RES_1: XgmiiCtrl.RES_1,
|
||||
BaseRCtrl.RES_2: XgmiiCtrl.RES_2,
|
||||
BaseRCtrl.RES_3: XgmiiCtrl.RES_3,
|
||||
BaseRCtrl.RES_4: XgmiiCtrl.RES_4,
|
||||
BaseRCtrl.RES_5: XgmiiCtrl.RES_5,
|
||||
}
|
||||
|
||||
|
||||
block_type_term_lane_mapping = {
|
||||
BaseRBlockType.TERM_0: 0,
|
||||
BaseRBlockType.TERM_1: 1,
|
||||
BaseRBlockType.TERM_2: 2,
|
||||
BaseRBlockType.TERM_3: 3,
|
||||
BaseRBlockType.TERM_4: 4,
|
||||
BaseRBlockType.TERM_5: 5,
|
||||
BaseRBlockType.TERM_6: 6,
|
||||
BaseRBlockType.TERM_7: 7,
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ class EthMacTx(Reset):
|
||||
self._run_ts_cr = None
|
||||
|
||||
if self.ptp_ts_valid:
|
||||
self.ptp_ts_valid <= 0
|
||||
self.ptp_ts_valid.value = 0
|
||||
|
||||
self.active = False
|
||||
|
||||
@@ -262,9 +262,9 @@ class EthMacTx(Reset):
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
if self._run_ts_cr is None and self.ptp_ts:
|
||||
self._run_ts_cr = cocotb.fork(self._run_ts())
|
||||
self._run_ts_cr = cocotb.start_soon(self._run_ts())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
@@ -322,16 +322,18 @@ class EthMacTx(Reset):
|
||||
await Timer(self.time_scale*self.ifg*8//self.speed, 'step')
|
||||
|
||||
async def _run_ts(self):
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
self.ptp_ts_valid <= 0
|
||||
await clock_edge_event
|
||||
self.ptp_ts_valid.value = 0
|
||||
|
||||
if not self.ts_queue.empty():
|
||||
ts, tag = self.ts_queue.get_nowait()
|
||||
self.ptp_ts <= ts
|
||||
self.ptp_ts.value = ts
|
||||
if self.ptp_ts_tag is not None:
|
||||
self.ptp_ts_tag <= tag
|
||||
self.ptp_ts_valid <= 1
|
||||
self.ptp_ts_tag.value = tag
|
||||
self.ptp_ts_valid.value = 1
|
||||
|
||||
|
||||
class EthMacRx(Reset):
|
||||
@@ -475,7 +477,7 @@ class EthMacRx(Reset):
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
|
||||
@@ -157,6 +157,7 @@ class GmiiSource(Reset):
|
||||
self.current_frame = None
|
||||
self.idle_event = Event()
|
||||
self.idle_event.set()
|
||||
self.active_event = Event()
|
||||
|
||||
self.ifg = 12
|
||||
self.mii_mode = False
|
||||
@@ -189,6 +190,7 @@ class GmiiSource(Reset):
|
||||
frame = GmiiFrame(frame)
|
||||
await self.queue.put(frame)
|
||||
self.idle_event.clear()
|
||||
self.active_event.set()
|
||||
self.queue_occupancy_bytes += len(frame)
|
||||
self.queue_occupancy_frames += 1
|
||||
|
||||
@@ -198,6 +200,7 @@ class GmiiSource(Reset):
|
||||
frame = GmiiFrame(frame)
|
||||
self.queue.put_nowait(frame)
|
||||
self.idle_event.clear()
|
||||
self.active_event.set()
|
||||
self.queue_occupancy_bytes += len(frame)
|
||||
self.queue_occupancy_frames += 1
|
||||
|
||||
@@ -225,6 +228,7 @@ class GmiiSource(Reset):
|
||||
frame.handle_tx_complete()
|
||||
self.dequeue_event.set()
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
self.queue_occupancy_bytes = 0
|
||||
self.queue_occupancy_frames = 0
|
||||
|
||||
@@ -239,10 +243,10 @@ class GmiiSource(Reset):
|
||||
self._run_cr = None
|
||||
|
||||
self.active = False
|
||||
self.data <= 0
|
||||
self.data.value = 0
|
||||
if self.er is not None:
|
||||
self.er <= 0
|
||||
self.dv <= 0
|
||||
self.er.value = 0
|
||||
self.dv.value = 0
|
||||
|
||||
if self.current_frame:
|
||||
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
||||
@@ -251,10 +255,11 @@ class GmiiSource(Reset):
|
||||
|
||||
if self.queue.empty():
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
@@ -264,8 +269,14 @@ class GmiiSource(Reset):
|
||||
ifg_cnt = 0
|
||||
self.active = False
|
||||
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
enable_event = None
|
||||
if self.enable is not None:
|
||||
enable_event = RisingEdge(self.enable)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_edge_event
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
if ifg_cnt > 0:
|
||||
@@ -308,10 +319,10 @@ class GmiiSource(Reset):
|
||||
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
|
||||
self.data.value = d
|
||||
if self.er is not None:
|
||||
self.er <= frame_error[frame_offset]
|
||||
self.dv <= 1
|
||||
self.er.value = frame_error[frame_offset]
|
||||
self.dv.value = 1
|
||||
frame_offset += 1
|
||||
|
||||
if frame_offset >= len(frame_data):
|
||||
@@ -321,12 +332,19 @@ class GmiiSource(Reset):
|
||||
frame = None
|
||||
self.current_frame = None
|
||||
else:
|
||||
self.data <= 0
|
||||
self.data.value = 0
|
||||
if self.er is not None:
|
||||
self.er <= 0
|
||||
self.dv <= 0
|
||||
self.er.value = 0
|
||||
self.dv.value = 0
|
||||
self.active = False
|
||||
self.idle_event.set()
|
||||
|
||||
if ifg_cnt == 0 and self.queue.empty():
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
await self.active_event.wait()
|
||||
|
||||
elif self.enable is not None and not self.enable.value:
|
||||
await enable_event
|
||||
|
||||
|
||||
class GmiiSink(Reset):
|
||||
@@ -422,14 +440,22 @@ class GmiiSink(Reset):
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
self.active = False
|
||||
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
active_event = RisingEdge(self.dv)
|
||||
|
||||
enable_event = None
|
||||
if self.enable is not None:
|
||||
enable_event = RisingEdge(self.enable)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_edge_event
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
d_val = self.data.value.integer
|
||||
@@ -488,6 +514,12 @@ class GmiiSink(Reset):
|
||||
frame.data.append(d_val)
|
||||
frame.error.append(er_val)
|
||||
|
||||
if not dv_val:
|
||||
await active_event
|
||||
|
||||
elif self.enable is not None and not self.enable.value:
|
||||
await enable_event
|
||||
|
||||
|
||||
class GmiiPhy:
|
||||
def __init__(self, txd, tx_er, tx_en, tx_clk, gtx_clk, rxd, rx_er, rx_dv, rx_clk,
|
||||
@@ -517,12 +549,12 @@ class GmiiPhy:
|
||||
self._clock_cr.kill()
|
||||
|
||||
if self.speed == 1000e6:
|
||||
self._clock_cr = cocotb.fork(self._run_clocks(8*1e9/self.speed))
|
||||
self._clock_cr = cocotb.start_soon(self._run_clocks(8*1e9/self.speed))
|
||||
self.tx.mii_mode = False
|
||||
self.rx.mii_mode = False
|
||||
self.tx.clock = self.gtx_clk
|
||||
else:
|
||||
self._clock_cr = cocotb.fork(self._run_clocks(4*1e9/self.speed))
|
||||
self._clock_cr = cocotb.start_soon(self._run_clocks(4*1e9/self.speed))
|
||||
self.tx.mii_mode = True
|
||||
self.rx.mii_mode = True
|
||||
self.tx.clock = self.tx_clk
|
||||
@@ -536,8 +568,8 @@ class GmiiPhy:
|
||||
|
||||
while True:
|
||||
await t
|
||||
self.rx_clk <= 1
|
||||
self.tx_clk <= 1
|
||||
self.rx_clk.value = 1
|
||||
self.tx_clk.value = 1
|
||||
await t
|
||||
self.rx_clk <= 0
|
||||
self.tx_clk <= 0
|
||||
self.rx_clk.value = 0
|
||||
self.tx_clk.value = 0
|
||||
|
||||
@@ -59,6 +59,7 @@ class MiiSource(Reset):
|
||||
self.current_frame = None
|
||||
self.idle_event = Event()
|
||||
self.idle_event.set()
|
||||
self.active_event = Event()
|
||||
|
||||
self.ifg = 12
|
||||
|
||||
@@ -90,6 +91,7 @@ class MiiSource(Reset):
|
||||
frame = GmiiFrame(frame)
|
||||
await self.queue.put(frame)
|
||||
self.idle_event.clear()
|
||||
self.active_event.set()
|
||||
self.queue_occupancy_bytes += len(frame)
|
||||
self.queue_occupancy_frames += 1
|
||||
|
||||
@@ -99,6 +101,7 @@ class MiiSource(Reset):
|
||||
frame = GmiiFrame(frame)
|
||||
self.queue.put_nowait(frame)
|
||||
self.idle_event.clear()
|
||||
self.active_event.set()
|
||||
self.queue_occupancy_bytes += len(frame)
|
||||
self.queue_occupancy_frames += 1
|
||||
|
||||
@@ -126,6 +129,7 @@ class MiiSource(Reset):
|
||||
frame.handle_tx_complete()
|
||||
self.dequeue_event.set()
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
self.queue_occupancy_bytes = 0
|
||||
self.queue_occupancy_frames = 0
|
||||
|
||||
@@ -140,10 +144,10 @@ class MiiSource(Reset):
|
||||
self._run_cr = None
|
||||
|
||||
self.active = False
|
||||
self.data <= 0
|
||||
self.data.value = 0
|
||||
if self.er is not None:
|
||||
self.er <= 0
|
||||
self.dv <= 0
|
||||
self.er.value = 0
|
||||
self.dv.value = 0
|
||||
|
||||
if self.current_frame:
|
||||
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
||||
@@ -152,10 +156,11 @@ class MiiSource(Reset):
|
||||
|
||||
if self.queue.empty():
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
@@ -165,8 +170,14 @@ class MiiSource(Reset):
|
||||
ifg_cnt = 0
|
||||
self.active = False
|
||||
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
enable_event = None
|
||||
if self.enable is not None:
|
||||
enable_event = RisingEdge(self.enable)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_edge_event
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
if ifg_cnt > 0:
|
||||
@@ -202,10 +213,10 @@ class MiiSource(Reset):
|
||||
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
|
||||
self.data.value = d
|
||||
if self.er is not None:
|
||||
self.er <= frame_error[frame_offset]
|
||||
self.dv <= 1
|
||||
self.er.value = frame_error[frame_offset]
|
||||
self.dv.value = 1
|
||||
frame_offset += 1
|
||||
|
||||
if frame_offset >= len(frame_data):
|
||||
@@ -215,12 +226,19 @@ class MiiSource(Reset):
|
||||
frame = None
|
||||
self.current_frame = None
|
||||
else:
|
||||
self.data <= 0
|
||||
self.data.value = 0
|
||||
if self.er is not None:
|
||||
self.er <= 0
|
||||
self.dv <= 0
|
||||
self.er.value = 0
|
||||
self.dv.value = 0
|
||||
self.active = False
|
||||
self.idle_event.set()
|
||||
|
||||
if ifg_cnt == 0 and self.queue.empty():
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
await self.active_event.wait()
|
||||
|
||||
elif self.enable is not None and not self.enable.value:
|
||||
await enable_event
|
||||
|
||||
|
||||
class MiiSink(Reset):
|
||||
@@ -313,14 +331,22 @@ class MiiSink(Reset):
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
self.active = False
|
||||
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
active_event = RisingEdge(self.dv)
|
||||
|
||||
enable_event = None
|
||||
if self.enable is not None:
|
||||
enable_event = RisingEdge(self.enable)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_edge_event
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
d_val = self.data.value.integer
|
||||
@@ -374,6 +400,12 @@ class MiiSink(Reset):
|
||||
frame.data.append(d_val)
|
||||
frame.error.append(er_val)
|
||||
|
||||
if not dv_val:
|
||||
await active_event
|
||||
|
||||
elif self.enable is not None and not self.enable.value:
|
||||
await enable_event
|
||||
|
||||
|
||||
class MiiPhy:
|
||||
def __init__(self, txd, tx_er, tx_en, tx_clk, rxd, rx_er, rx_dv, rx_clk, reset=None,
|
||||
@@ -402,7 +434,7 @@ class MiiPhy:
|
||||
if self._clock_cr is not None:
|
||||
self._clock_cr.kill()
|
||||
|
||||
self._clock_cr = cocotb.fork(self._run_clocks(4*1e9/self.speed))
|
||||
self._clock_cr = cocotb.start_soon(self._run_clocks(4*1e9/self.speed))
|
||||
|
||||
async def _run_clocks(self, period):
|
||||
half_period = get_sim_steps(period / 2.0, 'ns')
|
||||
@@ -410,8 +442,8 @@ class MiiPhy:
|
||||
|
||||
while True:
|
||||
await t
|
||||
self.tx_clk <= 1
|
||||
self.rx_clk <= 1
|
||||
self.tx_clk.value = 1
|
||||
self.rx_clk.value = 1
|
||||
await t
|
||||
self.tx_clk <= 0
|
||||
self.rx_clk <= 0
|
||||
self.tx_clk.value = 0
|
||||
self.rx_clk.value = 0
|
||||
|
||||
@@ -195,28 +195,30 @@ class PtpClock(Reset):
|
||||
self.ts_64_fns = 0
|
||||
self.drift_cnt = 0
|
||||
if self.ts_96 is not None:
|
||||
self.ts_96 <= 0
|
||||
self.ts_96.value = 0
|
||||
if self.ts_64 is not None:
|
||||
self.ts_64 <= 0
|
||||
self.ts_64.value = 0
|
||||
if self.ts_step is not None:
|
||||
self.ts_step <= 0
|
||||
self.ts_step.value = 0
|
||||
if self.pps is not None:
|
||||
self.pps <= 0
|
||||
self.pps.value = 0
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_edge_event
|
||||
|
||||
if self.ts_step is not None:
|
||||
self.ts_step <= self.ts_updated
|
||||
self.ts_step.value = self.ts_updated
|
||||
self.ts_updated = False
|
||||
|
||||
if self.pps is not None:
|
||||
self.pps <= 0
|
||||
self.pps.value = 0
|
||||
|
||||
# increment 96 bit timestamp
|
||||
if self.ts_96 is not None or self.pps is not None:
|
||||
@@ -229,13 +231,13 @@ class PtpClock(Reset):
|
||||
self.ts_96_s += 1
|
||||
t -= (1000000000 << 16)
|
||||
if self.pps is not None:
|
||||
self.pps <= 1
|
||||
self.pps.value = 1
|
||||
|
||||
self.ts_96_fns = t & 0xffff
|
||||
self.ts_96_ns = t >> 16
|
||||
|
||||
if self.ts_96 is not None:
|
||||
self.ts_96 <= (self.ts_96_s << 48) | (self.ts_96_ns << 16) | (self.ts_96_fns)
|
||||
self.ts_96.value = (self.ts_96_s << 48) | (self.ts_96_ns << 16) | (self.ts_96_fns)
|
||||
|
||||
# increment 64 bit timestamp
|
||||
if self.ts_64 is not None:
|
||||
@@ -247,7 +249,7 @@ class PtpClock(Reset):
|
||||
self.ts_64_fns = t & 0xffff
|
||||
self.ts_64_ns = t >> 16
|
||||
|
||||
self.ts_64 <= (self.ts_64_ns << 16) | self.ts_64_fns
|
||||
self.ts_64.value = (self.ts_64_ns << 16) | self.ts_64_fns
|
||||
|
||||
if self.drift_rate:
|
||||
if self.drift_cnt > 0:
|
||||
@@ -286,9 +288,9 @@ class PtpClockSimTime:
|
||||
if self.ts_64 is not None:
|
||||
self.ts_64.setimmediatevalue(0)
|
||||
if self.pps is not None:
|
||||
self.pps <= 0
|
||||
self.pps.value = 0
|
||||
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
def get_ts_96(self):
|
||||
return (self.ts_96_s << 48) | (self.ts_96_ns << 16) | self.ts_96_fns
|
||||
@@ -309,8 +311,10 @@ class PtpClockSimTime:
|
||||
return self.get_ts_64()*1e-9
|
||||
|
||||
async def _run(self):
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_edge_event
|
||||
|
||||
self.ts_64_fns, self.ts_64_ns = math.modf(get_sim_time('ns'))
|
||||
|
||||
@@ -321,12 +325,12 @@ class PtpClockSimTime:
|
||||
self.ts_96_fns = self.ts_64_fns
|
||||
|
||||
if self.ts_96 is not None:
|
||||
self.ts_96 <= (self.ts_96_s << 48) | (self.ts_96_ns << 16) | self.ts_96_fns
|
||||
self.ts_96.value = (self.ts_96_s << 48) | (self.ts_96_ns << 16) | self.ts_96_fns
|
||||
|
||||
if self.ts_64 is not None:
|
||||
self.ts_64 <= (self.ts_64_ns << 16) | self.ts_64_fns
|
||||
self.ts_64.value = (self.ts_64_ns << 16) | self.ts_64_fns
|
||||
|
||||
if self.pps is not None:
|
||||
self.pps <= int(self.last_ts_96_s != self.ts_96_s)
|
||||
self.pps.value = int(self.last_ts_96_s != self.ts_96_s)
|
||||
|
||||
self.last_ts_96_s = self.ts_96_s
|
||||
|
||||
@@ -33,7 +33,7 @@ class Reset:
|
||||
self._reset_state = True
|
||||
|
||||
if reset_signal is not None:
|
||||
cocotb.fork(self._run_reset(reset_signal, bool(active_level)))
|
||||
cocotb.start_soon(self._run_reset(reset_signal, bool(active_level)))
|
||||
|
||||
self._update_reset()
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ class RgmiiSource(Reset):
|
||||
self.current_frame = None
|
||||
self.idle_event = Event()
|
||||
self.idle_event.set()
|
||||
self.active_event = Event()
|
||||
|
||||
self.ifg = 12
|
||||
self.mii_mode = False
|
||||
@@ -90,6 +91,7 @@ class RgmiiSource(Reset):
|
||||
frame = GmiiFrame(frame)
|
||||
await self.queue.put(frame)
|
||||
self.idle_event.clear()
|
||||
self.active_event.set()
|
||||
self.queue_occupancy_bytes += len(frame)
|
||||
self.queue_occupancy_frames += 1
|
||||
|
||||
@@ -99,6 +101,7 @@ class RgmiiSource(Reset):
|
||||
frame = GmiiFrame(frame)
|
||||
self.queue.put_nowait(frame)
|
||||
self.idle_event.clear()
|
||||
self.active_event.set()
|
||||
self.queue_occupancy_bytes += len(frame)
|
||||
self.queue_occupancy_frames += 1
|
||||
|
||||
@@ -126,6 +129,7 @@ class RgmiiSource(Reset):
|
||||
frame.handle_tx_complete()
|
||||
self.dequeue_event.set()
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
self.queue_occupancy_bytes = 0
|
||||
self.queue_occupancy_frames = 0
|
||||
|
||||
@@ -140,8 +144,8 @@ class RgmiiSource(Reset):
|
||||
self._run_cr = None
|
||||
|
||||
self.active = False
|
||||
self.data <= 0
|
||||
self.ctrl <= 0
|
||||
self.data.value = 0
|
||||
self.ctrl.value = 0
|
||||
|
||||
if self.current_frame:
|
||||
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
||||
@@ -150,10 +154,11 @@ class RgmiiSource(Reset):
|
||||
|
||||
if self.queue.empty():
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
@@ -161,22 +166,39 @@ class RgmiiSource(Reset):
|
||||
frame_data = None
|
||||
frame_error = None
|
||||
ifg_cnt = 0
|
||||
in_ifg = False
|
||||
self.active = False
|
||||
d = 0
|
||||
er = 0
|
||||
en = 0
|
||||
|
||||
clock_rising_edge_event = RisingEdge(self.clock)
|
||||
clock_falling_edge_event = FallingEdge(self.clock)
|
||||
|
||||
enable_event = None
|
||||
if self.enable is not None:
|
||||
enable_event = RisingEdge(self.enable)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_falling_edge_event
|
||||
|
||||
# send low nibble after falling edge, leading in to rising edge
|
||||
self.data.value = d & 0x0F
|
||||
self.ctrl.value = en
|
||||
|
||||
await clock_rising_edge_event
|
||||
|
||||
# send high nibble after rising edge, leading in to falling edge
|
||||
self.data <= d >> 4
|
||||
self.ctrl <= en ^ er
|
||||
self.data.value = d >> 4
|
||||
self.ctrl.value = en ^ er
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
in_ifg = False
|
||||
|
||||
if ifg_cnt > 0:
|
||||
# in IFG
|
||||
ifg_cnt -= 1
|
||||
in_ifg = True
|
||||
|
||||
elif frame is None and not self.queue.empty():
|
||||
# send frame
|
||||
@@ -221,6 +243,7 @@ class RgmiiSource(Reset):
|
||||
|
||||
if frame_offset >= len(frame_data):
|
||||
ifg_cnt = max(self.ifg, 1)
|
||||
in_ifg = True
|
||||
frame.sim_time_end = get_sim_time()
|
||||
frame.handle_tx_complete()
|
||||
frame = None
|
||||
@@ -230,13 +253,14 @@ class RgmiiSource(Reset):
|
||||
er = 0
|
||||
en = 0
|
||||
self.active = False
|
||||
self.idle_event.set()
|
||||
|
||||
await FallingEdge(self.clock)
|
||||
if not in_ifg and self.queue.empty():
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
await self.active_event.wait()
|
||||
|
||||
# send low nibble after falling edge, leading in to rising edge
|
||||
self.data <= d & 0x0F
|
||||
self.ctrl <= en
|
||||
elif self.enable is not None and not self.enable.value:
|
||||
await enable_event
|
||||
|
||||
|
||||
class RgmiiSink(Reset):
|
||||
@@ -330,7 +354,7 @@ class RgmiiSink(Reset):
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
@@ -339,21 +363,30 @@ class RgmiiSink(Reset):
|
||||
dv_val = 0
|
||||
er_val = 0
|
||||
|
||||
clock_rising_edge_event = RisingEdge(self.clock)
|
||||
clock_falling_edge_event = FallingEdge(self.clock)
|
||||
|
||||
active_event = RisingEdge(self.ctrl)
|
||||
|
||||
enable_event = None
|
||||
if self.enable is not None:
|
||||
enable_event = RisingEdge(self.enable)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
|
||||
# capture low nibble on rising edge
|
||||
d_val = self.data.value.integer
|
||||
dv_val = self.ctrl.value.integer
|
||||
|
||||
await FallingEdge(self.clock)
|
||||
|
||||
# capture high nibble on falling edge
|
||||
d_val |= self.data.value.integer << 4
|
||||
er_val = dv_val ^ self.ctrl.value.integer
|
||||
await clock_rising_edge_event
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
|
||||
# capture low nibble on rising edge
|
||||
d_val = self.data.value.integer
|
||||
dv_val = self.ctrl.value.integer
|
||||
|
||||
await clock_falling_edge_event
|
||||
|
||||
# capture high nibble on falling edge
|
||||
d_val |= self.data.value.integer << 4
|
||||
er_val = dv_val ^ self.ctrl.value.integer
|
||||
|
||||
if frame is None:
|
||||
if dv_val:
|
||||
# start of frame
|
||||
@@ -406,6 +439,12 @@ class RgmiiSink(Reset):
|
||||
frame.data.append(d_val)
|
||||
frame.error.append(er_val)
|
||||
|
||||
if not dv_val:
|
||||
await active_event
|
||||
|
||||
elif self.enable is not None and not self.enable.value:
|
||||
await enable_event
|
||||
|
||||
|
||||
class RgmiiPhy:
|
||||
def __init__(self, txd, tx_ctl, tx_clk, rxd, rx_ctl, rx_clk, reset=None,
|
||||
@@ -434,11 +473,11 @@ class RgmiiPhy:
|
||||
self._clock_cr.kill()
|
||||
|
||||
if self.speed == 1000e6:
|
||||
self._clock_cr = cocotb.fork(self._run_clock(8*1e9/self.speed))
|
||||
self._clock_cr = cocotb.start_soon(self._run_clock(8*1e9/self.speed))
|
||||
self.tx.mii_mode = False
|
||||
self.rx.mii_mode = False
|
||||
else:
|
||||
self._clock_cr = cocotb.fork(self._run_clock(4*1e9/self.speed))
|
||||
self._clock_cr = cocotb.start_soon(self._run_clock(4*1e9/self.speed))
|
||||
self.tx.mii_mode = True
|
||||
self.rx.mii_mode = True
|
||||
|
||||
@@ -448,6 +487,6 @@ class RgmiiPhy:
|
||||
|
||||
while True:
|
||||
await t
|
||||
self.rx_clk <= 1
|
||||
self.rx_clk.value = 1
|
||||
await t
|
||||
self.rx_clk <= 0
|
||||
self.rx_clk.value = 0
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.1.16"
|
||||
__version__ = "0.1.20"
|
||||
|
||||
@@ -28,7 +28,7 @@ import zlib
|
||||
|
||||
import cocotb
|
||||
from cocotb.queue import Queue, QueueFull
|
||||
from cocotb.triggers import RisingEdge, Timer, First, Event
|
||||
from cocotb.triggers import Edge, RisingEdge, Timer, First, Event
|
||||
from cocotb.utils import get_sim_time
|
||||
|
||||
from .version import __version__
|
||||
@@ -158,6 +158,7 @@ class XgmiiSource(Reset):
|
||||
self.current_frame = None
|
||||
self.idle_event = Event()
|
||||
self.idle_event.set()
|
||||
self.active_event = Event()
|
||||
|
||||
self.enable_dic = True
|
||||
self.ifg = 12
|
||||
@@ -200,6 +201,7 @@ class XgmiiSource(Reset):
|
||||
frame = XgmiiFrame(frame)
|
||||
await self.queue.put(frame)
|
||||
self.idle_event.clear()
|
||||
self.active_event.set()
|
||||
self.queue_occupancy_bytes += len(frame)
|
||||
self.queue_occupancy_frames += 1
|
||||
|
||||
@@ -209,6 +211,7 @@ class XgmiiSource(Reset):
|
||||
frame = XgmiiFrame(frame)
|
||||
self.queue.put_nowait(frame)
|
||||
self.idle_event.clear()
|
||||
self.active_event.set()
|
||||
self.queue_occupancy_bytes += len(frame)
|
||||
self.queue_occupancy_frames += 1
|
||||
|
||||
@@ -236,6 +239,7 @@ class XgmiiSource(Reset):
|
||||
frame.handle_tx_complete()
|
||||
self.dequeue_event.set()
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
self.queue_occupancy_bytes = 0
|
||||
self.queue_occupancy_frames = 0
|
||||
|
||||
@@ -250,8 +254,8 @@ class XgmiiSource(Reset):
|
||||
self._run_cr = None
|
||||
|
||||
self.active = False
|
||||
self.data <= 0
|
||||
self.ctrl <= 0
|
||||
self.data.value = 0
|
||||
self.ctrl.value = 0
|
||||
|
||||
if self.current_frame:
|
||||
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
||||
@@ -260,10 +264,11 @@ class XgmiiSource(Reset):
|
||||
|
||||
if self.queue.empty():
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
@@ -272,8 +277,14 @@ class XgmiiSource(Reset):
|
||||
deficit_idle_cnt = 0
|
||||
self.active = False
|
||||
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
enable_event = None
|
||||
if self.enable is not None:
|
||||
enable_event = RisingEdge(self.enable)
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_edge_event
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
if ifg_cnt + deficit_idle_cnt > self.byte_lanes-1 or (not self.enable_dic and ifg_cnt > 4):
|
||||
@@ -351,13 +362,20 @@ class XgmiiSource(Reset):
|
||||
d_val |= XgmiiCtrl.IDLE << k*8
|
||||
c_val |= 1 << k
|
||||
|
||||
self.data <= d_val
|
||||
self.ctrl <= c_val
|
||||
self.data.value = d_val
|
||||
self.ctrl.value = c_val
|
||||
else:
|
||||
self.data <= self.idle_d
|
||||
self.ctrl <= self.idle_c
|
||||
self.data.value = self.idle_d
|
||||
self.ctrl.value = self.idle_c
|
||||
self.active = False
|
||||
self.idle_event.set()
|
||||
|
||||
if ifg_cnt == 0 and self.queue.empty():
|
||||
self.idle_event.set()
|
||||
self.active_event.clear()
|
||||
await self.active_event.wait()
|
||||
|
||||
elif self.enable is not None and not self.enable.value:
|
||||
await enable_event
|
||||
|
||||
|
||||
class XgmiiSink(Reset):
|
||||
@@ -450,19 +468,32 @@ class XgmiiSink(Reset):
|
||||
else:
|
||||
self.log.info("Reset de-asserted")
|
||||
if self._run_cr is None:
|
||||
self._run_cr = cocotb.fork(self._run())
|
||||
self._run_cr = cocotb.start_soon(self._run())
|
||||
|
||||
async def _run(self):
|
||||
frame = None
|
||||
self.active = False
|
||||
|
||||
clock_edge_event = RisingEdge(self.clock)
|
||||
|
||||
active_event = First(Edge(self.data), Edge(self.ctrl))
|
||||
|
||||
enable_event = None
|
||||
if self.enable is not None:
|
||||
enable_event = RisingEdge(self.enable)
|
||||
|
||||
idle_d = sum([XgmiiCtrl.IDLE << n*8 for n in range(self.byte_lanes)])
|
||||
idle_c = 2**self.byte_lanes-1
|
||||
|
||||
while True:
|
||||
await RisingEdge(self.clock)
|
||||
await clock_edge_event
|
||||
|
||||
if self.enable is None or self.enable.value:
|
||||
data_val = self.data.value.integer
|
||||
ctrl_val = self.ctrl.value.integer
|
||||
for offset in range(self.byte_lanes):
|
||||
d_val = (self.data.value.integer >> (offset*8)) & 0xff
|
||||
c_val = (self.ctrl.value.integer >> offset) & 1
|
||||
d_val = (data_val >> (offset*8)) & 0xff
|
||||
c_val = (ctrl_val >> offset) & 1
|
||||
|
||||
if frame is None:
|
||||
if c_val and d_val == XgmiiCtrl.START:
|
||||
@@ -495,3 +526,9 @@ class XgmiiSink(Reset):
|
||||
|
||||
frame.data.append(d_val)
|
||||
frame.ctrl.append(c_val)
|
||||
|
||||
if data_val == idle_d and ctrl_val == idle_c:
|
||||
await active_event
|
||||
|
||||
elif self.enable is not None and not self.enable.value:
|
||||
await enable_event
|
||||
|
||||
33
setup.cfg
33
setup.cfg
@@ -17,17 +17,18 @@ long-description-content-type = text/markdown
|
||||
platforms = any
|
||||
classifiers =
|
||||
Development Status :: 3 - Alpha
|
||||
Programming Language :: Python :: 3
|
||||
Framework :: cocotb
|
||||
License :: OSI Approved :: MIT License
|
||||
Operating System :: OS Independent
|
||||
Programming Language :: Python :: 3
|
||||
Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
|
||||
|
||||
[options]
|
||||
packages = find_namespace:
|
||||
python_requires = >=3.6
|
||||
install_requires =
|
||||
cocotb
|
||||
cocotbext-axi
|
||||
cocotb >= 1.6.0
|
||||
cocotbext-axi >= 0.1.16
|
||||
|
||||
[options.extras_require]
|
||||
test =
|
||||
@@ -46,31 +47,39 @@ addopts =
|
||||
|
||||
# tox configuration
|
||||
[tox:tox]
|
||||
envlist = py36, py37, py38, py39
|
||||
envlist = py37, py38, py39, py310
|
||||
skip_missing_interpreters = true
|
||||
minversion = 3.18.0
|
||||
requires = virtualenv >= 16.1
|
||||
|
||||
[gh-actions]
|
||||
python =
|
||||
3.6: py36
|
||||
3.7: py37
|
||||
3.8: py38
|
||||
3.9: py39
|
||||
3.10: py310
|
||||
|
||||
[testenv]
|
||||
setenv =
|
||||
COVERAGE=1
|
||||
usedevelop = True
|
||||
|
||||
deps =
|
||||
pytest
|
||||
pytest-xdist
|
||||
cocotb-test
|
||||
coverage
|
||||
pytest-cov
|
||||
pytest == 7.2.1
|
||||
pytest-xdist == 3.1.0
|
||||
cocotb == 1.7.2
|
||||
cocotb-bus == 0.2.1
|
||||
cocotb-test == 0.2.4
|
||||
cocotbext-axi == 0.1.20
|
||||
coverage == 7.0.5
|
||||
pytest-cov == 4.0.0
|
||||
|
||||
commands =
|
||||
pytest --cov=cocotbext --cov=tests --cov-branch -n auto
|
||||
pytest --cov=cocotbext --cov=tests --cov-branch {posargs:-n auto --verbose}
|
||||
bash -c 'find . -type f -name "\.coverage" | xargs coverage combine --append'
|
||||
coverage report
|
||||
|
||||
whitelist_externals =
|
||||
allowlist_externals =
|
||||
bash
|
||||
|
||||
# combine if paths are different
|
||||
|
||||
@@ -45,8 +45,8 @@ class TB:
|
||||
self.log = logging.getLogger("cocotb.tb")
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
cocotb.fork(Clock(dut.tx_clk, 6.4, units="ns").start())
|
||||
cocotb.fork(Clock(dut.rx_clk, 6.4, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.tx_clk, 6.4, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.rx_clk, 6.4, units="ns").start())
|
||||
|
||||
self.mac = EthMac(
|
||||
tx_clk=dut.tx_clk,
|
||||
@@ -81,12 +81,12 @@ class TB:
|
||||
self.dut.rx_rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
self.dut.tx_rst <= 1
|
||||
self.dut.rx_rst <= 1
|
||||
self.dut.tx_rst.value = 1
|
||||
self.dut.rx_rst.value = 1
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
self.dut.tx_rst <= 0
|
||||
self.dut.rx_rst <= 0
|
||||
self.dut.tx_rst.value = 0
|
||||
self.dut.rx_rst.value = 0
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class TB:
|
||||
self._enable_generator = None
|
||||
self._enable_cr = None
|
||||
|
||||
cocotb.fork(Clock(dut.clk, 2, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.clk, 2, units="ns").start())
|
||||
|
||||
self.source = GmiiSource(dut.gmii_d, dut.gmii_er, dut.gmii_en,
|
||||
dut.clk, dut.rst, dut.gmii_clk_en, dut.gmii_mii_sel)
|
||||
@@ -61,10 +61,10 @@ class TB:
|
||||
self.dut.rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 1
|
||||
self.dut.rst.value = 1
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 0
|
||||
self.dut.rst.value = 0
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
|
||||
@@ -76,15 +76,17 @@ class TB:
|
||||
self._enable_generator = generator
|
||||
|
||||
if self._enable_generator is not None:
|
||||
self._enable_cr = cocotb.fork(self._run_enable())
|
||||
self._enable_cr = cocotb.start_soon(self._run_enable())
|
||||
|
||||
def clear_enable_generator(self):
|
||||
self.set_enable_generator(None)
|
||||
|
||||
async def _run_enable(self):
|
||||
clock_edge_event = RisingEdge(self.dut.clk)
|
||||
|
||||
for val in self._enable_generator:
|
||||
self.dut.gmii_clk_en <= val
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.gmii_clk_en.value = val
|
||||
await clock_edge_event
|
||||
|
||||
|
||||
async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12, enable_gen=None, mii_sel=False):
|
||||
@@ -92,7 +94,7 @@ async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12, enable_
|
||||
tb = TB(dut)
|
||||
|
||||
tb.source.ifg = ifg
|
||||
tb.dut.gmii_mii_sel <= mii_sel
|
||||
tb.dut.gmii_mii_sel.value = mii_sel
|
||||
|
||||
if enable_gen is not None:
|
||||
tb.set_enable_generator(enable_gen())
|
||||
|
||||
@@ -44,7 +44,7 @@ class TB:
|
||||
self.log = logging.getLogger("cocotb.tb")
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
cocotb.fork(Clock(dut.phy_gtx_clk, 8, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.phy_gtx_clk, 8, units="ns").start())
|
||||
|
||||
self.gmii_phy = GmiiPhy(dut.phy_txd, dut.phy_tx_er, dut.phy_tx_en, dut.phy_tx_clk, dut.phy_gtx_clk,
|
||||
dut.phy_rxd, dut.phy_rx_er, dut.phy_rx_dv, dut.phy_rx_clk, dut.phy_rst, speed=speed)
|
||||
@@ -64,10 +64,10 @@ class TB:
|
||||
self.dut.phy_rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
self.dut.phy_rst <= 1
|
||||
self.dut.phy_rst.value = 1
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
self.dut.phy_rst <= 0
|
||||
self.dut.phy_rst.value = 0
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class TB:
|
||||
self._enable_generator = None
|
||||
self._enable_cr = None
|
||||
|
||||
cocotb.fork(Clock(dut.clk, 2, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.clk, 2, units="ns").start())
|
||||
|
||||
self.source = MiiSource(dut.mii_d, dut.mii_er, dut.mii_en,
|
||||
dut.clk, dut.rst, dut.mii_clk_en)
|
||||
@@ -60,10 +60,10 @@ class TB:
|
||||
self.dut.rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 1
|
||||
self.dut.rst.value = 1
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 0
|
||||
self.dut.rst.value = 0
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
|
||||
@@ -75,15 +75,17 @@ class TB:
|
||||
self._enable_generator = generator
|
||||
|
||||
if self._enable_generator is not None:
|
||||
self._enable_cr = cocotb.fork(self._run_enable())
|
||||
self._enable_cr = cocotb.start_soon(self._run_enable())
|
||||
|
||||
def clear_enable_generator(self):
|
||||
self.set_enable_generator(None)
|
||||
|
||||
async def _run_enable(self):
|
||||
clock_edge_event = RisingEdge(self.dut.clk)
|
||||
|
||||
for val in self._enable_generator:
|
||||
self.dut.mii_clk_en <= val
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.mii_clk_en.value = val
|
||||
await clock_edge_event
|
||||
|
||||
|
||||
async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12, enable_gen=None):
|
||||
|
||||
@@ -55,10 +55,10 @@ class TB:
|
||||
self.dut.phy_rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
self.dut.phy_rst <= 1
|
||||
self.dut.phy_rst.value = 1
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
self.dut.phy_rst <= 0
|
||||
self.dut.phy_rst.value = 0
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import cocotb_test.simulator
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import RisingEdge
|
||||
from cocotb.triggers import RisingEdge, ClockCycles
|
||||
from cocotb.utils import get_sim_time
|
||||
|
||||
from cocotbext.eth import PtpClock
|
||||
@@ -43,7 +43,7 @@ class TB:
|
||||
self.log = logging.getLogger("cocotb.tb")
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
cocotb.fork(Clock(dut.clk, 6.4, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.clk, 6.4, units="ns").start())
|
||||
|
||||
self.ptp_clock = PtpClock(
|
||||
ts_96=dut.ts_96,
|
||||
@@ -59,10 +59,10 @@ class TB:
|
||||
self.dut.rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 1
|
||||
self.dut.rst.value = 1
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 0
|
||||
self.dut.rst.value = 0
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
|
||||
@@ -79,8 +79,7 @@ async def run_default_rate(dut):
|
||||
start_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
start_ts_64 = dut.ts_64.value.integer/2**16*1e-9
|
||||
|
||||
for k in range(10000):
|
||||
await RisingEdge(dut.clk)
|
||||
await ClockCycles(dut.clk, 10000)
|
||||
|
||||
stop_time = get_sim_time('sec')
|
||||
stop_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
@@ -126,8 +125,7 @@ async def run_load_timestamps(dut):
|
||||
start_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
start_ts_64 = dut.ts_64.value.integer/2**16*1e-9
|
||||
|
||||
for k in range(2000):
|
||||
await RisingEdge(dut.clk)
|
||||
await ClockCycles(dut.clk, 2000)
|
||||
|
||||
stop_time = get_sim_time('sec')
|
||||
stop_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
@@ -221,8 +219,7 @@ async def run_frequency_adjustment(dut):
|
||||
start_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
start_ts_64 = dut.ts_64.value.integer/2**16*1e-9
|
||||
|
||||
for k in range(10000):
|
||||
await RisingEdge(dut.clk)
|
||||
await ClockCycles(dut.clk, 10000)
|
||||
|
||||
stop_time = get_sim_time('sec')
|
||||
stop_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
@@ -264,8 +261,7 @@ async def run_drift_adjustment(dut):
|
||||
start_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
start_ts_64 = dut.ts_64.value.integer/2**16*1e-9
|
||||
|
||||
for k in range(10000):
|
||||
await RisingEdge(dut.clk)
|
||||
await ClockCycles(dut.clk, 10000)
|
||||
|
||||
stop_time = get_sim_time('sec')
|
||||
stop_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
|
||||
@@ -30,7 +30,7 @@ import cocotb_test.simulator
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import RisingEdge
|
||||
from cocotb.triggers import RisingEdge, ClockCycles
|
||||
from cocotb.utils import get_sim_time
|
||||
|
||||
from cocotbext.eth import PtpClockSimTime
|
||||
@@ -43,7 +43,7 @@ class TB:
|
||||
self.log = logging.getLogger("cocotb.tb")
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
cocotb.fork(Clock(dut.clk, 6.4, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.clk, 6.4, units="ns").start())
|
||||
|
||||
self.ptp_clock = PtpClockSimTime(
|
||||
ts_96=dut.ts_96,
|
||||
@@ -66,8 +66,7 @@ async def run_test(dut):
|
||||
start_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
start_ts_64 = dut.ts_64.value.integer/2**16*1e-9
|
||||
|
||||
for k in range(10000):
|
||||
await RisingEdge(dut.clk)
|
||||
await ClockCycles(dut.clk, 10000)
|
||||
|
||||
stop_time = get_sim_time('sec')
|
||||
stop_ts_96 = (dut.ts_96.value.integer >> 48) + ((dut.ts_96.value.integer & 0xffffffffffff)/2**16*1e-9)
|
||||
|
||||
@@ -47,7 +47,7 @@ class TB:
|
||||
self._enable_generator = None
|
||||
self._enable_cr = None
|
||||
|
||||
cocotb.fork(Clock(dut.clk, 2, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.clk, 2, units="ns").start())
|
||||
|
||||
self.source = RgmiiSource(dut.rgmii_d, dut.rgmii_ctl, dut.clk, dut.rst, dut.rgmii_clk_en, dut.rgmii_mii_sel)
|
||||
self.sink = RgmiiSink(dut.rgmii_d, dut.rgmii_ctl, dut.clk, dut.rst, dut.rgmii_clk_en, dut.rgmii_mii_sel)
|
||||
@@ -59,10 +59,10 @@ class TB:
|
||||
self.dut.rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 1
|
||||
self.dut.rst.value = 1
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 0
|
||||
self.dut.rst.value = 0
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
|
||||
@@ -74,15 +74,17 @@ class TB:
|
||||
self._enable_generator = generator
|
||||
|
||||
if self._enable_generator is not None:
|
||||
self._enable_cr = cocotb.fork(self._run_enable())
|
||||
self._enable_cr = cocotb.start_soon(self._run_enable())
|
||||
|
||||
def clear_enable_generator(self):
|
||||
self.set_enable_generator(None)
|
||||
|
||||
async def _run_enable(self):
|
||||
clock_edge_event = RisingEdge(self.dut.clk)
|
||||
|
||||
for val in self._enable_generator:
|
||||
self.dut.rgmii_clk_en <= val
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rgmii_clk_en.value = val
|
||||
await clock_edge_event
|
||||
|
||||
|
||||
async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12, enable_gen=None, mii_sel=False):
|
||||
@@ -90,7 +92,7 @@ async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12, enable_
|
||||
tb = TB(dut)
|
||||
|
||||
tb.source.ifg = ifg
|
||||
tb.dut.rgmii_mii_sel <= mii_sel
|
||||
tb.dut.rgmii_mii_sel.value = mii_sel
|
||||
|
||||
if enable_gen is not None:
|
||||
tb.set_enable_generator(enable_gen())
|
||||
|
||||
@@ -45,11 +45,11 @@ class TB:
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
if speed == 1000e6:
|
||||
cocotb.fork(Clock(dut.phy_tx_clk, 8, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.phy_tx_clk, 8, units="ns").start())
|
||||
elif speed == 100e6:
|
||||
cocotb.fork(Clock(dut.phy_tx_clk, 40, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.phy_tx_clk, 40, units="ns").start())
|
||||
elif speed == 10e6:
|
||||
cocotb.fork(Clock(dut.phy_tx_clk, 400, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.phy_tx_clk, 400, units="ns").start())
|
||||
|
||||
self.rgmii_phy = RgmiiPhy(dut.phy_txd, dut.phy_tx_ctl, dut.phy_tx_clk,
|
||||
dut.phy_rxd, dut.phy_rx_ctl, dut.phy_rx_clk, dut.phy_rst, speed=speed)
|
||||
@@ -68,10 +68,10 @@ class TB:
|
||||
self.dut.phy_rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
self.dut.phy_rst <= 1
|
||||
self.dut.phy_rst.value = 1
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
self.dut.phy_rst <= 0
|
||||
self.dut.phy_rst.value = 0
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
await RisingEdge(self.dut.phy_tx_clk)
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class TB:
|
||||
self._enable_generator = None
|
||||
self._enable_cr = None
|
||||
|
||||
cocotb.fork(Clock(dut.clk, 2, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.clk, 2, units="ns").start())
|
||||
|
||||
self.source = XgmiiSource(dut.xgmii_d, dut.xgmii_c, dut.clk, dut.rst, dut.xgmii_clk_en)
|
||||
self.sink = XgmiiSink(dut.xgmii_d, dut.xgmii_c, dut.clk, dut.rst, dut.xgmii_clk_en)
|
||||
@@ -59,10 +59,10 @@ class TB:
|
||||
self.dut.rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 1
|
||||
self.dut.rst.value = 1
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.rst <= 0
|
||||
self.dut.rst.value = 0
|
||||
await RisingEdge(self.dut.clk)
|
||||
await RisingEdge(self.dut.clk)
|
||||
|
||||
@@ -74,15 +74,17 @@ class TB:
|
||||
self._enable_generator = generator
|
||||
|
||||
if self._enable_generator is not None:
|
||||
self._enable_cr = cocotb.fork(self._run_enable())
|
||||
self._enable_cr = cocotb.start_soon(self._run_enable())
|
||||
|
||||
def clear_enable_generator(self):
|
||||
self.set_enable_generator(None)
|
||||
|
||||
async def _run_enable(self):
|
||||
clock_edge_event = RisingEdge(self.dut.clk)
|
||||
|
||||
for val in self._enable_generator:
|
||||
self.dut.xgmii_clk_en <= val
|
||||
await RisingEdge(self.dut.clk)
|
||||
self.dut.xgmii_clk_en.value = val
|
||||
await clock_edge_event
|
||||
|
||||
|
||||
async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12, enable_dic=True,
|
||||
|
||||
Reference in New Issue
Block a user