def get_wire_t_params(t): """ wire/reg type is actually stored as: t#(width, is_signed) This function extracts t, width, is_signed and potential array dimmensions if this type is an array. """ t, array_dim = collect_array_dims(t) if t in PRIMITIVE_TYPES: is_signed = None if t == HdlValueId("signed"): is_signed = True elif t == HdlValueId("unsigned"): is_signed = False return t, None, is_signed, array_dim # 1b scala if not isinstance( t, HdlOp) or t.fn != HdlOpType.PARAMETRIZATION or len(t.ops) != 3: return None if t.ops[0] not in PRIMITIVE_TYPES: return None t, width, is_signed = t.ops if width == NULL: width = None if is_signed is None: is_signed = None else: is_signed = bool(is_signed) return t, width, is_signed, array_dim
class ToHdlAstVivadoTclExpr(ToHdlAstVhdl2008): _spirit_decode = HdlValueId("spirit:decode") _id = HdlValueId("id") def as_hdl_SignalItem(self, si, declaration=False): assert(declaration == False) if si.hidden: assert si.origin is not None, si return self.as_hdl(si.origin) else: id_ = hdl_call(self._id, [f'MODELPARAM_VALUE.{si.name}']) return hdl_call(self._spirit_decode, [id_])
def _visit_type(self, t): """ :type t: Union[iHdlExpr, iHdlTypeDef] """ if isinstance(t, HdlOp) and t.fn == HdlOpType.INDEX: o0, o1 = t.ops return hdl_index(self._visit_type(o0), o1) elif isinstance(t, HdlTypeBitsDef): width = _verilog_slice_to_width(t.msb, t.lsb) return BitsT(width, bool(t.signed)) elif isinstance(t, HdlValueId): if t == HdlValueId("integer"): return HdlValueId("INT") raise NotImplementedError(t)
def _visit_HdlStmExitOrNext(self, o, stm_name): """ :type o: HdlOp :type stm_name: str :attention: next/exit statement is represented as a call of next/exit function and does not have a specific object, as it is expression it does not render the ending ; """ assert o.fn == HdlOpType.CALL and o.ops[0] == HdlValueId(stm_name), o w = self.out.write w(stm_name) if len(o.ops) == 1: pass elif len(o.ops) == 2: # label w(" ") self.visit_iHdlExpr(o.ops[1]) elif len(o.ops) == 3: # label, condition w(" ") _, label, cond = o.ops self.visit_iHdlExpr(label) w(" WHEN (") self.visit_iHdlExpr(cond) w(")") else: raise ValueError(o)
def visit_HdlModuleDef(self, o): """ :type o: HdlModuleDef """ if o.dec is not None: self.visit_HdlModuleDec(o.dec) self.visit_doc(o) for _o in o.objs: if isinstance(_o, iHdlStatement): self.visit_iHdlStatement(_o) elif isinstance(_o, HdlIdDef): self.visit_HdlIdDef(_o) elif isinstance(_o, HdlCompInst): self.visit_HdlCompInst(_o) elif isinstance(_o, HdlFunctionDef): self.visit_HdlFunctionDef(_o) elif isinstance(_o, HdlModuleDec): # vhdl components self.visit_HdlModuleDec(_o) elif isinstance(_o, HdlOp): assert _o.ops[0] == HdlValueId("assert"), _o self.visit_HdlOp(_o) else: raise NotImplementedError(_o) return o
def visit_type(self, t): """ :type t: iHdlExpr """ t, array_dims = collect_array_dims(t) wire_params = get_wire_t_params(t) if wire_params is None: if t == HdlTypeAuto: t = HdlTypeBitsDef(1) else: base_t, msb, is_signed, _ = wire_params lsb = 0 if msb is None: msb = 0 elif isinstance(msb, HdlOp): if msb.fn == HdlOpType.DOWNTO: msb, lsb = msb.ops elif msb.fn == HdlOpType.TO: lsb, msb = msb.ops elif msb.fn == HdlOpType.CALL and msb.ops[0] == HdlValueId( "slice"): lsb = msb.ops[2] msb = hdl_sub_int(msb.ops[1], 1) t = HdlTypeBitsDef(msb, lsb=lsb, signed=is_signed) for i in array_dims: t = hdl_index(t, i) return t
def visit_HdlIdDef(self, o): """ :type o: HdlIdDef """ if o.type is HdlTypeAuto: if is_str(o.value): o.type = HdlValueId("STR") return o elif isinstance(o.value, HdlValueInt): v = o.value.val if isinstance(v, int) and (v <= 1 and v >= 0): o.type = HdlValueId("BIT") else: o.type = HdlValueId("INT") return o return VerilogResolveTypes.visit_HdlIdDef(self, o)
class ToHdlAstSimModel_types(): """ part of ToHdlAstSimModel responsible for type serialization """ SELF = HdlValueId("self", obj=LanguageKeyword()) BITS3T = HdlValueId("Bits3t", obj=Bits3t) SLICE = HdlValueId("slice", obj=slice) def as_hdl_HdlType_bits(self, typ: Bits, declaration=False): assert not declaration w = typ.bit_length() if isinstance(w, int): pass else: w = int(w) return hdl_call(self.BITS3T, [ HdlValueInt(w, None, None), HdlValueInt(int(bool(typ.signed)), None, None) ]) def as_hdl_HdlType_slice(self, typ: Slice, declaration=False): if declaration: raise NotImplementedError() else: return self.SLICE def as_hdl_HdlType_array(self, typ, declaration=False): if declaration: return super(ToHdlAstSimModel_types, self).as_hdl_HdlType_array(typ, declaration=declaration) else: t_name = self.name_scope.get_object_name(typ) return hdl_getattr(self.SELF, t_name) def as_hdl_HdlType_enum(self, typ, declaration=False): if declaration: return super(ToHdlAstSimModel_types, self).as_hdl_HdlType_enum(typ, declaration=True) else: t_name = self.name_scope.get_object_name(typ) return hdl_getattr(self.SELF, t_name)
def visit_HdlModuleDef(self, o): """ Remove genvar instances as they do not need forward declarations :type o: HdlModuleDef """ genvar = HdlValueId("genvar") o.objs = [ _o for _o in o.objs if not isinstance(_o, HdlIdDef) or _o.type != genvar ] super(VerilogTypesToHwt, self).visit_HdlModuleDef(o) return o
def as_hdl_HdlCompInst(self, o: HdlCompInst) -> HdlCompInst: new_o = copy(o) param_map = [] for p in o.param_map: assert isinstance(p, HdlIdDef), p pm = hdl_map_asoc(HdlValueId(p.name, obj=p), self.as_hdl(p.value)) param_map.append(pm) new_o.param_map = param_map port_map = [] for pi in o.port_map: pm = self.as_hdl_PortConnection(pi) port_map.append(pm) new_o.port_map = port_map return new_o
def as_hdl_HdlType_enum(self, typ: HEnum, declaration=False): ns = self.name_scope if declaration: e = HdlEnumDef() e.origin = typ e.name = ns.checked_name(typ.name, typ) e.values = [(ns.checked_name(n, getattr(typ, n)), None) for n in typ._allValues] dec = HdlIdDef() dec.type = HdlTypeType dec.value = e dec.name = e.name return dec else: name = ns.get_object_name(typ) return HdlValueId(name, obj=None)
def BitsT(width, is_signed=False, bits_cls_name="Bits3t"): """ Create an AST expression of Bits type constructor (reg/std_logic_vector equivalent for BasicHdlSimModel) :type width: iHdlExpr """ width = verilog_slice_to_width(width) if isinstance(width, int): width = HdlValueInt(width, None, None) c = HdlOp(HdlOpType.CALL, [ HdlValueId(bits_cls_name, obj=LanguageKeyword()), width, NONE if is_signed is None else HdlValueInt(int(is_signed), None, None) ]) return c
def as_hdl_HdlType_array(self, typ: HArray, declaration=False): ns = self.name_scope if declaration: dec = HdlIdDef() dec.type = HdlTypeType if self.does_type_requires_extra_def(typ.element_t, ()): # problem there is that we do not have a list of already defined types # so we can not just declare an element type raise NotImplementedError(typ.element_t) dec.value = hdl_index(self.as_hdl_HdlType(typ.element_t, declaration=False), self.as_hdl_int(int(typ.size))) name = getattr(typ, "name", "arr_t_") dec.name = ns.checked_name(name, typ) return dec else: name = ns.get_object_name(typ) return HdlValueId(name, obj=typ)
def BitsT(width, is_signed=False, bits_cls_name="Bits3t"): """ Create an AST expression of Bits type constructor (reg/std_logic_vector equivalent for BasicHdlSimModel) :type width: iHdlExpr """ if isinstance(width, HdlOp): if width.fn == HdlOpType.DOWNTO: high, low = width.ops assert int(low) == 0 width = int(high) + 1 else: raise NotImplementedError(width) c = HdlOp(HdlOpType.CALL, [ HdlValueId(bits_cls_name, obj=LanguageKeyword()), HdlValueInt(width, None, None), NONE if is_signed is None else HdlValueInt(int(is_signed), None, None) ]) return c
def BitsT(width, is_signed=False, bits_cls_name="Bits"): """ Create an AST expression of Bits type constructor (reg/std_logic_vector equivalent for hwt) :type width: iHdlExpr """ width = verilog_slice_to_width(width) if isinstance(width, int): width = HdlValueInt(width, None, None) args = [ HdlValueId(bits_cls_name, obj=LanguageKeyword()), width, ] if is_signed is not None: args.append(HdlValueInt(int(is_signed), None, None)) return HdlOp(HdlOpType.CALL, args)
def as_hdl_HEnumVal(self, val: HEnumVal): name = self.name_scope.get_object_name(val) return HdlValueId(name, obj=val)
from hdlConvertorAst.hdlAst import HdlValueId, HdlOp, HdlOpType, HdlTypeAuto PRIMITIVE_TYPES = ( HdlValueId("reg"), HdlValueId("wire"), HdlValueId("bit"), HdlValueId("logic"), HdlValueId("signed"), HdlValueId("unsigned"), HdlTypeAuto, ) NULL = HdlValueId("null") def collect_array_dims(t): array_dim = [] while isinstance(t, HdlOp) and t.fn == HdlOpType.INDEX: assert len(t.ops) <= 2 if len(t.ops) == 2: d = t.ops[1] else: d = None array_dim.append(d) t = t.ops[0] array_dim.reverse() return t, array_dim def get_wire_t_params(t): """
def visit_HdlOp(self, o): """ :type o: HdlOp """ o = HdlAstModifier.visit_HdlOp(self, o) op = o.fn if op == HdlOpType.EQ or op == HdlOpType.XNOR: # HdlOpType.EQ: '%s._eq(%s)', to_property_call(o, "_eq") elif op == HdlOpType.CONCAT: to_property_call(o, "_concat") elif op == HdlOpType.TERNARY: to_property_call(o, "_ternary__val") elif op == HdlOpType.DOWNTO: if self.downto_to_slice_fn: o.fn = HdlOpType.CALL o.ops = [ HdlValueId("slice"), hdl_add_int(o.ops[0], 1), o.ops[1] ] else: o.ops = [hdl_add_int(o.ops[0], 1), o.ops[1]] elif op == HdlOpType.TO: raise NotImplementedError(o) elif op == HdlOpType.CALL: fn = o.ops[0] if fn == HdlValueId("$display"): o.ops = [ HdlValueId("print"), ] + o.ops[1:] elif fn == HdlValueId("$finish"): t = HdlStmThrow() t.val = hdl_call(HdlValueId("Exception"), []) return t elif fn == HdlValueId("$time"): return hdl_getattr(HdlValueId("sim"), "now") elif fn == HdlValueId("$rtoi"): o.ops = [ HdlValueId("int"), ] + o.ops[1:] else: return hdl_call(hdl_getattr(HdlValueId("self"), fn.val), o.ops[1:]) elif op == HdlOpType.REPL_CONCAT: n, v = o.ops return hdl_call(HdlValueId("replicate"), [n, v]) elif op in (HdlOpType.AND_LOG, HdlOpType.OR_LOG, HdlOpType.NEG_LOG): ops = [hdl_call(hdl_getattr(_o, "_isOn"), []) for _o in o.ops] if op == HdlOpType.AND_LOG: new_o_fn = HdlOpType.AND elif op == HdlOpType.OR_LOG: new_o_fn = HdlOpType.OR else: assert op == HdlOpType.NEG_LOG new_o_fn = HdlOpType.NEG return HdlOp(new_o_fn, ops) elif op == HdlOpType.PART_SELECT_POST: # logic [31: 0] a; # a[ 0 +: 8] == a[ 7 : 0]; # logic [0 :31] b; # b[ 0 +: 8] == b[0 : 7] high, width = o.ops o.fn = HdlOpType.CALL o.ops = [ HdlValueId("slice"), high, HdlOp(HdlOpType.SUB, [deepcopy(high), width]) ] return o
class ToHwt(ToHwtStm): """ Convert hdlObject AST to BasicHdlSimModel (Python simulation model used by hwtSimApi simulator) :ivar _is_param: flag which specifies if the current HdlIdDef is a param/generic :ivar _is_port: flag which specifies if the current HdlIdDef is a port """ ALL_STATEMENT_CLASSES = ALL_STATEMENT_CLASSES VAR_PER_LINE_LIMIT = 10 TYPES_WHICH_CAN_BE_OMMITED = (HdlValueId("INT"), HdlValueId("STR"), HdlValueId("BOOL"), HdlValueId("FLOAT")) def __init__(self, out_stream): ToHdlCommon.__init__(self, out_stream) self.module_path_prefix = None self.add_imports = True self._is_port = False self._is_param = False def visit_doc(self, obj, doc_string=False): if doc_string: doc = obj.doc if doc is not None: doc = doc.split("\n") w = self.out.write if len(doc) > 1: w('"""') for d in doc: w(d.replace('\r', '')) w("\n") w('"""\n') else: w('"') if doc: w(doc[0].replace('\r', '')) w('"\n') else: return super(ToHwt, self).visit_doc(obj, "#") def add_module_exampe_serialization(self, module_name): w = self.out.write w('if __name__ == "__main__":\n') with Indent(self.out): w("from hwt.synthesizer.utils import to_rtl_str\n") w("u = ") w(module_name) w("()\n") w("print(to_rtl_str(u))\n") def ivars_to_local_vars(self, var_names): if var_names: w = self.out.write VAR_PER_LINE_LIMIT = self.VAR_PER_LINE_LIMIT # ports and params to locals for i, (last, name) in enumerate(iter_with_last(var_names)): w(name) if not last: w(", ") if i % VAR_PER_LINE_LIMIT == 0 and i > 0: # jump to new line to have reasonably long variable list w("\\\n") w(" = \\\n") for i, (last, name) in enumerate(iter_with_last(var_names)): w("self.") w(name) if not last: w(", ") if i % VAR_PER_LINE_LIMIT == 0 and i > 0: # jump to new line to have reasonably long variable list w("\\\n") w("\n") def visit_HdlModuleDef(self, mod_def): """ :type mod_def: HdlModuleDef """ mod_dec = mod_def.dec assert mod_dec is not None, mod_def assert not mod_dec.objs, mod_dec w = self.out.write if self.add_imports: w(DEFAULT_IMPORTS) w("\n") if self.module_path_prefix is None: self.add_imports = False split_HdlModuleDefObjs = method_as_function(ToBasicHdlSimModel.split_HdlModuleDefObjs) otherDefs, variables, processes, components = \ split_HdlModuleDefObjs(self, mod_def.objs) method_as_function(ToBasicHdlSimModel.visit_component_imports)(self, components) w("class ") w(mod_dec.name) w("(Unit):\n") with Indent(self.out): self.visit_doc(mod_dec, doc_string=True) params_names = [] if mod_dec.params: w('def _config(self):\n') with Indent(self.out): try: self._is_param = True for p in mod_dec.params: self.visit_HdlIdDef(p, None) params_names.append(p.name) finally: self._is_param = False w("\n") types = [] for d in otherDefs: if isinstance(d, HdlFunctionDef): self.visit_HdlFunctionDef(d) elif isinstance(d, iHdlTypeDef): types.append(d) else: raise NotImplementedError(d) names_of_constants = set(params_names) port_params_comp_names = [*params_names] w('def _declr(self):\n') with Indent(self.out): self.ivars_to_local_vars(port_params_comp_names) for t in types: self.visit_type_declr(t) w('# ports\n') try: self._is_port = True for p in mod_dec.ports: self.visit_HdlIdDef(p, names_of_constants) port_params_comp_names.append(p.name) finally: self._is_port = False w("# component instances\n") for c in components: if c.param_map: w(c.name.val) w(" = ") w("self.") w(c.name.val) w(" = ") w(c.module_name.val) w('()\n') port_params_comp_names.append(c.name.val) for cp in c.param_map: mod_p, val = pop_port_or_param_map(cp) w(c.name.val) w(".") w(mod_p.val) w(" = ") self.visit_iHdlExpr(val) w("\n") w("\n") w("def _impl(self):\n") with Indent(self.out): self.ivars_to_local_vars(port_params_comp_names) w("# internal signals\n") for v in variables: self.visit_HdlIdDef(v, names_of_constants) for c in components: for pm in c.port_map: mod_port, connected_sig = pop_port_or_param_map(pm) assert isinstance( connected_sig, HdlValueId), connected_sig p = mod_port.obj assert p is not None, ( "HdlValueId to module ports " "shoudl have been discovered before") d = p.direction assert d.name in (HdlDirection.IN.name, HdlDirection.OUT.name), d is_input = d.name == HdlDirection.IN.name if is_input: w(c.name.val) w(".") self.visit_iHdlExpr(mod_port) w("(") self.visit_iHdlExpr(connected_sig) w(")\n") else: self.visit_iHdlExpr(connected_sig) w("(") w(c.name.val) w(".") self.visit_iHdlExpr(mod_port) w(")\n") for p in processes: self.visit_iHdlStatement(p) # extra line to separate a process functions w("\n") # w("\n") # w("\n") # self.add_module_exampe_serialization(mod_dec.name) def visit_HdlFunctionDef(self, o): """ :type o: HdlFunctionDef """ w = self.out.write w("def ") w(o.name) w("(self") for p in o.params: w(", ") w(p.name) w("):\n") with Indent(self.out): self.visit_doc(o, doc_string=True) for stm in o.body: self.visit_iHdlStatement(stm) w("\n") w("\n") def visit_HdlIdDef(self, var, names_of_constants): """ :type var: HdlIdDef """ self.visit_doc(var) w = self.out.write if self._is_port or self._is_param: w("self.") w(var.name) if self._is_port: w(" = Signal(") if var.type != HdlValueId("BIT"): self.visit_type(var.type) w(")") if var.direction == HdlDirection.OUT: w("._m()\n") else: w("\n") assert var.direction == HdlDirection.IN, var.direction elif self._is_param: w(" = Param(") if var.type in self.TYPES_WHICH_CAN_BE_OMMITED: # ommit the type specification in the case where the type can be resolved from value type self.visit_iHdlExpr(var.value) w(")\n") else: self.visit_type(var.type) w(".from_py(") self.visit_iHdlExpr(var.value) w("))\n") elif var.is_const: names_of_constants.add(var.name) w(" = ") if var.type in self.TYPES_WHICH_CAN_BE_OMMITED: self.visit_iHdlExpr(var.value) w("\n") else: self.visit_type(var.type) w(".from_py(") self.visit_iHdlExpr(var.value) w(")\n") else: # body signal if var.value is not None and var.value != HdlValueId("None") and is_not_const(var.value, names_of_constants): w(' = rename_signal(self, ') self.visit_iHdlExpr(var.value) w(', "') w(var.name) w('")\n') else: w(' = self._sig(') with Indent(self.out): w('"') w(var.name) if var.type == HdlValueId("BIT"): w('"') else: w('", ') self.visit_type(var.type) if var.value is None: w(")\n") else: w(", def_val=") self.visit_iHdlExpr(var.value) w(")\n")
def visit_HdlIdDef(self, var, names_of_constants): """ :type var: HdlIdDef """ self.visit_doc(var) w = self.out.write if self._is_port or self._is_param: w("self.") w(var.name) if self._is_port: w(" = Signal(") if var.type != HdlValueId("BIT"): self.visit_type(var.type) w(")") if var.direction == HdlDirection.OUT: w("._m()\n") else: w("\n") assert var.direction == HdlDirection.IN, var.direction elif self._is_param: w(" = Param(") if var.type in self.TYPES_WHICH_CAN_BE_OMMITED: # ommit the type specification in the case where the type can be resolved from value type self.visit_iHdlExpr(var.value) w(")\n") else: self.visit_type(var.type) w(".from_py(") self.visit_iHdlExpr(var.value) w("))\n") elif var.is_const: names_of_constants.add(var.name) w(" = ") if var.type in self.TYPES_WHICH_CAN_BE_OMMITED: self.visit_iHdlExpr(var.value) w("\n") else: self.visit_type(var.type) w(".from_py(") self.visit_iHdlExpr(var.value) w(")\n") else: # body signal if var.value is not None and var.value != HdlValueId("None") and is_not_const(var.value, names_of_constants): w(' = rename_signal(self, ') self.visit_iHdlExpr(var.value) w(', "') w(var.name) w('")\n') else: w(' = self._sig(') with Indent(self.out): w('"') w(var.name) if var.type == HdlValueId("BIT"): w('"') else: w('", ') self.visit_type(var.type) if var.value is None: w(")\n") else: w(", def_val=") self.visit_iHdlExpr(var.value) w(")\n")
def _parse_hdlConvertor_json(j): # handle primitive types if j is None: return j elif isinstance(j, float): return j elif is_str(j): return HdlValueId(j) elif isinstance(j, int): return HdlValueInt(j, None, None) elif isinstance(j, list): return [_parse_hdlConvertor_json(_j) for _j in j] # load a hdlAst object cls = j["__class__"] cls = KNOWN_NODES[cls] consumed = { "__class__", } if cls in NON_INSTANCIABLE_NODES: assert len(j) == 1 return cls elif cls in (dict, list, tuple): _items = j["items"] items = [_parse_hdlConvertor_json(i) for i in _items] if cls is dict: return {k: v for k, v in items} elif cls is tuple: return tuple(items) else: return items elif cls is str: return j["val"] elif cls is HdlValueInt: return HdlValueInt(j["val"], j.get("bits", None), j.get("base", None)) argc = cls.__init__.__code__.co_argcount if argc == 1: o = cls() else: # load argumets for __init__ argv = [] # 1st is self arg_names = cls.__init__.__code__.co_varnames[1:argc] for a in arg_names: v = j.get(a, None) if a == "fn": v = getattr(HdlOpType, v) else: v = _parse_hdlConvertor_json(v) argv.append(v) consumed.add(a) o = cls(*argv) not_consumed = set(j.keys()).difference(consumed) if not_consumed: # load rest of the properties which were not in __init__ params for k in not_consumed: v = j[k] # there are few cases where object class is not specified specified # explicitly we have to handle them first if k == "position": _v = CodePosition() (_v.start_line, _v.start_column, _v.stop_line, _v.stop_column) = v elif k == "direction": if v is None: _v = v else: _v = getattr(HdlDirection, v) elif k == "join_t": _v = getattr(HdlStmBlockJoinType, v) elif k == "trigger_constrain": _v = getattr(HdlStmProcessTriggerConstrain, v) elif cls is HdlStmCase and k == "type": _v = getattr(HdlStmCaseType, v) else: _v = _parse_hdlConvertor_json(v) setattr(o, k, _v) return o
def add_io_prefix(o): s = HdlValueId("self") s = hdl_getattr(s, "io") return hdl_name_prefix(s, o)
def create_HdlModuleDef(self, target_platform: DummyPlatform, store_manager: "StoreManager"): ctx = self._ctx mdef = HdlModuleDef() mdef.dec = ctx.ent mdef.module_name = HdlValueId(ctx.ent.name, obj=ctx.ent) mdef.name = "rtl" # constant signals which represents the param/generic values param_signals = [ ctx.sig(p.hdl_name, p.get_hdl_type(), def_val=p.get_hdl_value()) for p in sorted(self._params, key=lambda x: x.hdl_name) ] # rewrite ports to use generic/params of this entity/module port_type_variants = self._collectPortTypeVariants() self._injectParametersIntoPortTypes(port_type_variants, param_signals) for p in param_signals: p._const = True p.hidden = False # instanciate component variants in if generate statement ns = store_manager.name_scope as_hdl_ast = self._store_manager.as_hdl_ast if_generate_cases = [] for u in self._units: # create instance ci = HdlCompInst() ci.origin = u ci.module_name = HdlValueId(u._ctx.ent.name, obj=u._ctx.ent) ci.name = HdlValueId(ns.checked_name(u._name + "_inst", ci), obj=u) e = u._ctx.ent ci.param_map.extend(e.params) # connect ports assert len(e.ports) == len(ctx.ent.ports) for p, parent_port in zip(e.ports, ctx.ent.ports): i = p.getInternSig() parent_port_sig = parent_port.getInternSig() assert i.name == parent_port_sig.name o = p.getOuterSig() # can not connect directly to parent port because type is different # but need to connect to something with the same nme if o is p.src: p.src = p.dst else: assert o is p.dst, (o, p.dst) p.dst = p.src ci.port_map.append(p) # create if generate instanciation condition param_cmp_expr = BIT.from_py(1) assert len(u._params) == len(param_signals) for p, p_sig in zip(sorted(u._params, key=lambda x: x.hdl_name), param_signals): assert p.hdl_name == p_sig.name, (p.hdl_name, p_sig.name) param_cmp_expr = param_cmp_expr & p_sig._eq(p.get_hdl_value()) # add case if generate statement _param_cmp_expr = as_hdl_ast.as_hdl(param_cmp_expr) ci = as_hdl_ast.as_hdl_HdlCompInst(ci) b = HdlStmBlock() b.body.append(ci) b.in_preproc = True if_generate_cases.append((_param_cmp_expr, b)) if_generate = HdlStmIf() if_generate.in_preproc = True if_generate.labels.append( ns.checked_name("implementation_select", if_generate)) for c, ci in if_generate_cases: if if_generate.cond is None: if_generate.cond = c if_generate.if_true = ci else: if_generate.elifs.append((c, ci)) mdef.objs.append(if_generate) for p in ctx.ent.ports: s = p.getInternSig() if p.direction != DIRECTION.IN: s.drivers.append(if_generate) else: s.endpoints.append(if_generate) ctx.arch = mdef return mdef
from hdlConvertorAst.hdlAst import HdlValueId, HdlOpType, HdlValueInt, HdlOp, iHdlExpr from hdlConvertorAst.translate.common.name_scope import LanguageKeyword NONE = HdlValueId("None") def verilog_slice_to_width(width): """ :type width: iHdlExpr :return: Union[int, iHdlExpr] """ if isinstance(width, HdlOp): if width.fn in (HdlOpType.DOWNTO, HdlOpType.TO): if width.fn == HdlOpType.DOWNTO: high, low = width.ops else: low, high = width.ops return _verilog_slice_to_width(high, low) return width def _verilog_slice_to_width(high, low): """ :type high: Union[int, iHdlExpr] :type low: Union[int, iHdlExpr] :return: Union[int, iHdlExpr] """ if isinstance(low, (int, HdlValueInt)) and isinstance(high, (int, HdlValueInt)): assert int(low) == 0, low
HdlOpType.ASSIGN, HdlOpType.PLUS_ASSIGN, HdlOpType.MINUS_ASSIGN, HdlOpType.MUL_ASSIGN, HdlOpType.DIV_ASSIGN, HdlOpType.MOD_ASSIGN, HdlOpType.AND_ASSIGN, HdlOpType.OR_ASSIGN, HdlOpType.XOR_ASSIGN, HdlOpType.SHIFT_LEFT_ASSIGN, HdlOpType.SHIFT_RIGHT_ASSIGN, HdlOpType.ARITH_SHIFT_LEFT_ASSIGN, HdlOpType.ARITH_SHIFT_RIGHT_ASSIGN, ] SIGNED = HdlValueId("signed") def pop_signed_flag(o): """ :type op: HdlOp pop signed/unsigned flag from type expr """ base_expr = o is_signed = None if o.fn == HdlOpType.PARAMETRIZATION and len(o.ops) == 2: op1 = o.ops[1] if isinstance(op1, HdlOp) and\ op1.fn == HdlOpType.MAP_ASSOCIATION and\
class ToHdlAstVhdl2008_Value(ToHdlAst_Value): TRUE = HdlValueId("TRUE", obj=LanguageKeyword()) FALSE = HdlValueId("FALSE", obj=LanguageKeyword()) #TO_UNSIGNED = HdlValueId("TO_UNSIGNED", obj=LanguageKeyword()) #TO_SIGNED = HdlValueId("TO_SIGNED", obj=LanguageKeyword()) def as_hdl_cond(self, c, forceBool): assert isinstance(c, (RtlSignalBase, HValue)), c if not forceBool or c._dtype == BOOL: return self.as_hdl(c) elif c._dtype == BIT: return self.as_hdl(c._eq(1)) elif isinstance(c._dtype, Bits): return self.as_hdl(c != 0) else: raise NotImplementedError() def as_hdl_HEnumVal(self, val: HEnumVal): name = self.name_scope.get_object_name(val) return HdlValueId(name, obj=val) def as_hdl_HArrayVal(self, val): return [self.as_hdl_Value(v) for v in val] def sensitivityListItem(self, item, anyIsEventDependnt): if isinstance(item, Operator): item = item.operands[0] return self.as_hdl(item) def as_hdl_BitString(self, v, width: int, force_vector: bool, vld_mask: int, signed): is_bit = not force_vector and width == 1 #if vld_mask != mask(width) or width >= 32 or is_bit: v = bit_string(v, width, vld_mask) if is_bit: v.base = 256 return v if signed is None: return v elif signed: cast = self.SIGNED else: cast = self.UNSIGNED return HdlOp(HdlOpType.APOSTROPHE, [cast, v]) #else: # v = HdlValueInt(v, None, None) # # if signed is None: # return v # elif signed: # cast_fn = self.TO_SIGNED # else: # cast_fn = self.TO_UNSIGNED # return hdl_call(cast_fn, [v, HdlValueInt(width, None, None)]) def as_hdl_BoolVal(self, val: BitsVal): if val.val: return self.TRUE else: return self.FALSE def as_hdl_BitsVal(self, val: BitsVal): t = val._dtype v = super(ToHdlAstVhdl2008_Value, self).as_hdl_BitsVal(val) # handle '1' vs "1" difference (bit literal vs vector) if not t.force_vector and t.bit_length() == 1 and t != BOOL: if isinstance(v, HdlValueInt): v.base = 256 else: # assert is cast assert isinstance(v, HdlOp) and v.fn == HdlOpType.CALL, v _v = v.ops[1] if isinstance(_v, HdlValueInt): _v.base = 256 else: raise NotImplementedError() return v def as_hdl_SliceVal(self, val: SliceVal): upper = val.val.start if int(val.val.step) == -1: if isinstance(upper, HValue): upper = HdlValueInt(int(upper) - 1, None, None) else: upper = HdlOp(HdlOpType.SUB, [self.as_hdl_Value(upper), HdlValueInt(1, None, None)]) else: raise NotImplementedError(val.val.step) return HdlOp(HdlOpType.DOWNTO, [upper, self.as_hdl(val.val.stop)])