<commit_before>import networkx as nx
import importlib.resources
import pathlib
import shutil
from .modules import modules
from .util import sub_brackets

class prefix_node():
    """Defines a node in the prefix summation graph

    Nodes have an x position (bit), y position (level),
    the module they are representing (black, grey, etc),
    and two dictionary of edges
    """

    def __init__(self, x, y, module, flat=False, custom_module=None):
        """Initializes a node in the prefix summation graph

        Pre-conditions:
        x, y are integers
        module is a valid module from the modules list
        flat is an optional flag to determine how HDL is output
        custom_module is an optional alternative for providing
            a module definition that is not included in modules

        Post-conditions:
        stores all these values into internal variables
        creates two dictionaries of input/output edges
        """
        if not (isinstance(x,int) and isinstance(y,int)):
            raise TypeError("prefix_node x,y must both be integers")

        if module not in modules and not isinstance(custom_module,dict):
            raise ValueError("trying to create node with invalid module")
        if isinstance(custom_module,dict):
            if 'verilog' not in custom_module:
                raise ValueError("custom modules must have valid HDL")
            if 'logic' not in custom_module:
                raise ValueError("custom modules must have valid logic")
            modules[module]=custom_module

        self.x=x; self.y=y; self.m=module; self.flat=flat;

        # Create inputs and outputs dictionaries; initialize to None
        self.ins={x:[None]*y for x,y in modules[self.m]['ins']}
        self.outs={x:[None]*y for x,y in modules[self.m]['outs']}

        # A list of all nodes that directly or indirectly feed into this one
        self.upstream=set()

        # All nodes start, by default, outside of any blocks
        self.block=None

    def _exists(n):
        """Static helper function that checks whether a node is not invis"""
        return n is not None and modules[n.m]['exists']

    def _isbuf(n):
        """Static helper function that checks whether a node is a buffer"""
        return n is not None and modules[n.m]['buf']

    def _in_tree(n):
        """Static helper function that checks whether a node is in the tree"""
        return n is not None and modules[n.m]['type']=='main'

    def _parse_net(x):
        """Static helper function that converts a net's ID to its name in HDL

        These come in 3 possible flavors:
            - None (unassigned net) -> parsed to n0
            - Integer (assigned net) -> parsed to n`Integer
            - Hardcoded name ($net_name) -> parsed to net_name
        """
        if x is None:
            return "n0"
        if isinstance(x,int):
            return "n"+str(x)
        if "$" in x:
            return x.replace("$","")
        raise TypeError("net stored in node {0} is invalid".format(repr(x)))

    def _verilog(self):
        """Return single line of Verilog consisting of module instantiation"""

        # Fill in the module instantiation
        ret="\t{3} {0}_{1}_{2} (".format(self.m,self.x,self.y,self.m)
        
        # Create list of all instance pins and copy in unformatted net IDs
        pins=self.ins.copy()
        pins.update(self.outs)
        
        # Format net IDs and add them to module instantation line
        for a in pins:
            ret+=" ."+a+"( {"
            ret+=','.join(reversed([prefix_node._parse_net(x) for x in pins[a]]))
            ret+='} ),'
        ret=ret[:-1]+' );'
        
        return ret

    def _vhdl(self):
        """Return single line of VHDL consisting of module instantiation"""

        # Fill in the module instantiation
        ret="\t{0}_{1}_{2}: {3}\n".format(self.m,self.x,self.y,self.m)
        ret+="\t\tport map ("

        # Create list of all instance pins and copy in unformatted net IDs
        pins=self.ins.copy()
        pins.update(self.outs)

        # Format net IDs and add them to module instantation line
        for a in pins:
            for b in range(len(pins[a])):
                net_name = prefix_node._parse_net(pins[a][b])
                ret+="\n\t\t\t{0}({1}) => {2},".format(a,b,net_name)

        # Close parenthesis
        ret=ret[:-1]
        ret+="\n\t\t);"

        return ret

    def _flat(self,language="verilog"):
        """Return HDL consisting of the module's logic"""

        ### Grab only instantiated cells from the HDL definiton

        # Iterate over each line in the HDL definition
        hdl_def = modules[self.m][language].splitlines()

        # Flag whether we're currently looking at a cell
        in_std_cell = False

        # Store the filtered HDL in a string
        ret = ''

        for l in hdl_def:
            if 'assign' in l or '<=' in l:
                ret+=l+'\n'
            else:
                if 'U' in l: in_std_cell = True
                if in_std_cell == True: ret += l+'\n'
                if l!='' and l[-1] == ';': in_std_cell = False

        # Create list of all instance pins and copy in unformatted net IDs
        pins=self.ins.copy()
        pins.update(self.outs)

        # Format net IDs and replace them into module's HDL
        for a in pins:
            if len(pins[a])==1:
                net_name=prefix_node._parse_net(pins[a][0])
                ret=ret.replace(a,net_name)
            else:
                for b in range(len(pins[a])):
                    net_name=prefix_node._parse_net(pins[a][b])
                    ret=ret.replace("{0}[{1}]".format(a,b),net_name)

        return ret[:-1]

    def flatten(self,flag=True):
        """Determine which verilog representation to output"""
        self.flat=flag

    def hdl(self,language="verilog"):
        """Return HDL representation of node"""
        if self.flat: return self._flat()
        if language == 'verilog': return self._verilog()
        if language == 'vhdl': return self._vhdl()

    def __str__(self):
        """Currently returns same representation as __repr__"""
        return self.__repr__()

    def __repr__(self):
        """Basic representation of node that can partially recreate it"""
        return "prefix_node({0},{1},{2})".format(self.x,self.y,self.m)

    def __lt__(self,value):
        """Define less-than by position in tree"""
        return (self.x,self.y)<(value.x,value.y)
<commit_msg>Fix prefix_node._flat using incorrect HDL<commit_after>import networkx as nx
import importlib.resources
import pathlib
import shutil
from .modules import modules
from .util import sub_brackets

class prefix_node():
    """Defines a node in the prefix summation graph

    Nodes have an x position (bit), y position (level),
    the module they are representing (black, grey, etc),
    and two dictionary of edges
    """

    def __init__(self, x, y, module, flat=False, custom_module=None):
        """Initializes a node in the prefix summation graph

        Pre-conditions:
        x, y are integers
        module is a valid module from the modules list
        flat is an optional flag to determine how HDL is output
        custom_module is an optional alternative for providing
            a module definition that is not included in modules

        Post-conditions:
        stores all these values into internal variables
        creates two dictionaries of input/output edges
        """
        if not (isinstance(x,int) and isinstance(y,int)):
            raise TypeError("prefix_node x,y must both be integers")

        if module not in modules and not isinstance(custom_module,dict):
            raise ValueError("trying to create node with invalid module")
        if isinstance(custom_module,dict):
            if 'verilog' not in custom_module:
                raise ValueError("custom modules must have valid HDL")
            if 'logic' not in custom_module:
                raise ValueError("custom modules must have valid logic")
            modules[module]=custom_module

        self.x=x; self.y=y; self.m=module; self.flat=flat;

        # Create inputs and outputs dictionaries; initialize to None
        self.ins={x:[None]*y for x,y in modules[self.m]['ins']}
        self.outs={x:[None]*y for x,y in modules[self.m]['outs']}

        # A list of all nodes that directly or indirectly feed into this one
        self.upstream=set()

        # All nodes start, by default, outside of any blocks
        self.block=None

    def _exists(n):
        """Static helper function that checks whether a node is not invis"""
        return n is not None and modules[n.m]['exists']

    def _isbuf(n):
        """Static helper function that checks whether a node is a buffer"""
        return n is not None and modules[n.m]['buf']

    def _in_tree(n):
        """Static helper function that checks whether a node is in the tree"""
        return n is not None and modules[n.m]['type']=='main'

    def _parse_net(x):
        """Static helper function that converts a net's ID to its name in HDL

        These come in 3 possible flavors:
            - None (unassigned net) -> parsed to n0
            - Integer (assigned net) -> parsed to n`Integer
            - Hardcoded name ($net_name) -> parsed to net_name
        """
        if x is None:
            return "n0"
        if isinstance(x,int):
            return "n"+str(x)
        if "$" in x:
            return x.replace("$","")
        raise TypeError("net stored in node {0} is invalid".format(repr(x)))

    def _verilog(self):
        """Return single line of Verilog consisting of module instantiation"""

        # Fill in the module instantiation
        ret="\t{3} {0}_{1}_{2} (".format(self.m,self.x,self.y,self.m)
        
        # Create list of all instance pins and copy in unformatted net IDs
        pins=self.ins.copy()
        pins.update(self.outs)
        
        # Format net IDs and add them to module instantation line
        for a in pins:
            ret+=" ."+a+"( {"
            ret+=','.join(reversed([prefix_node._parse_net(x) for x in pins[a]]))
            ret+='} ),'
        ret=ret[:-1]+' );'
        
        return ret

    def _vhdl(self):
        """Return single line of VHDL consisting of module instantiation"""

        # Fill in the module instantiation
        ret="\t{0}_{1}_{2}: {3}\n".format(self.m,self.x,self.y,self.m)
        ret+="\t\tport map ("

        # Create list of all instance pins and copy in unformatted net IDs
        pins=self.ins.copy()
        pins.update(self.outs)

        # Format net IDs and add them to module instantation line
        for a in pins:
            for b in range(len(pins[a])):
                net_name = prefix_node._parse_net(pins[a][b])
                ret+="\n\t\t\t{0}({1}) => {2},".format(a,b,net_name)

        # Close parenthesis
        ret=ret[:-1]
        ret+="\n\t\t);"

        return ret

    def _flat(self,language="verilog"):
        """Return HDL consisting of the module's logic"""

        ### Grab only instantiated cells from the HDL definiton

        # Iterate over each line in the HDL definition
        hdl_def = modules[self.m][language].splitlines()

        # Flag whether we're currently looking at a cell
        in_std_cell = False

        # Store the filtered HDL in a string
        ret = ''

        for l in hdl_def:
            if 'assign' in l or '<=' in l:
                ret+=l+'\n'
            else:
                if 'U' in l: in_std_cell = True
                if in_std_cell == True: ret += l+'\n'
                if l!='' and l[-1] == ';': in_std_cell = False

        # Create list of all instance pins and copy in unformatted net IDs
        pins=self.ins.copy()
        pins.update(self.outs)

        # Format net IDs and replace them into module's HDL
        for a in pins:
            if len(pins[a])==1:
                net_name=prefix_node._parse_net(pins[a][0])
                ret=ret.replace(a,net_name)
            else:
                for b in range(len(pins[a])):
                    net_name=prefix_node._parse_net(pins[a][b])
                    ret=ret.replace("{0}[{1}]".format(a,b),net_name)

        return ret[:-1]

    def flatten(self,flag=True):
        """Determine which verilog representation to output"""
        self.flat=flag

    def hdl(self,language="verilog"):
        """Return HDL representation of node"""
        if self.flat: return self._flat(language=language)
        if language == 'verilog': return self._verilog()
        if language == 'vhdl': return self._vhdl()

    def __str__(self):
        """Currently returns same representation as __repr__"""
        return self.__repr__()

    def __repr__(self):
        """Basic representation of node that can partially recreate it"""
        return "prefix_node({0},{1},{2})".format(self.x,self.y,self.m)

    def __lt__(self,value):
        """Define less-than by position in tree"""
        return (self.x,self.y)<(value.x,value.y)

{'fraction_non_alphanumeric': 0.10985980234428867, 'fraction_numerical': 0.003983758522944917, 'mean_word_length': 2.18701171875, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5802947', 'n_tokens_mistral': 3882, 'n_tokens_neox': 3648, 'n_words': 1288}