Пример #1
0
def test_hdl_module():
    """Test modules."""
    mod = HDLModule("my_module")
    mod = HDLModule("my_module", [HDLModulePort("in", "myport", 8)])
    mod = HDLModule("my_module",
                    params=[HDLModuleParameter("myparam", "integer", 0)])

    expr = ast.parse("myparam-1", mode="eval")
    vec = HDLVectorDescriptor(left_size=HDLExpression(expr), right_size=0)
    mod = HDLModule(
        "my_module",
        ports=[HDLModulePort("in", "myport", vec)],
        params=HDLModuleParameter("myparam", "integer", 0),
    )
    print(mod.dumps(evaluate=True))

    _ = mod.get_parameter_scope()
    _ = mod.get_full_scope()
    _ = mod.get_param_names()
    _ = mod.get_port_names()

    # failures
    with pytest.raises(TypeError):
        mod = HDLModule("my_module", 0)

    with pytest.raises(TypeError):
        mod = HDLModule("my_module", [0])

    with pytest.raises(TypeError):
        mod = HDLModule("my_module", params=[0])

    with pytest.raises(TypeError):
        mod = HDLModule("my_module", params=0)
Пример #2
0
def test_module():
    """Test module."""
    gen = VerilogCodeGenerator()

    inp = HDLModulePort(direction="in", name="an_input", size=4)
    out = HDLModulePort(direction="out", name="an_output", size=1)
    prm = HDLModuleParameter(
        param_name="a_parameter",
        param_type="integer",
        param_default=HDLIntegerConstant(0),
    )

    mod = HDLModule(module_name="my_module", ports=[inp, out], params=[prm])

    print(gen.dump_element(mod))
Пример #3
0
def test_module_port():
    """Test ports."""
    HDLModulePort("in", "myport", 3)
    HDLModulePort("out", "myport", (2, 0))
    HDLModulePort("inout", "myport", HDLVectorDescriptor(2, 0))

    # fail cases
    with pytest.raises(ValueError):
        HDLModulePort("unknown", "myport", 0)

    with pytest.raises(ValueError):
        HDLModulePort("in", "myport", -1)

    with pytest.raises(ValueError):
        HDLModulePort("in", "myport", (2, 3, 0))

    with pytest.raises(TypeError):
        HDLModulePort("in", "myport", "INVALID")
Пример #4
0
    def parameterize(cls, **kwargs):
        """Parameterize interface ports."""
        ports = []
        for port_name, port_desc in cls._PORTS.items():
            port_optional = port_desc.get("optional", False)
            if "dir" not in port_desc or "size" not in port_desc:
                raise HDLModuleInterfaceError("malformed port description")
            size = port_desc["size"]
            if not isinstance(size, (int, str)):
                raise HDLModuleInterfaceError(
                    "port size must be integer or expression")

            if isinstance(size, str):
                # determine if is simple name or expression
                m = EXPRESSION_REGEX.findall(size)
                if m:
                    # is expression
                    names = re.findall(r"[_a-zA-Z]\w*", size)
                    for name in names:
                        original_name = name
                        if name not in kwargs:
                            name = cls.find_alias(name)
                        if name not in kwargs and port_optional is False:
                            raise HDLModuleInterfaceError(
                                f"in expression '{size}': unknown name '{name}'"
                            )
                        if port_optional:
                            # ignore port
                            continue
                        size = size.replace(original_name, str(kwargs[name]))
                    # force integer division
                    size = size.replace("/", "//")
                    try:
                        size = eval(size)
                    except SyntaxError:
                        raise HDLModuleInterfaceError(
                            f"invalid expression: '{size}'")
                else:
                    # is name
                    if size not in kwargs and port_optional is False:
                        raise HDLModuleInterfaceError(f"unknown name: {size}")
                    if port_optional:
                        # not specified, so ignore
                        continue
                    if not isinstance(kwargs[size], int):
                        raise HDLModuleInterfaceError(
                            "port sizes must be integer values")
                    size = kwargs[size]
            else:
                enable_port = kwargs.get(f"enable{port_name}", False)
                if port_optional and bool(enable_port) is False:
                    # ignore optional port
                    continue
            if size == 0:
                # ignore port
                continue
            if size < 0:
                raise HDLModuleInterfaceError(f"invalid port size: {size}")
            if port_desc["dir"] == "input":
                direction = "in"
            elif port_desc["dir"] == "output":
                direction = "out"
            elif port_desc["dir"] == "inout":
                direction = "inout"
            else:
                raise HDLModuleInterfaceError(
                    "port direction must be input, output or inout")
            ports.append(HDLModulePort(direction, port_name, size))
        return HDLParameterizedInterface(*ports)
Пример #5
0
    def _parse_file(self):
        """Parse file."""
        meta_model = metamodel_from_file(
            pkg_resources.resource_filename(
                "hdltools", "verilog/module_grammar.tx"
            )
        )

        module_decl = meta_model.model_from_file(self.mod_file)

        # create module object
        hdl_mod = HDLModule(module_decl.mod_decl.mod_name)

        # create and add parameters
        if module_decl.mod_decl.param_decl is not None:
            params = module_decl.mod_decl.param_decl.params[:]
            for param in params:

                # use ast to parse
                if param.def_val.expr is not None:
                    param_str = param.def_val.expr.replace("$", "_")
                    param_tree = ast.parse(param_str, mode="eval")

                    # dependency check
                    param_deps = self._find_dependencies(param_tree)
                    for dep in param_deps:
                        if dep not in self.hdl_model.get_param_names():
                            raise KeyError(
                                "unknown identifier:" " {}".format(dep)
                            )

                    # evaluate parameters immediately (not necessary)
                    scope = hdl_mod.get_full_scope()
                    param_val = HDLExpression(param_tree).evaluate(**scope)
                else:
                    param_val = param.def_val.bitstr

                hdl_param = HDLModuleParameter(
                    param_name=param.par_name,
                    param_type=param.par_type,
                    param_default=param_val,
                )

                hdl_mod.add_parameters(hdl_param)

        self.hdl_model = hdl_mod

        # create and add ports
        ports = module_decl.mod_decl.ports[:]
        for port in ports:
            # ugly, but not my fault
            direction = self._class_to_port_dir[port.__class__.__name__]
            name = port.decl.port_name
            if port.decl.srange is not None:
                size = (
                    port.decl.srange.left_size,
                    port.decl.srange.right_size,
                )

                # use ast to parse, avoiding complicated grammar
                left_str = port.decl.srange.left_size.replace("$", "_")
                right_str = port.decl.srange.right_size.replace("$", "_")
                left_tree = ast.parse(left_str, mode="eval")
                right_tree = ast.parse(right_str, mode="eval")
                left_deps = self._find_dependencies(left_tree)
                right_deps = self._find_dependencies(right_tree)

                # search dependencies in parameters
                for dep in left_deps:
                    if dep not in self.hdl_model.get_param_names():
                        raise KeyError("unknown identifier: {}".format(dep))
                for dep in right_deps:
                    if dep not in self.hdl_model.get_param_names():
                        raise KeyError("unknown identifier: {}".format(dep))

                size = (HDLExpression(left_tree), HDLExpression(right_tree))
            else:
                size = (0, 0)
            try:
                hdl_port = HDLModulePort(
                    direction=direction, name=name, size=size
                )
            except TypeError:
                pass

            self.hdl_model.add_ports(hdl_port)
Пример #6
0
def inout_port(name, size=1, _type=None):
    """Make an input port."""
    if _type is not None:
        return HDLModuleTypedPort("inout", name, size, _type)
    return HDLModulePort("inout", name, size)