Example #1
0
 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())
Example #2
0
 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
Example #3
0
    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)
Example #4
0
 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())
Example #5
0
    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
Example #6
0
    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))
Example #7
0
 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
Example #8
0
 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
Example #9
0
 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())
Example #10
0
 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
Example #11
0
    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
Example #12
0
 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
Example #13
0
 def __add_stmt_with_debug(self, block, stmt):
     if self.debug:
         stmt.add_fn_ln(get_fn_ln())
     block.add_stmt(stmt)
Example #14
0
 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
Example #15
0
 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)
Example #16
0
 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)