Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a35c31b4b | ||
|
|
73fe54705f | ||
|
|
448451e274 | ||
|
|
21c2c05c57 | ||
|
|
ab84a3b100 | ||
|
|
0f3060b9ba | ||
|
|
2ee51890f5 | ||
|
|
fbdf4149b3 | ||
|
|
03156ff759 | ||
|
|
8956de42b5 |
15
README.md
15
README.md
@@ -467,6 +467,7 @@ To use these modules, import the one you need and connect it to the DUT:
|
|||||||
tx_bus=AxiStreamBus.from_prefix(dut, "tx_axis"),
|
tx_bus=AxiStreamBus.from_prefix(dut, "tx_axis"),
|
||||||
tx_ptp_time=dut.tx_ptp_time,
|
tx_ptp_time=dut.tx_ptp_time,
|
||||||
tx_ptp_ts=dut.tx_ptp_ts,
|
tx_ptp_ts=dut.tx_ptp_ts,
|
||||||
|
tx_ptp_ts_tag=dut.tx_ptp_ts_tag,
|
||||||
tx_ptp_ts_valid=dut.tx_ptp_ts_valid,
|
tx_ptp_ts_valid=dut.tx_ptp_ts_valid,
|
||||||
rx_clk=dut.rx_clk,
|
rx_clk=dut.rx_clk,
|
||||||
rx_rst=dut.rx_rst,
|
rx_rst=dut.rx_rst,
|
||||||
@@ -492,6 +493,8 @@ To receive data, call `recv()` or `recv_nowait()`. Optionally call `wait()` to
|
|||||||
|
|
||||||
data = await mac.tx.recv()
|
data = await mac.tx.recv()
|
||||||
|
|
||||||
|
PTP timestamping requires free-running PTP clocks driving the PTP time inputs, synchronous with the corresponding MAC clocks. The values of these fields are then captured when the frame SFD is transferred and returned either on tuser (for received frames) or on a separate streaming interface (for transmitted frames). Additionally, on the transmit path, a tag value from tuser is returned along with the timestamp.
|
||||||
|
|
||||||
#### Signals
|
#### Signals
|
||||||
|
|
||||||
* `tdata`: payload data, must be a multiple of 8 bits
|
* `tdata`: payload data, must be a multiple of 8 bits
|
||||||
@@ -499,9 +502,10 @@ To receive data, call `recv()` or `recv_nowait()`. Optionally call `wait()` to
|
|||||||
* `tready`: indicates sink is ready for data (tx only)
|
* `tready`: indicates sink is ready for data (tx only)
|
||||||
* `tlast`: marks the last cycle of a frame
|
* `tlast`: marks the last cycle of a frame
|
||||||
* `tkeep`: qualifies data byte, data bus width must be evenly divisible by `tkeep` signal width
|
* `tkeep`: qualifies data byte, data bus width must be evenly divisible by `tkeep` signal width
|
||||||
* `tuser`: user data, carries frame error mark and captured receive PTP timestamp
|
* `tuser`: user data, carries frame error mark and captured receive PTP timestamp (RX) or PTP timestamp tag (TX)
|
||||||
* `ptp_time`: PTP time input from PHC, captured into `ptp_timestamp` field coincident with transfer of frame SFD and output on `ptp_ts`
|
* `ptp_time`: PTP time input from PHC, captured into `ptp_timestamp` field coincident with transfer of frame SFD and output on `ptp_ts` (TX) or `tuser` (RX)
|
||||||
* `ptp_ts`: captured transmit PTP timestamp
|
* `ptp_ts`: captured transmit PTP timestamp
|
||||||
|
* `ptp_ts_tag`: captured transmit PTP timestamp tag
|
||||||
* `ptp_ts_valid`: qualifies captured transmit PTP timestamp
|
* `ptp_ts_valid`: qualifies captured transmit PTP timestamp
|
||||||
|
|
||||||
#### Constructor parameters (`EthMacRx` and `EthMacTx`):
|
#### Constructor parameters (`EthMacRx` and `EthMacTx`):
|
||||||
@@ -510,7 +514,8 @@ To receive data, call `recv()` or `recv_nowait()`. Optionally call `wait()` to
|
|||||||
* _clock_: clock signal
|
* _clock_: clock signal
|
||||||
* _reset_: reset signal (optional)
|
* _reset_: reset signal (optional)
|
||||||
* _ptp_time_: PTP time input from PHC (optional)
|
* _ptp_time_: PTP time input from PHC (optional)
|
||||||
* _ptp_ts_: PTP timestamp output (optional) (tx)
|
* _ptp_ts_: PTP timestamp (optional) (tx)
|
||||||
|
* _ptp_ts_tag_: PTP timestamp tag (optional) (tx)
|
||||||
* _ptp_ts_valid_: PTP timestamp valid (optional) (tx)
|
* _ptp_ts_valid_: PTP timestamp valid (optional) (tx)
|
||||||
* _reset_active_level_: reset active level (optional, default `True`)
|
* _reset_active_level_: reset active level (optional, default `True`)
|
||||||
* _ifg_: IFG size in byte times (optional, default `12`)
|
* _ifg_: IFG size in byte times (optional, default `12`)
|
||||||
@@ -522,7 +527,8 @@ To receive data, call `recv()` or `recv_nowait()`. Optionally call `wait()` to
|
|||||||
* _tx_clk_: transmit clock
|
* _tx_clk_: transmit clock
|
||||||
* _tx_rst_: transmit reset (optional)
|
* _tx_rst_: transmit reset (optional)
|
||||||
* _tx_ptp_time_: transmit PTP time input from PHC (optional)
|
* _tx_ptp_time_: transmit PTP time input from PHC (optional)
|
||||||
* _tx_ptp_ts_: transmit PTP timestamp output (optional)
|
* _tx_ptp_ts_: transmit PTP timestamp (optional)
|
||||||
|
* _tx_ptp_ts_tag_: transmit PTP timestamp tag (optional)
|
||||||
* _tx_ptp_ts_valid_: transmit PTP timestamp valid (optional)
|
* _tx_ptp_ts_valid_: transmit PTP timestamp valid (optional)
|
||||||
* _rx_bus_: `AxiStreamBus` object containing receive AXI stream interface signals
|
* _rx_bus_: `AxiStreamBus` object containing receive AXI stream interface signals
|
||||||
* _rx_clk_: receive clock
|
* _rx_clk_: receive clock
|
||||||
@@ -565,6 +571,7 @@ Attributes:
|
|||||||
* `sim_time_start`: simulation time of first transfer cycle of frame.
|
* `sim_time_start`: simulation time of first transfer cycle of frame.
|
||||||
* `sim_time_sfd`: simulation time at which the SFD was transferred.
|
* `sim_time_sfd`: simulation time at which the SFD was transferred.
|
||||||
* `sim_time_end`: simulation time of last transfer cycle of frame.
|
* `sim_time_end`: simulation time of last transfer cycle of frame.
|
||||||
|
* `ptp_tag`: PTP timestamp tag for transmitted frames.
|
||||||
* `ptp_timestamp`: captured value of `ptp_time` at frame SFD
|
* `ptp_timestamp`: captured value of `ptp_time` at frame SFD
|
||||||
* `tx_complete`: event or callable triggered when frame is transmitted.
|
* `tx_complete`: event or callable triggered when frame is transmitted.
|
||||||
|
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ class XgmiiCtrl(enum.IntEnum):
|
|||||||
TERM = 0xfd
|
TERM = 0xfd
|
||||||
ERROR = 0xfe
|
ERROR = 0xfe
|
||||||
SEQ_OS = 0x9c
|
SEQ_OS = 0x9c
|
||||||
RES0 = 0x1c
|
RES_0 = 0x1c
|
||||||
RES1 = 0x3c
|
RES_1 = 0x3c
|
||||||
RES2 = 0x7c
|
RES_2 = 0x7c
|
||||||
RES3 = 0xbc
|
RES_3 = 0xbc
|
||||||
RES4 = 0xdc
|
RES_4 = 0xdc
|
||||||
RES5 = 0xf7
|
RES_5 = 0xf7
|
||||||
SIG_OS = 0x5c
|
SIG_OS = 0x5c
|
||||||
|
|
||||||
|
|
||||||
@@ -93,3 +93,41 @@ class BaseRBlockType(enum.IntEnum):
|
|||||||
TERM_5 = 0xd2 # C7 C6 D4 D3 D2 D1 D0 BT
|
TERM_5 = 0xd2 # C7 C6 D4 D3 D2 D1 D0 BT
|
||||||
TERM_6 = 0xe1 # C7 D5 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
|
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,
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ class EthMacFrame:
|
|||||||
self.sim_time_sfd = None
|
self.sim_time_sfd = None
|
||||||
self.sim_time_end = None
|
self.sim_time_end = None
|
||||||
self.ptp_timestamp = None
|
self.ptp_timestamp = None
|
||||||
|
self.ptp_tag = None
|
||||||
self.tx_complete = None
|
self.tx_complete = None
|
||||||
|
|
||||||
if type(data) is EthMacFrame:
|
if type(data) is EthMacFrame:
|
||||||
@@ -57,6 +58,7 @@ class EthMacFrame:
|
|||||||
self.sim_time_sfd = data.sim_time_sfd
|
self.sim_time_sfd = data.sim_time_sfd
|
||||||
self.sim_time_end = data.sim_time_end
|
self.sim_time_end = data.sim_time_end
|
||||||
self.ptp_timestamp = data.ptp_timestamp
|
self.ptp_timestamp = data.ptp_timestamp
|
||||||
|
self.ptp_tag = data.ptp_tag
|
||||||
self.tx_complete = data.tx_complete
|
self.tx_complete = data.tx_complete
|
||||||
else:
|
else:
|
||||||
self.data = bytearray(data)
|
self.data = bytearray(data)
|
||||||
@@ -104,7 +106,8 @@ class EthMacFrame:
|
|||||||
f"sim_time_start={self.sim_time_start!r}, "
|
f"sim_time_start={self.sim_time_start!r}, "
|
||||||
f"sim_time_sfd={self.sim_time_sfd!r}, "
|
f"sim_time_sfd={self.sim_time_sfd!r}, "
|
||||||
f"sim_time_end={self.sim_time_end!r}, "
|
f"sim_time_end={self.sim_time_end!r}, "
|
||||||
f"ptp_timestamp={self.ptp_timestamp!r})"
|
f"ptp_timestamp={self.ptp_timestamp!r}, "
|
||||||
|
f"ptp_tag={self.ptp_tag!r})"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
@@ -118,7 +121,7 @@ class EthMacFrame:
|
|||||||
|
|
||||||
|
|
||||||
class EthMacTx(Reset):
|
class EthMacTx(Reset):
|
||||||
def __init__(self, bus, clock, reset=None, ptp_time=None, ptp_ts=None, ptp_ts_valid=None,
|
def __init__(self, bus, clock, reset=None, ptp_time=None, ptp_ts=None, ptp_ts_tag=None, ptp_ts_valid=None,
|
||||||
reset_active_level=True, ifg=12, speed=1000e6, *args, **kwargs):
|
reset_active_level=True, ifg=12, speed=1000e6, *args, **kwargs):
|
||||||
|
|
||||||
self.bus = bus
|
self.bus = bus
|
||||||
@@ -126,6 +129,7 @@ class EthMacTx(Reset):
|
|||||||
self.reset = reset
|
self.reset = reset
|
||||||
self.ptp_time = ptp_time
|
self.ptp_time = ptp_time
|
||||||
self.ptp_ts = ptp_ts
|
self.ptp_ts = ptp_ts
|
||||||
|
self.ptp_ts_tag = ptp_ts_tag
|
||||||
self.ptp_ts_valid = ptp_ts_valid
|
self.ptp_ts_valid = ptp_ts_valid
|
||||||
self.ifg = ifg
|
self.ifg = ifg
|
||||||
self.speed = speed
|
self.speed = speed
|
||||||
@@ -189,6 +193,8 @@ class EthMacTx(Reset):
|
|||||||
|
|
||||||
if self.ptp_ts:
|
if self.ptp_ts:
|
||||||
self.ptp_ts.setimmediatevalue(0)
|
self.ptp_ts.setimmediatevalue(0)
|
||||||
|
if self.ptp_ts_tag:
|
||||||
|
self.ptp_ts_tag.setimmediatevalue(0)
|
||||||
if self.ptp_ts_valid:
|
if self.ptp_ts_valid:
|
||||||
self.ptp_ts_valid.setimmediatevalue(0)
|
self.ptp_ts_valid.setimmediatevalue(0)
|
||||||
|
|
||||||
@@ -247,7 +253,7 @@ class EthMacTx(Reset):
|
|||||||
self._run_ts_cr = None
|
self._run_ts_cr = None
|
||||||
|
|
||||||
if self.ptp_ts_valid:
|
if self.ptp_ts_valid:
|
||||||
self.ptp_ts_valid <= 0
|
self.ptp_ts_valid.value = 0
|
||||||
|
|
||||||
self.active = False
|
self.active = False
|
||||||
|
|
||||||
@@ -278,7 +284,8 @@ class EthMacTx(Reset):
|
|||||||
|
|
||||||
if self.ptp_time:
|
if self.ptp_time:
|
||||||
frame.ptp_timestamp = self.ptp_time.value.integer
|
frame.ptp_timestamp = self.ptp_time.value.integer
|
||||||
self.ts_queue.put_nowait(frame.ptp_timestamp)
|
frame.ptp_tag = cycle.tuser.integer >> 1
|
||||||
|
self.ts_queue.put_nowait((frame.ptp_timestamp, frame.ptp_tag))
|
||||||
|
|
||||||
# process frame data
|
# process frame data
|
||||||
while True:
|
while True:
|
||||||
@@ -317,12 +324,14 @@ class EthMacTx(Reset):
|
|||||||
async def _run_ts(self):
|
async def _run_ts(self):
|
||||||
while True:
|
while True:
|
||||||
await RisingEdge(self.clock)
|
await RisingEdge(self.clock)
|
||||||
self.ptp_ts_valid <= 0
|
self.ptp_ts_valid.value = 0
|
||||||
|
|
||||||
if not self.ts_queue.empty():
|
if not self.ts_queue.empty():
|
||||||
ts = self.ts_queue.get_nowait()
|
ts, tag = self.ts_queue.get_nowait()
|
||||||
self.ptp_ts <= ts
|
self.ptp_ts.value = ts
|
||||||
self.ptp_ts_valid <= 1
|
if self.ptp_ts_tag is not None:
|
||||||
|
self.ptp_ts_tag.value = tag
|
||||||
|
self.ptp_ts_valid.value = 1
|
||||||
|
|
||||||
|
|
||||||
class EthMacRx(Reset):
|
class EthMacRx(Reset):
|
||||||
@@ -532,13 +541,13 @@ class EthMacRx(Reset):
|
|||||||
|
|
||||||
|
|
||||||
class EthMac:
|
class EthMac:
|
||||||
def __init__(self, tx_bus=None, tx_clk=None, tx_rst=None, tx_ptp_time=None, tx_ptp_ts=None, tx_ptp_ts_valid=None,
|
def __init__(self, tx_bus=None, tx_clk=None, tx_rst=None, tx_ptp_time=None, tx_ptp_ts=None, tx_ptp_ts_tag=None,
|
||||||
rx_bus=None, rx_clk=None, rx_rst=None, rx_ptp_time=None,
|
tx_ptp_ts_valid=None, rx_bus=None, rx_clk=None, rx_rst=None, rx_ptp_time=None,
|
||||||
reset_active_level=True, ifg=12, speed=1000e6, *args, **kwargs):
|
reset_active_level=True, ifg=12, speed=1000e6, *args, **kwargs):
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.tx = EthMacTx(tx_bus, tx_clk, tx_rst, tx_ptp_time, tx_ptp_ts, tx_ptp_ts_valid,
|
self.tx = EthMacTx(tx_bus, tx_clk, tx_rst, tx_ptp_time, tx_ptp_ts, tx_ptp_ts_tag, tx_ptp_ts_valid,
|
||||||
reset_active_level=reset_active_level, ifg=ifg, speed=speed)
|
reset_active_level=reset_active_level, ifg=ifg, speed=speed)
|
||||||
self.rx = EthMacRx(rx_bus, rx_clk, rx_rst, rx_ptp_time,
|
self.rx = EthMacRx(rx_bus, rx_clk, rx_rst, rx_ptp_time,
|
||||||
reset_active_level=reset_active_level, ifg=ifg, speed=speed)
|
reset_active_level=reset_active_level, ifg=ifg, speed=speed)
|
||||||
|
|||||||
@@ -239,10 +239,10 @@ class GmiiSource(Reset):
|
|||||||
self._run_cr = None
|
self._run_cr = None
|
||||||
|
|
||||||
self.active = False
|
self.active = False
|
||||||
self.data <= 0
|
self.data.value = 0
|
||||||
if self.er is not None:
|
if self.er is not None:
|
||||||
self.er <= 0
|
self.er.value = 0
|
||||||
self.dv <= 0
|
self.dv.value = 0
|
||||||
|
|
||||||
if self.current_frame:
|
if self.current_frame:
|
||||||
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
||||||
@@ -308,10 +308,10 @@ class GmiiSource(Reset):
|
|||||||
d = frame_data[frame_offset]
|
d = frame_data[frame_offset]
|
||||||
if frame.sim_time_sfd is None and d in (EthPre.SFD, 0xD):
|
if frame.sim_time_sfd is None and d in (EthPre.SFD, 0xD):
|
||||||
frame.sim_time_sfd = get_sim_time()
|
frame.sim_time_sfd = get_sim_time()
|
||||||
self.data <= d
|
self.data.value = d
|
||||||
if self.er is not None:
|
if self.er is not None:
|
||||||
self.er <= frame_error[frame_offset]
|
self.er.value = frame_error[frame_offset]
|
||||||
self.dv <= 1
|
self.dv.value = 1
|
||||||
frame_offset += 1
|
frame_offset += 1
|
||||||
|
|
||||||
if frame_offset >= len(frame_data):
|
if frame_offset >= len(frame_data):
|
||||||
@@ -321,10 +321,10 @@ class GmiiSource(Reset):
|
|||||||
frame = None
|
frame = None
|
||||||
self.current_frame = None
|
self.current_frame = None
|
||||||
else:
|
else:
|
||||||
self.data <= 0
|
self.data.value = 0
|
||||||
if self.er is not None:
|
if self.er is not None:
|
||||||
self.er <= 0
|
self.er.value = 0
|
||||||
self.dv <= 0
|
self.dv.value = 0
|
||||||
self.active = False
|
self.active = False
|
||||||
self.idle_event.set()
|
self.idle_event.set()
|
||||||
|
|
||||||
@@ -536,8 +536,8 @@ class GmiiPhy:
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
await t
|
await t
|
||||||
self.rx_clk <= 1
|
self.rx_clk.value = 1
|
||||||
self.tx_clk <= 1
|
self.tx_clk.value = 1
|
||||||
await t
|
await t
|
||||||
self.rx_clk <= 0
|
self.rx_clk.value = 0
|
||||||
self.tx_clk <= 0
|
self.tx_clk.value = 0
|
||||||
|
|||||||
@@ -140,10 +140,10 @@ class MiiSource(Reset):
|
|||||||
self._run_cr = None
|
self._run_cr = None
|
||||||
|
|
||||||
self.active = False
|
self.active = False
|
||||||
self.data <= 0
|
self.data.value = 0
|
||||||
if self.er is not None:
|
if self.er is not None:
|
||||||
self.er <= 0
|
self.er.value = 0
|
||||||
self.dv <= 0
|
self.dv.value = 0
|
||||||
|
|
||||||
if self.current_frame:
|
if self.current_frame:
|
||||||
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
||||||
@@ -202,10 +202,10 @@ class MiiSource(Reset):
|
|||||||
d = frame_data[frame_offset]
|
d = frame_data[frame_offset]
|
||||||
if frame.sim_time_sfd is None and d == 0xD:
|
if frame.sim_time_sfd is None and d == 0xD:
|
||||||
frame.sim_time_sfd = get_sim_time()
|
frame.sim_time_sfd = get_sim_time()
|
||||||
self.data <= d
|
self.data.value = d
|
||||||
if self.er is not None:
|
if self.er is not None:
|
||||||
self.er <= frame_error[frame_offset]
|
self.er.value = frame_error[frame_offset]
|
||||||
self.dv <= 1
|
self.dv.value = 1
|
||||||
frame_offset += 1
|
frame_offset += 1
|
||||||
|
|
||||||
if frame_offset >= len(frame_data):
|
if frame_offset >= len(frame_data):
|
||||||
@@ -215,10 +215,10 @@ class MiiSource(Reset):
|
|||||||
frame = None
|
frame = None
|
||||||
self.current_frame = None
|
self.current_frame = None
|
||||||
else:
|
else:
|
||||||
self.data <= 0
|
self.data.value = 0
|
||||||
if self.er is not None:
|
if self.er is not None:
|
||||||
self.er <= 0
|
self.er.value = 0
|
||||||
self.dv <= 0
|
self.dv.value = 0
|
||||||
self.active = False
|
self.active = False
|
||||||
self.idle_event.set()
|
self.idle_event.set()
|
||||||
|
|
||||||
@@ -410,8 +410,8 @@ class MiiPhy:
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
await t
|
await t
|
||||||
self.tx_clk <= 1
|
self.tx_clk.value = 1
|
||||||
self.rx_clk <= 1
|
self.rx_clk.value = 1
|
||||||
await t
|
await t
|
||||||
self.tx_clk <= 0
|
self.tx_clk.value = 0
|
||||||
self.rx_clk <= 0
|
self.rx_clk.value = 0
|
||||||
|
|||||||
@@ -195,13 +195,13 @@ class PtpClock(Reset):
|
|||||||
self.ts_64_fns = 0
|
self.ts_64_fns = 0
|
||||||
self.drift_cnt = 0
|
self.drift_cnt = 0
|
||||||
if self.ts_96 is not None:
|
if self.ts_96 is not None:
|
||||||
self.ts_96 <= 0
|
self.ts_96.value = 0
|
||||||
if self.ts_64 is not None:
|
if self.ts_64 is not None:
|
||||||
self.ts_64 <= 0
|
self.ts_64.value = 0
|
||||||
if self.ts_step is not None:
|
if self.ts_step is not None:
|
||||||
self.ts_step <= 0
|
self.ts_step.value = 0
|
||||||
if self.pps is not None:
|
if self.pps is not None:
|
||||||
self.pps <= 0
|
self.pps.value = 0
|
||||||
else:
|
else:
|
||||||
self.log.info("Reset de-asserted")
|
self.log.info("Reset de-asserted")
|
||||||
if self._run_cr is None:
|
if self._run_cr is None:
|
||||||
@@ -212,11 +212,11 @@ class PtpClock(Reset):
|
|||||||
await RisingEdge(self.clock)
|
await RisingEdge(self.clock)
|
||||||
|
|
||||||
if self.ts_step is not None:
|
if self.ts_step is not None:
|
||||||
self.ts_step <= self.ts_updated
|
self.ts_step.value = self.ts_updated
|
||||||
self.ts_updated = False
|
self.ts_updated = False
|
||||||
|
|
||||||
if self.pps is not None:
|
if self.pps is not None:
|
||||||
self.pps <= 0
|
self.pps.value = 0
|
||||||
|
|
||||||
# increment 96 bit timestamp
|
# increment 96 bit timestamp
|
||||||
if self.ts_96 is not None or self.pps is not None:
|
if self.ts_96 is not None or self.pps is not None:
|
||||||
@@ -229,13 +229,13 @@ class PtpClock(Reset):
|
|||||||
self.ts_96_s += 1
|
self.ts_96_s += 1
|
||||||
t -= (1000000000 << 16)
|
t -= (1000000000 << 16)
|
||||||
if self.pps is not None:
|
if self.pps is not None:
|
||||||
self.pps <= 1
|
self.pps.value = 1
|
||||||
|
|
||||||
self.ts_96_fns = t & 0xffff
|
self.ts_96_fns = t & 0xffff
|
||||||
self.ts_96_ns = t >> 16
|
self.ts_96_ns = t >> 16
|
||||||
|
|
||||||
if self.ts_96 is not None:
|
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
|
# increment 64 bit timestamp
|
||||||
if self.ts_64 is not None:
|
if self.ts_64 is not None:
|
||||||
@@ -247,7 +247,7 @@ class PtpClock(Reset):
|
|||||||
self.ts_64_fns = t & 0xffff
|
self.ts_64_fns = t & 0xffff
|
||||||
self.ts_64_ns = t >> 16
|
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_rate:
|
||||||
if self.drift_cnt > 0:
|
if self.drift_cnt > 0:
|
||||||
@@ -286,7 +286,7 @@ class PtpClockSimTime:
|
|||||||
if self.ts_64 is not None:
|
if self.ts_64 is not None:
|
||||||
self.ts_64.setimmediatevalue(0)
|
self.ts_64.setimmediatevalue(0)
|
||||||
if self.pps is not None:
|
if self.pps is not None:
|
||||||
self.pps <= 0
|
self.pps.value = 0
|
||||||
|
|
||||||
self._run_cr = cocotb.fork(self._run())
|
self._run_cr = cocotb.fork(self._run())
|
||||||
|
|
||||||
@@ -321,12 +321,12 @@ class PtpClockSimTime:
|
|||||||
self.ts_96_fns = self.ts_64_fns
|
self.ts_96_fns = self.ts_64_fns
|
||||||
|
|
||||||
if self.ts_96 is not None:
|
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:
|
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:
|
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
|
self.last_ts_96_s = self.ts_96_s
|
||||||
|
|||||||
@@ -140,8 +140,8 @@ class RgmiiSource(Reset):
|
|||||||
self._run_cr = None
|
self._run_cr = None
|
||||||
|
|
||||||
self.active = False
|
self.active = False
|
||||||
self.data <= 0
|
self.data.value = 0
|
||||||
self.ctrl <= 0
|
self.ctrl.value = 0
|
||||||
|
|
||||||
if self.current_frame:
|
if self.current_frame:
|
||||||
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
||||||
@@ -170,8 +170,8 @@ class RgmiiSource(Reset):
|
|||||||
await RisingEdge(self.clock)
|
await RisingEdge(self.clock)
|
||||||
|
|
||||||
# send high nibble after rising edge, leading in to falling edge
|
# send high nibble after rising edge, leading in to falling edge
|
||||||
self.data <= d >> 4
|
self.data.value = d >> 4
|
||||||
self.ctrl <= en ^ er
|
self.ctrl.value = en ^ er
|
||||||
|
|
||||||
if self.enable is None or self.enable.value:
|
if self.enable is None or self.enable.value:
|
||||||
if ifg_cnt > 0:
|
if ifg_cnt > 0:
|
||||||
@@ -235,8 +235,8 @@ class RgmiiSource(Reset):
|
|||||||
await FallingEdge(self.clock)
|
await FallingEdge(self.clock)
|
||||||
|
|
||||||
# send low nibble after falling edge, leading in to rising edge
|
# send low nibble after falling edge, leading in to rising edge
|
||||||
self.data <= d & 0x0F
|
self.data.value = d & 0x0F
|
||||||
self.ctrl <= en
|
self.ctrl.value = en
|
||||||
|
|
||||||
|
|
||||||
class RgmiiSink(Reset):
|
class RgmiiSink(Reset):
|
||||||
@@ -448,6 +448,6 @@ class RgmiiPhy:
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
await t
|
await t
|
||||||
self.rx_clk <= 1
|
self.rx_clk.value = 1
|
||||||
await t
|
await t
|
||||||
self.rx_clk <= 0
|
self.rx_clk.value = 0
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = "0.1.14"
|
__version__ = "0.1.18"
|
||||||
|
|||||||
@@ -250,8 +250,8 @@ class XgmiiSource(Reset):
|
|||||||
self._run_cr = None
|
self._run_cr = None
|
||||||
|
|
||||||
self.active = False
|
self.active = False
|
||||||
self.data <= 0
|
self.data.value = 0
|
||||||
self.ctrl <= 0
|
self.ctrl.value = 0
|
||||||
|
|
||||||
if self.current_frame:
|
if self.current_frame:
|
||||||
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
self.log.warning("Flushed transmit frame during reset: %s", self.current_frame)
|
||||||
@@ -351,11 +351,11 @@ class XgmiiSource(Reset):
|
|||||||
d_val |= XgmiiCtrl.IDLE << k*8
|
d_val |= XgmiiCtrl.IDLE << k*8
|
||||||
c_val |= 1 << k
|
c_val |= 1 << k
|
||||||
|
|
||||||
self.data <= d_val
|
self.data.value = d_val
|
||||||
self.ctrl <= c_val
|
self.ctrl.value = c_val
|
||||||
else:
|
else:
|
||||||
self.data <= self.idle_d
|
self.data.value = self.idle_d
|
||||||
self.ctrl <= self.idle_c
|
self.ctrl.value = self.idle_c
|
||||||
self.active = False
|
self.active = False
|
||||||
self.idle_event.set()
|
self.idle_event.set()
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,10 @@ long-description-content-type = text/markdown
|
|||||||
platforms = any
|
platforms = any
|
||||||
classifiers =
|
classifiers =
|
||||||
Development Status :: 3 - Alpha
|
Development Status :: 3 - Alpha
|
||||||
Programming Language :: Python :: 3
|
Framework :: cocotb
|
||||||
License :: OSI Approved :: MIT License
|
License :: OSI Approved :: MIT License
|
||||||
Operating System :: OS Independent
|
Operating System :: OS Independent
|
||||||
|
Programming Language :: Python :: 3
|
||||||
Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
|
Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
|
||||||
|
|
||||||
[options]
|
[options]
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ class TB:
|
|||||||
tx_bus=AxiStreamBus.from_prefix(dut, "tx_axis"),
|
tx_bus=AxiStreamBus.from_prefix(dut, "tx_axis"),
|
||||||
tx_ptp_time=dut.tx_ptp_time,
|
tx_ptp_time=dut.tx_ptp_time,
|
||||||
tx_ptp_ts=dut.tx_ptp_ts,
|
tx_ptp_ts=dut.tx_ptp_ts,
|
||||||
|
tx_ptp_ts_tag=dut.tx_ptp_ts_tag,
|
||||||
tx_ptp_ts_valid=dut.tx_ptp_ts_valid,
|
tx_ptp_ts_valid=dut.tx_ptp_ts_valid,
|
||||||
rx_clk=dut.rx_clk,
|
rx_clk=dut.rx_clk,
|
||||||
rx_rst=dut.rx_rst,
|
rx_rst=dut.rx_rst,
|
||||||
|
|||||||
@@ -36,11 +36,12 @@ module test_eth_mac
|
|||||||
inout wire [63:0] tx_axis_tdata,
|
inout wire [63:0] tx_axis_tdata,
|
||||||
inout wire [7:0] tx_axis_tkeep,
|
inout wire [7:0] tx_axis_tkeep,
|
||||||
inout wire tx_axis_tlast,
|
inout wire tx_axis_tlast,
|
||||||
inout wire tx_axis_tuser,
|
inout wire [16:0] tx_axis_tuser,
|
||||||
inout wire tx_axis_tvalid,
|
inout wire tx_axis_tvalid,
|
||||||
inout wire tx_axis_tready,
|
inout wire tx_axis_tready,
|
||||||
inout wire [95:0] tx_ptp_time,
|
inout wire [95:0] tx_ptp_time,
|
||||||
inout wire [95:0] tx_ptp_ts,
|
inout wire [95:0] tx_ptp_ts,
|
||||||
|
inout wire [15:0] tx_ptp_ts_tag,
|
||||||
inout wire tx_ptp_ts_valid,
|
inout wire tx_ptp_ts_valid,
|
||||||
|
|
||||||
inout wire rx_clk,
|
inout wire rx_clk,
|
||||||
|
|||||||
Reference in New Issue
Block a user