Source code for hwt.synthesizer.rtlLevel.reduce_processes

from itertools import islice

from hwt.doc_markers import internal
from hwt.hdl.statements.assignmentContainer import HdlAssignmentContainer
from hwt.hdl.statements.codeBlockContainer import HdlStmCodeBlockContainer
from hwt.hdl.statements.utils.reduction import HdlStatement_merge_statement_lists, \
    is_mergable_statement_list
from hwt.pyUtils.arrayQuery import areSetsIntersets, groupedby
from hwt.serializer.utils import HdlStatement_sort_key


[docs]class HwtStmIncompatibleStructure(Exception): """ Statements are not comparable due incompatible structure """
[docs]@internal def checkIfIsTooSimple(proc): """check if process is just unconditional assignments and it is useless to merge them""" try: a, = proc.statements if isinstance(a, HdlAssignmentContainer): return True except ValueError: pass return False
[docs]@internal def tryToMerge(procA: HdlStmCodeBlockContainer, procB: HdlStmCodeBlockContainer): """ Try merge procB into procA :raise IncompatibleStructure: if merge is not possible :attention: procA is now result if merge has succeed :return: procA which is now result of merge """ if (areSetsIntersets(procA._outputs, procB._sensitivity) or areSetsIntersets(procB._outputs, procA._sensitivity) or not is_mergable_statement_list(procA.statements, procB.statements)): raise HwtStmIncompatibleStructure() procA.statements = HdlStatement_merge_statement_lists( procA.statements, procB.statements) procB.statements = None procA._outputs.extend(procB._outputs) procA._inputs.extend(procB._inputs) procA._sensitivity.extend(procB._sensitivity) return procA
[docs]@internal def reduceProcesses(processes): """ Try to merge processes as much is possible :param processes: list of processes instances """ # sort to make order of merging same deterministic processes.sort(key=HdlStatement_sort_key, reverse=True) # now try to reduce processes with nearly same structure of statements into one # to minimize number of processes for _, procs in groupedby(processes, lambda p: p.rank): _procs = [] for p in procs: if checkIfIsTooSimple(p): yield p else: _procs.append(p) procs = _procs for iA, pA in enumerate(procs): if pA is None: continue for iB, pB in enumerate(islice(procs, iA + 1, None)): if pB is None: continue try: pA = tryToMerge(pA, pB) except HwtStmIncompatibleStructure: continue procs[iA + 1 + iB] = None # procs[iA] = pA for p in procs: if p is not None: yield p