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)
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))
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")
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)
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)
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)