Source code for hwtLib.examples.axi.debugbusmonitor

#!/usr/bin/env python3arent
# -*- coding: utf-8 -*-

from typing import Dict, Tuple, Optional

from hwt.interfaces.std import Clk, Rst_n, Handshaked
from hwt.interfaces.utils import addClkRstn, propagateClkRstn
from hwt.synthesizer.unit import Unit
from hwtLib.abstract.debug_bus_monitor import DebugBusMonitor, \
    DebugBusMonitorDataRecord
from hwtLib.amba.axi4Lite import Axi4Lite
from hwtLib.amba.axiLite_comp.endpoint import AxiLiteEndpoint
from hwtLib.handshaked.reg import HandshakedReg


[docs]class DebugBusMonitorExampleAxi(Unit): """ An example how to use :class:`hwtLib.abstract.debug_bus_monitor.DebugBusMonitor` .. hwt-autodoc:: """ def _config(self): Axi4Lite._config(self) def _declr(self): addClkRstn(self) with self._paramsShared(): self.s = Axi4Lite() self.din0 = Handshaked() self.dout0 = Handshaked()._m() self.reg = HandshakedReg(Handshaked) self.din1 = Handshaked() self.dout1 = Handshaked()._m() self.other_clk = Clk() self.other_clk.FREQ = self.clk.FREQ * 2 with self._associated(clk=self.other_clk): self.other_rst_n = Rst_n() self.din2 = Handshaked() self.dout2 = Handshaked()._m() def _impl(self): # spy on previously generated circuit db = DebugBusMonitor(Axi4Lite, AxiLiteEndpoint) intf_to_dbg: Dict[Handshaked, DebugBusMonitorDataRecord] = {} def spy_connections(i: Handshaked): """ * Construct a record in DebugBusMonitor for a specified interface. * Link to other visual nodes on connections. * Automatically build nodes for visual hierarchy. """ # cdc if the interface ussing a different clock signal parent = i._parent parents = [] while parent is not self: parents.append(parent) parent = parent._parent parent_node: Optional[DebugBusMonitorDataRecord] = None for o in reversed(parents): n = intf_to_dbg.get(o, None) if n is None: n = intf_to_dbg[o] = DebugBusMonitorDataRecord(None, o._name, False, False, False) db.monitored_data.append(n) if parent_node is not None: parent_node.children.append(n) parent_node = n cdc = i._getAssociatedClk() is not self.clk n0 = db.register(i, cdc=cdc) intf_to_dbg[i] = n0 n1 = db.register(i, name=i._name + "_snapshot", cdc=cdc, trigger=i.vld & i.rd) n0.add_link(n1) if parent_node is not None: parent_node.add_children(n0) parent_node.add_children(n1) orig_connect = i._connectTo def _connectTo(master, exclude=None, fit=False): n0 = intf_to_dbg[master] n1 = intf_to_dbg[i] n0.add_link(n1) return orig_connect(master, exclude=exclude, fit=fit) i._connectTo = _connectTo for i in [self.din0, self.dout0, self.din1, self.reg.dataIn, self.reg.dataOut, self.dout1, self.din2, self.dout2, ]: spy_connections(i) # some connections self.dout0(self.din0) self.reg.dataIn(self.din1) self.dout1(self.reg.dataOut) self.dout2(self.din2) intf_to_dbg[self.reg.dataIn].add_link(intf_to_dbg[self.reg.dataOut]) # we need to add register for ".s" because otherwise there would be # a combinational loop # db.register(self.s, add_reg=True) # for i in self.s._interfaces: # db.register(i, name="s_" + i._name + "_snapshot", # trigger=i.valid & i.ready) with self._paramsShared(): self.db = db db.s(self.s) # there we actually connect the monitored interface # to the monitor instance db.apply_connections() propagateClkRstn(self)
if __name__ == '__main__': from hwt.synthesizer.utils import to_rtl_str u = DebugBusMonitorExampleAxi() print(to_rtl_str(u))