|  | # Copyright lowRISC contributors. | 
|  | # Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | # SPDX-License-Identifier: Apache-2.0 | 
|  |  | 
|  | from enum import Enum | 
|  |  | 
|  |  | 
|  | class Edge: | 
|  | """Edge class contains the connection from a node to a node. | 
|  |  | 
|  | a Node can be a host port, output of async_fifo, port in a socket, | 
|  | or a device port. | 
|  | """ | 
|  | def __init__(self, us, ds): | 
|  | self.us = us | 
|  | self.ds = ds | 
|  |  | 
|  | def __repr__(self): | 
|  | return "U(%s) D(%s)" % (self.us.name, self.ds.name) | 
|  |  | 
|  |  | 
|  | # Edges = List[Edge] | 
|  | # Clocks = List[str]  # If length is more than one, should be exactly two | 
|  |  | 
|  | # [UpstreamClock, DownstreamClock] | 
|  |  | 
|  |  | 
|  | class NodeType(Enum): | 
|  | HOST = 1 | 
|  | DEVICE = 2 | 
|  | ASYNC_FIFO = 3 | 
|  | SOCKET_1N = 4 | 
|  | SOCKET_M1 = 5 | 
|  |  | 
|  |  | 
|  | class Node: | 
|  | """Node class is a port that communicates from/to other Node or TL-UL | 
|  | input/output. | 
|  | """ | 
|  |  | 
|  | name = ""  # name: str | 
|  | # node_type: NodeType | 
|  | clocks = []  # Clocks  # clock domains of the node | 
|  | resets = []  # Resets  # resets of the node | 
|  | # e.g. async_fifo in : clk_core , out : clk_main | 
|  |  | 
|  | # If NodeType is Socket out from 1:N then address steering is used | 
|  | # But this value is also propagated up to a Host from multiple Devices | 
|  | # Device Node should have address_from, address_to | 
|  | # address_from = 0  #: int | 
|  | # address_to = 0  #: int | 
|  | addr_range = [] | 
|  |  | 
|  | us = []  # Edges  # Number of Ports depends on the NodeType | 
|  | # 1 for Host, Device, 2 for Async FIFO, N for Sockets | 
|  | ds = []  # Edges | 
|  |  | 
|  | # Req/Rsp FIFO. default False | 
|  | # when False, no storage element | 
|  | # when True, FIFO present with default depth, the "fifo_pass" | 
|  | # variables control whether a particular direction in the fifo | 
|  | # has the passthrough behvaior | 
|  | pipeline = True | 
|  |  | 
|  | # FIFO passtru option. default True | 
|  | # If pipeline is false, these fields have no meaning | 
|  | # passthrough behavior refers to a FIFO passing the trasnaction | 
|  | # through if the FIFO is currently empty | 
|  | req_fifo_pass = True | 
|  | rsp_fifo_pass = True | 
|  |  | 
|  | def __init__(self, name, node_type, clock, reset): | 
|  | self.name = name | 
|  | self.node_type = node_type | 
|  | self.clocks = [clock] | 
|  | self.resets = [reset] | 
|  | self.us = [] | 
|  | self.ds = [] | 
|  | self.addr_range = [] | 
|  |  | 
|  | def esc_name(self) -> str: | 
|  | '''Return an "escaped name" for this node | 
|  |  | 
|  | This replaces '.' characters with '__'. Needed because the node name | 
|  | might be of the form inst_name.if_name (which isn't a valid symbol name | 
|  | in C or SystemVerilog) | 
|  |  | 
|  | ''' | 
|  | return self.name.replace('.', '__') |