Exemplo n.º 1
0
    def visit_HdlStmProcess(self, proc):
        """
        :type proc: HdlStmProcess
        """
        self.visit_doc(proc)
        sens = proc.sensitivity
        body = proc.body
        w = self.out.write
        skip_body = False
        if sens is None:
            if isinstance(body, HdlStmWait):
                skip_body = True
                wait = body
                body = []
            elif (isinstance(body, HdlStmBlock)
                    and body.body
                    and isinstance(body.body[0], HdlStmWait)):
                wait = body.body[0]
                body = body.body[1:]
            else:
                wait = None

            if wait is None:
                assert self.top_stm is proc
                assert isinstance(body, HdlStmBlock), body
                body = body.body
                wait = body[-1]
                assert isinstance(wait, HdlStmWait), wait
                assert len(wait.val) == 0
                body = body[:-1]
                w("initial")
            else:
                if self.top_stm is proc:
                    w("always ")
                w("#")
                assert len(wait.val) == 1
                self.visit_iHdlExpr(wait.val[0])
            _body = HdlStmBlock()
            _body.body = body
            body = _body
        else:
            if self.top_stm is proc:
                w("always ")
            w("@(")
            for last, item in iter_with_last(sens):
                self.visit_iHdlExpr(item)
                if not last:
                    w(", ")
            w(")")

        # to prevent useless newline for empty always/time waits
        if skip_body:
            return True
        else:
            return self.visit_iHdlStatement_in_statement(body)
Exemplo n.º 2
0
    def as_hdl_IfContainer(self, ifc: IfContainer) -> HdlStmIf:
        """
        .. code-block:: python

            if cond:
                ...
            else:
                ...

        will become

        .. code-block:: python

            c, cVld = sim_eval_cond(cond)
            if not cVld:
                # ivalidate outputs
            elif c:
                ... # original if true branch
            else:
                ... # original if else brach
        """
        invalidate_block = self.as_hdl_IfContainer_out_invalidate_section(
            ifc._outputs, ifc)
        c, cVld, cond_eval = self.as_hdl_IfContainer_cond_eval(ifc.cond)
        _if = HdlStmIf()
        res = HdlStmBlock()
        res.body = [cond_eval, _if]

        _if.cond = HdlOp(HdlOpType.NEG_LOG, [
            cVld,
        ])
        _if.if_true = invalidate_block

        if_true = self.as_hdl_statements(ifc.ifTrue)
        _if.elifs.append((c, if_true))
        elifs = iter(ifc.elIfs)
        for eif_c, eif_stms in elifs:
            c, cVld, cond_eval = self.as_hdl_IfContainer_cond_eval(eif_c)
            newIf = HdlStmIf()
            newIf.cond = HdlOp(HdlOpType.NEG_LOG, [
                cVld,
            ])
            newIf.if_true = invalidate_block

            if_true = self.as_hdl_statements(eif_stms)
            newIf.elifs.append((c, if_true))

            _if.if_false = HdlStmBlock()
            _if.if_false.body = [cond_eval, newIf]
            _if = newIf

        _if.if_false = self.as_hdl_statements(ifc.ifFalse)

        return res
Exemplo n.º 3
0
    def as_hdl_HdlStatementBlock(self, proc: HdlStatementBlock) -> iHdlStatement:
        p = super(ToHdlAstVerilog_statements,
                  self).as_hdl_HdlStatementBlock(proc)
        if isinstance(p, HdlStmProcess):
            no_wait = True
            if isinstance(p.body, HdlStmWait):
                no_wait = False
            elif isinstance(p.body, HdlStmBlock):
                for _o in p.body.body:
                    if isinstance(_o, HdlStmWait):
                        no_wait = False
                        break
            if no_wait and not p.sensitivity:
                # all input are constant and that is why this process does not have
                # any sensitivity
                p.sensitivity = [HdlAll, ]

            # add label
            if not isinstance(p.body, HdlStmBlock):
                b = p.body
                p.body = HdlStmBlock()
                p.body.body.append(b)
            p.body.labels.extend(p.labels)
            p.labels.clear()
        return p
Exemplo n.º 4
0
    def as_hdl_IfContainer_out_invalidate_section(self,
                                                  outputs: List[RtlSignalBase],
                                                  parent: IfContainer):
        outputInvalidateStms = []
        for o in outputs:
            # [TODO] look up indexes
            indexes = None
            v = o._dtype.from_py(None)
            oa = Assignment(v, o, indexes,
                            virtual_only=True, parentStm=parent,
                            is_completly_event_dependent=parent._is_completly_event_dependent)
            outputInvalidateStms.append(self.as_hdl_Assignment(oa))

        if len(outputInvalidateStms) == 1:
            return outputInvalidateStms[0]
        else:
            b = HdlStmBlock()
            b.body = outputInvalidateStms
            return b
Exemplo n.º 5
0
def elifs_to_if_then_else(stm):
    """
    Optionally create if-then-else without else-ifs from this if-then-else statement

    :type stm: HdlStmIf
    :note: non recursive
    """
    if stm.elifs:
        # replace elifs with nested if statements
        ifFalse = HdlStmBlock()
        topIf = HdlStmIf(stm.cond, stm.if_true, ifFalse)

        for c, stms in stm.elifs:
            _ifFalse = HdlStmBlock()

            lastIf = HdlStmIf(c, stms, _ifFalse)

            ifFalse.append(lastIf)
            ifFalse = _ifFalse

        if stm.if_false is None:
            lastIf.if_false = HdlStmBlock()
        else:
            lastIf.if_false = stm.if_false

        return topIf
    return stm
Exemplo n.º 6
0
    def as_hdl_SwitchContainer(self, sw: SwitchContainer) -> HdlStmCase:
        """
        Same as parent as_hdl_SwitchContainer but add "break" to all cases
        """
        sw_hdl = super(ToHdlAstSystemC_statements,
                       self).as_hdl_SwitchContainer(sw)
        new_cases = []
        for c, stm in sw_hdl.cases:
            if not isinstance(stm, HdlStmBlock):
                _stm = HdlStmBlock()
                _stm.body.append(stm)
                stm = _stm

            stm.body.append(HdlStmBreak())
            new_cases.append((c, stm))
        sw_hdl.cases = new_cases
        return sw_hdl
Exemplo n.º 7
0
 def as_hdl_HdlModuleDef_variable(self, v, types, hdl_types, hdl_variables,
                                  processes, component_insts):
     new_v = copy(v)
     with SignalTypeSwap(self, verilogTypeOfSig(v.origin)):
         t = v.type
         # if type requires extra definition
         if self.does_type_requires_extra_def(t, types):
             _t = self.as_hdl_HdlType(t, declaration=True)
             hdl_types.append(_t)
             types.add(t)
         new_v.type = self.as_hdl_HdlType(t, declaration=False)
         # this is a array variable which requires value intialization in init
         # process
         if isinstance(t, HArray):
             if v.value.vld_mask:
                 rom = v.origin
                 p = HdlStmProcess()
                 label = self.name_scope.checked_name(
                     rom.name + "_rom_init", p)
                 p.labels.append(label)
                 p.body = HdlStmBlock()
                 body = p.body.body
                 for i, _v in enumerate(rom.def_val.val):
                     a = HdlStmAssign(self.as_hdl_int(int(_v)),
                                      self.as_hdl(rom[i]))
                     a.is_blocking = True
                     body.append(a)
                 w = HdlStmWait()
                 w.val = []  # initial process
                 body.append(w)
                 processes.append(p)
             # because we would not be able to initialize const/localparam variable later
             new_v.is_const = False
             new_v.value = None
         elif new_v.value is not None:
             new_v.value = self.as_hdl_Value(new_v.value)
         return new_v