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 )
def Assignment(cls, a: Assignment, ctx): dst = a.dst assert isinstance(dst, SignalItem) # dstSignalType = verilogTypeOfSig(dst) indent_str = getIndent(ctx.indent) _dst = dst if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.__copy__() dst = dst[i] dstStr = cls.asHdl(dst, ctx) ver_sig_t = verilogTypeOfSig(_dst) if ver_sig_t == SIGNAL_TYPE.REG: evDep = False for driver in _dst.drivers: if driver._now_is_event_dependent: evDep = True break if not evDep or _dst.virtual_only: prefix = "" symbol = "=" else: prefix = "" symbol = "<=" elif ver_sig_t == SIGNAL_TYPE.WIRE: if a.parentStm is None: prefix = "assign " else: prefix = "" symbol = "=" else: ValueError(ver_sig_t) firstPartOfStr = "%s%s%s" % (indent_str, prefix, dstStr) src_t = a.src._dtype dst_t = dst._dtype srcStr = cls.Value(a.src, ctx) if dst_t == src_t \ or (isinstance(src_t, Bits) and isinstance(dst_t, Bits) and src_t.bit_length() == dst_t.bit_length() == 1): return "%s %s %s;" % (firstPartOfStr, symbol, srcStr) else: raise SerializerException("%s %s %s is not valid assignment\n" " because types are different (%r; %r) " % (dstStr, symbol, srcStr, dst._dtype, a.src._dtype))
def PortItem(cls, pi, ctx): t = cls.HdlType(pi._dtype, ctx.forPort()) if verilogTypeOfSig(pi.getInternSig()) == SIGNAL_TYPE.REG: if t: f = "%s reg %s %s" else: f = "%s reg %s" else: if t: f = "%s %s %s" else: f = "%s %s" if t: return f % (cls.DIRECTION(pi.direction), t, pi.name) else: return f % (cls.DIRECTION(pi.direction), pi.name)
def as_hdl_Assignment(self, a: Assignment): blocking = False ver_sig_t = verilogTypeOfSig(a.dst) if ver_sig_t in (SIGNAL_TYPE.REG, SIGNAL_TYPE.PORT_REG): evDep = False for driver in a.dst.drivers: if driver._now_is_event_dependent: evDep = True break if not evDep or a.dst.virtual_only: blocking = True elif ver_sig_t in (SIGNAL_TYPE.WIRE, SIGNAL_TYPE.PORT_WIRE): blocking = True else: raise ValueError(ver_sig_t) a = super(ToHdlAstVerilog_statements, self).as_hdl_Assignment(a) a.is_blocking = blocking return a
def Assignment(cls, a, ctx): dst = a.dst assert isinstance(dst, SignalItem) def valAsHdl(v): return cls.Value(v, ctx) dstSignalType = verilogTypeOfSig(dst) assert not dst.virtualOnly if dstSignalType is SIGNAL_TYPE.REG: prefix = "" symbol = "<=" else: prefix = "assign " symbol = "=" if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.clone() i.val = (i.val[0], i.val[1]) dst = dst[i] indent_str = getIndent(ctx.indent) dstStr = cls.asHdl(dst, ctx) firstPartOfStr = "%s%s%s" % (indent_str, prefix, dstStr) src_t = a.src._dtype dst_t = dst._dtype if dst_t == src_t \ or (isinstance(src_t, Bits) and isinstance(dst_t, Bits) and src_t.bit_length() == dst_t.bit_length() == 1): return "%s %s %s;" % (firstPartOfStr, symbol, valAsHdl(a.src)) else: raise SerializerException( "%s %s %s is not valid assignment\n" " because types are different (%r; %r) " % (dstStr, symbol, valAsHdl(a.src), dst._dtype, a.src._dtype))
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
def as_hdl_SignalItem(self, si, declaration=False): if declaration: with SignalTypeSwap(self, verilogTypeOfSig(si)): return ToHdlAst_Value.as_hdl_SignalItem(self, si) else: return ToHdlAst_Value.as_hdl_SignalItem(self, si)
def forSignal(self, signalItem): ctx = copy(self) ctx.signalType = verilogTypeOfSig(signalItem) return ctx
def has_to_be_process(self, proc: HdlStatementBlock): for o in proc._outputs: if verilogTypeOfSig(o) in (SIGNAL_TYPE.REG, SIGNAL_TYPE.PORT_REG): return True return False
def as_hdl_HdlPortItem(self, pi: HdlPortItem): with SignalTypeSwap(self, verilogTypeOfSig(pi)): v = super(ToHdlAstVerilog, self).as_hdl_HdlPortItem(pi) v.is_latched = self.signalType == SIGNAL_TYPE.PORT_REG return v