def output(self, name, width, is_signed=False, size=1, port_type=PortType.Data): self.definition.add_definition(name, width, size, is_signed, PortDirection.Out, port_type) if self.debug: self.definition.add_debug_info(name, get_fn_ln())
def reset(self, name, is_input=True, is_async=True, active_high=None): direction = PortDirection.In if is_input else PortDirection.Out reset = PortType.AsyncReset if is_async else PortType.Reset p = self.__generator.port(direction.value, name, 1, 1, reset.value, False) if self.debug: p.add_fn_ln(get_fn_ln()) if active_high is not None: p.active_high = active_high return p
def add_child_generator(self, instance_name: str, generator: "Generator", comment="", python_only=False, **kargs): if self.is_cloned: self.__cached_initialization.append( (self.add_child_generator, (instance_name, generator))) return if instance_name in self.__child_generator: raise Exception("{0} already exists in {1}".format( instance_name, self.instance_name)) assert isinstance(generator, Generator), "generator is not a Generator instance" self.__child_generator[instance_name] = generator generator.__parent = self if python_only: # only add it to the python level interface, the caller is # responsible for the connections etc return else: generator.__generator.instance_name = instance_name if self.debug: fn, ln = get_fn_ln() self.__generator.add_child_generator(instance_name, generator.__generator, (fn, ln)) else: self.__generator.add_child_generator(instance_name, generator.__generator) if comment: self.__generator.set_child_comment(instance_name, comment) # set parameter values first for child_param, parent_value in kargs.items(): if child_param in generator.params: generator.params[child_param].value = parent_value # bulk wiring for child_port, parent_port in kargs.items(): # it can be parameter as well. we already taken care of that if child_port in generator.params: continue if isinstance(parent_port, str): if parent_port in self.ports: parent_port = self.ports[parent_port] else: parent_port = self.vars[parent_port] self.wire(generator.ports[child_port], parent_port, additional_frame=1)
def case_(self, cond: _kratos.Var, *args: _kratos.Stmt): if isinstance(cond, int): cond = const(cond, self.__predicate.width, self.__predicate.signed) case = None for stmt in args: if not isinstance(stmt, _kratos.Stmt): stmt = stmt.stmt() case = self._stmt.add_switch_case(cond, stmt) assert case is not None if self.__generator.debug: case.add_fn_ln(get_fn_ln())
def __init__(self, name: str, debug: bool = False, is_clone: bool = False, internal_generator=None): """ Base class for all generators :param name: generator name :param debug: set to ``True`` if you want to collect debug information on this particular generator :param is_clone: mark whether the generator is a clone or not. :param internal_generator: native C++ handle """ # for initialization self.__cached_initialization = [] if internal_generator is not None: assert isinstance(internal_generator, _kratos.Generator) self.__generator = internal_generator else: if not is_clone and len(name) > 0: self.__generator = self.__context.generator(name) else: self.__generator = self.__context.empty_generator() self.__generator.is_cloned = True self.__set_generator_name(name) self.__child_generator: Dict[str, Generator] = {} if not debug: self.debug = get_global_debug() else: self.debug = debug if debug: fn, ln = get_fn_ln(Generator.__inspect_frame_depth) self.__generator.add_fn_ln((fn, ln)) # gemstone style port interface self.ports = PortProxy(self) self.params = ParamProxy(self) self.vars = VarProxy(self) self.interfaces = InterfaceProxy(self) self.__def_instance = self # helper function data self.__reg_next_stmt = {} self.__reg_init_stmt = {} self.__reg_en_stmt = {} # meta data self.__stmt_label_mapping = {} self.__parent = None
def __init__(self, generator, block_type: StatementBlockType, debug_frame_depth): self.block_type = block_type self._generator = generator if block_type == StatementBlockType.Combinational: self._block = generator.internal_generator.combinational() elif block_type == StatementBlockType.Initial: self._block = generator.internal_generator.initial() elif block_type == StatementBlockType.Latch: self._block = generator.internal_generator.latch() else: self._block = generator.internal_generator.sequential() if generator.debug: fn, ln = get_fn_ln(debug_frame_depth) self._block.add_fn_ln((fn, ln))
def port(self, name: str, width: Union[int, _kratos.Param, _kratos.Enum], direction: PortDirection, port_type: PortType = PortType.Data, is_signed: bool = False, size: Union[int, Union[List, Tuple]] = 1, packed: bool = False, explicit_array: bool = False) -> _kratos.Port: size, params = self.__filter_size(size) if isinstance(width, _kratos.Enum): p = self.__generator.port(direction.value, name, width) else: p = self.__generator.port(direction.value, name, width, size, port_type.value, is_signed) if self.debug: p.add_fn_ln(get_fn_ln()) p.is_packed = packed p.explicit_array = explicit_array self.__set_var_size(p, params) return p
def var(self, name: str, width: Union[int, _kratos.Param, _kratos.Enum, _kratos.PackedStruct], is_signed: bool = False, size: Union[int, Union[List, Tuple]] = 1, packed: bool = False, explicit_array: bool = False) -> _kratos.Var: size, params = self.__filter_size(size) if isinstance(width, _kratos.Enum): v = self.__generator.enum_var(name, width) elif isinstance(width, _kratos.PackedStruct): v = self.__generator.var_packed(name, width, size) else: v = self.__generator.var(name, width, size, is_signed) if self.debug: v.add_fn_ln(get_fn_ln()) if not isinstance(width, _kratos.PackedStruct): v.is_packed = packed v.explicit_array = explicit_array self.__set_var_size(v, params) return v
def __init__(self, predicate: _kratos.Var): self._stmt = _kratos.IfStmt(predicate) self.__generator = predicate.generator if self.__generator.debug: self._stmt.add_fn_ln(get_fn_ln())
def __init__(self, predicate: _kratos.Var): self._stmt = _kratos.SwitchStmt(predicate) if predicate.generator.debug: self._stmt.add_fn_ln(get_fn_ln()) self.__predicate = predicate self.__generator = predicate.generator
def wire(self, var_to, var_from, attributes: Union[List[_kratos.passes.Attribute], _kratos.passes.Attribute] = None, comment="", locals_=None, fn_ln=None, additional_frame=0, no_fn_ln=False): if self.is_cloned: if self.debug and locals_ is None: locals_ = get_frame_local(2 + additional_frame) self.__cached_initialization.append( (self.wire, [var_to, var_from, attributes, comment, locals_])) return # wire interface is a special treatment if isinstance(var_from, (_kratos.InterfaceRef, InterfaceWrapper)) or \ isinstance(var_to, (_kratos.InterfaceRef, InterfaceWrapper)): if isinstance(var_from, InterfaceWrapper): var_from = var_from.internal_interface if isinstance(var_to, InterfaceWrapper): var_to = var_to.internal_interface assert isinstance(var_from, _kratos.InterfaceRef) assert isinstance(var_to, _kratos.InterfaceRef) # TODO: add debug info to interface wiring self.__generator.wire_interface(var_to, var_from) return # this is a top level direct wire assignment # notice that we can figure out the direction automatically if # both of them are ports # handle port bundles if isinstance(var_to, _kratos.PortBundleRef): assert isinstance(var_from, _kratos.PortBundleRef) if self.debug: entry = get_fn_ln(2 + additional_frame) else: entry = [] var_from.assign(var_to, self.__generator, entry) return if isinstance(var_to, _kratos.Port) and isinstance( var_from, _kratos.Port): stmt = self.__generator.wire_ports(var_to, var_from) else: stmt = self.__assign(var_to, var_from) if self.debug and not no_fn_ln: if fn_ln is not None: stmt.add_fn_ln(fn_ln) else: stmt.add_fn_ln(get_fn_ln(2 + additional_frame)) if locals_ is None: locals_ = get_frame_local(2 + additional_frame) add_scope_context(stmt, locals_) if attributes is not None: if not isinstance(attributes, list): attributes = [attributes] for attr in attributes: stmt.add_attribute(attr) if comment: stmt.comment = comment
def var_packed(self, name: str, struct_packed: _kratos.PortPackedStruct): v = self.__generator.var_packed(name, struct_packed) if self.debug: v.add_fn_ln(get_fn_ln()) return v
def __add_stmt_with_debug(self, block, stmt): if self.debug: stmt.add_fn_ln(get_fn_ln()) block.add_stmt(stmt)
def __create_new_var(self, var_name, var_ref): new_var = self.var(var_name, var_ref.width, var_ref.signed, var_ref.size) if self.debug: new_var.add_fn_ln(get_fn_ln()) return new_var
def output(self, var, value): if self.__generator.debug: debug = get_fn_ln() self.__fsm_state.output(var, value, debug) else: self.__fsm_state.output(var, value)
def next(self, next_state, cond): if self.__generator.debug: debug = get_fn_ln() self.__fsm_state.next(next_state.internal_state, cond, debug) else: self.__fsm_state.next(next_state.internal_state, cond)