Esempio n. 1
0
    def hardcodeRomIntoProcess(cls, rom):
        """
        Due to verilog restrictions it is not posible to use array constants
        and rom memories has to be hardcoded as process
        """
        processes = []
        signals = []
        for e in rom.endpoints:
            assert isinstance(e, Operator) and e.operator == AllOps.INDEX, e
            me, index = e.operands
            assert me is rom

            # construct output of the rom
            romValSig = rom.ctx.sig(rom.name, dtype=e.result._dtype)
            romValSig.hidden = False
            signals.append(romValSig)

            # construct process which will represent content of the rom
            cases = [(toHVal(i), [romValSig(v), ])
                     for i, v in enumerate(rom.def_val.val)]
            romSwitchStm = SwitchContainer(index, cases)

            for (_, (stm,)) in cases:
                stm.parentStm = romSwitchStm

            p = HWProcess(rom.name, [romSwitchStm, ],
                          {index, }, {index, }, {romValSig, })
            processes.append(p)

            # override usage of original index operator on rom
            # to use signal generated from this process
            for _e in e.result.endpoints:
                _e._replace_input(e.result, romValSig)
        rom.hidden = True
        return processes, signals
Esempio n. 2
0
    def HWProcess(cls, proc: HWProcess, ctx):
        """
        Serialize HWProcess objects
        """
        body = proc.statements
        extraVars = []
        extraVarsSerialized = []

        anyIsEventDependnt = arr_any(
            proc.sensitivityList, lambda s: isinstance(s, Operator))
        sensitivityList = sorted(
            map(lambda s: cls.sensitivityListItem(s, ctx,
                                                  anyIsEventDependnt),
                proc.sensitivityList))

        hasToBeProcess = arr_any(
            proc.outputs,
            lambda x: verilogTypeOfSig(x) == SIGNAL_TYPE.REG
        )

        if hasToBeProcess:
            childCtx = ctx.withIndent()
        else:
            childCtx = ctx

        def createTmpVarFn(suggestedName, dtype):
            s = RtlSignal(None, None, dtype, virtual_only=True)
            s.name = childCtx.scope.checkedName(suggestedName, s)
            s.hidden = False
            serializedS = cls.SignalItem(s, childCtx, declaration=True)
            extraVars.append(s)
            extraVarsSerialized.append(serializedS)
            return s

        childCtx.createTmpVarFn = createTmpVarFn
        statemets = [cls.asHdl(s, childCtx) for s in body]

        if hasToBeProcess:
            proc.name = ctx.scope.checkedName(proc.name, proc)

        extraVarsInit = []
        for s in extraVars:
            a = Assignment(s.def_val, s, virtual_only=True)
            extraVarsInit.append(cls.Assignment(a, childCtx))

        return cls.processTmpl.render(
            indent=getIndent(ctx.indent),
            name=proc.name,
            hasToBeProcess=hasToBeProcess,
            extraVars=extraVarsSerialized,
            sensitivityList=" or ".join(sensitivityList),
            statements=extraVarsInit + statemets
        )
Esempio n. 3
0
    def HWProcess(cls, proc: HWProcess, ctx: HwtSerializerCtx):
        body = proc.statements
        assert body
        proc.name = ctx.scope.checkedName(proc.name, proc)
        sensitivityList = sorted(
            map(cls.sensitivityListItem, proc.sensitivityList))

        _body = "\n".join([cls.stmAsHdl(stm, ctx) for stm in body])

        return processTmpl.render(indent=getIndent(ctx.indent),
                                  name=proc.name,
                                  sensitivityList=sensitivityList,
                                  stmLines=[_body])
Esempio n. 4
0
    def hardcodeRomIntoProcess(cls, rom):
        """
        Due to verilog restrictions it is not posible to use array constants
        and rom memories has to be hardcoded as process
        """
        processes = []
        signals = []
        for e in rom.endpoints:
            assert isinstance(e, Operator) and e.operator == AllOps.INDEX, e
            me, index = e.operands
            assert me is rom

            # construct output of the rom
            romValSig = rom.ctx.sig(rom.name, dtype=e.result._dtype)
            signals.append(romValSig)
            romValSig.hidden = False

            # construct process which will represent content of the rom
            cases = [(toHVal(i), [
                romValSig(v),
            ]) for i, v in enumerate(rom.defVal.val)]
            statements = [
                SwitchContainer(index, cases),
            ]

            for (_, (stm, )) in cases:
                stm.parentStm = statements[0]

            p = HWProcess(rom.name, statements, {
                index,
            }, {
                index,
            }, {
                romValSig,
            })
            processes.append(p)

            # override usage of original index operator on rom
            # to use signal generated from this process
            def replaceOrigRomIndexExpr(x):
                if x is e.result:
                    return romValSig
                else:
                    return x

            for _e in e.result.endpoints:
                _e.operands = tuple(map(replaceOrigRomIndexExpr, _e.operands))
                e.result = romValSig

        return processes, signals
Esempio n. 5
0
    def HWProcess(cls, proc: HWProcess, ctx: SerializerCtx):
        body = proc.statements
        assert body
        proc.name = ctx.scope.checkedName(proc.name, proc)
        sensitivityList = sorted(
            map(cls.sensitivityListItem, proc.sensitivityList))

        childCtx = ctx.withIndent(2)
        _body = "\n".join([cls.stmAsHdl(stm, childCtx) for stm in body])

        return processTmpl.render(hasConditions=arr_any(
            body, lambda stm: not isinstance(stm, Assignment)),
                                  name=proc.name,
                                  sensitivityList=sensitivityList,
                                  stmLines=[_body])
Esempio n. 6
0
def tryToMerge(procA: HWProcess, procB: HWProcess):
    """
    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 (checkIfIsTooSimple(procA) or checkIfIsTooSimple(procB)
            or areSetsIntersets(procA.outputs, procB.sensitivityList)
            or areSetsIntersets(procB.outputs, procA.sensitivityList)
            or not HdlStatement._is_mergable_statement_list(
                procA.statements, procB.statements)):
        raise IncompatibleStructure()

    procA.statements = HdlStatement._merge_statement_lists(
        procA.statements, procB.statements)

    procA.outputs.extend(procB.outputs)
    procA.inputs.extend(procB.inputs)
    procA.sensitivityList.extend(procB.sensitivityList)

    return procA
Esempio n. 7
0
def _statements_to_HWProcesses(_statements, tryToSolveCombLoops)\
        -> Generator[HWProcess, None, None]:
    assert _statements
    # try to simplify statements
    proc_statements = []
    for _stm in _statements:
        stms, _ = _stm._try_reduce()
        proc_statements.extend(stms)

    outputs = UniqList()
    _inputs = UniqList()
    sensitivity = UniqList()
    enclosed_for = set()
    for _stm in proc_statements:
        seen = set()
        _stm._discover_sensitivity(seen)
        _stm._discover_enclosure()
        outputs.extend(_stm._outputs)
        _inputs.extend(_stm._inputs)
        sensitivity.extend(_stm._sensitivity)
        enclosed_for.update(_stm._enclosed_for)

    enclosure_values = {}
    for sig in outputs:
        # inject nopVal if needed
        if sig._useNopVal:
            n = sig._nopVal
            enclosure_values[sig] = n

    if enclosure_values:
        do_enclose_for = list(where(outputs,
                                    lambda o: o in enclosure_values))
        fill_stm_list_with_enclosure(None, enclosed_for, proc_statements,
                                     do_enclose_for, enclosure_values)

    if proc_statements:
        for o in outputs:
            assert not o.hidden, o
        seen = set()
        inputs = UniqList()
        for i in _inputs:
            inputs.extend(i._walk_public_drivers(seen))

        intersect = outputs.intersection_set(sensitivity)
        if intersect:
            if not tryToSolveCombLoops:
                raise HwtSyntaxError(
                    "Combinational loop on signal(s)", intersect)

            # try to solve combinational loops by separating drivers of signals
            # from statements
            for sig in intersect:
                proc_statements, proc_stms_select = cut_off_drivers_of(
                    sig, proc_statements)
                yield from _statements_to_HWProcesses(proc_stms_select, False)

            if proc_statements:
                yield from _statements_to_HWProcesses(proc_statements, False)
        else:
            name = name_for_process(outputs)
            yield HWProcess("assig_process_" + name,
                            proc_statements, sensitivity,
                            inputs, outputs)
    else:
        assert not outputs
        # this can happen e.g. when If does not contains any Assignment
        pass
Esempio n. 8
0
def mkDriverProc(intf, tbCtx):
    d = HWProcess(intf._sigInside.name + "_driver", [], set(), set(), set())
    d.actualTime = -1
    d.driverFor = tbCtx[intf]

    return d