From 4b768e267dd00fb5db5f93abbf54c84ecd9155b0 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 24 Dec 2020 14:35:51 -0800 Subject: [PATCH] Add RgmiiPhy --- cocotbext/eth/__init__.py | 2 +- cocotbext/eth/rgmii.py | 44 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/cocotbext/eth/__init__.py b/cocotbext/eth/__init__.py index fc2f31e..485fc9c 100644 --- a/cocotbext/eth/__init__.py +++ b/cocotbext/eth/__init__.py @@ -26,7 +26,7 @@ from .version import __version__ from .gmii import GmiiFrame, GmiiSource, GmiiSink from .mii import MiiSource, MiiSink, MiiPhy -from .rgmii import RgmiiSource, RgmiiSink +from .rgmii import RgmiiSource, RgmiiSink, RgmiiPhy from .xgmii import XgmiiFrame, XgmiiSource, XgmiiSink from .ptp import PtpClock diff --git a/cocotbext/eth/rgmii.py b/cocotbext/eth/rgmii.py index 8da8607..7f91b9a 100644 --- a/cocotbext/eth/rgmii.py +++ b/cocotbext/eth/rgmii.py @@ -27,7 +27,7 @@ from collections import deque import cocotb from cocotb.triggers import RisingEdge, FallingEdge, Timer, First, Event -from cocotb.utils import get_sim_time +from cocotb.utils import get_sim_time, get_sim_steps from .version import __version__ from .gmii import GmiiFrame @@ -312,3 +312,45 @@ class RgmiiSink(object): if frame is not None: frame.data.append(d_val) frame.error.append(er_val) + + +class RgmiiPhy: + def __init__(self, txd, tx_ctl, tx_clk, rxd, rx_ctl, rx_clk, reset=None, speed=1000e6, *args, **kwargs): + self.tx_clk = tx_clk + self.rx_clk = rx_clk + + self.tx = RgmiiSink(txd, tx_ctl, tx_clk, reset) + self.rx = RgmiiSource(rxd, rx_ctl, rx_clk, reset) + + self.rx_clk.setimmediatevalue(0) + + self._clock_cr = None + self.set_speed(speed) + + def set_speed(self, speed): + if speed in (10e6, 100e6, 1000e6): + self.speed = speed + else: + raise ValueError("Invalid speed selection") + + if self._clock_cr is not None: + self._clock_cr.kill() + + if self.speed == 1000e6: + self._clock_cr = cocotb.fork(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.tx.mii_mode = True + self.rx.mii_mode = True + + async def _run_clock(self, period): + half_period = get_sim_steps(period / 2.0, 'ns') + t = Timer(half_period) + + while True: + await t + self.rx_clk <= 1 + await t + self.rx_clk <= 0