def fsm_module(mod, counter_size=8): """FSM Module.""" # signals mod.add([ HDLSignal("reg", "state", size="defer"), HDLSignal("reg", "state2", size="defer"), HDLSignal("reg", "done_reg"), HDLSignal("reg", "counter", size=counter_size), ]) @HDLBlock(mod) @ParallelBlock() def fsm_body(): done = done_reg # sequential block generation @TestFSM(clk, rst, state, initial="zero") def myfsm(): pass # TODO: state variable cannot be the same, detect and prevent # in generation code @TestFSM(clk, rst, state2, initial="zero") def mysecondfsm(): pass # add generated body to module mod.extend(*fsm_body())
def test_hdl_signal(): """Test signals.""" my_sig = HDLSignal("reg", "signal_x", size=(7, 0)) print(my_sig.dumps()) _ = my_sig[3:1] _ = my_sig[7] yet_another = my_sig[2:] _ = my_sig[:2] print(yet_another.dumps()) _ = HDLSignal("reg", "sig", HDLVectorDescriptor(1, 0)) # exceptions with pytest.raises(ValueError): _ = HDLSignal("unknown", "sig", 1) with pytest.raises(ValueError): _ = HDLSignal("reg", "sig", -1) with pytest.raises(ValueError): _ = HDLSignal("reg", "sig", (1, 2, 3)) with pytest.raises(TypeError): _ = HDLSignal("reg", "sig", "invalid") _ = HDLSignalSlice(my_sig, HDLVectorDescriptor(1, 0)) with pytest.raises(TypeError): _ = HDLSignalSlice(my_sig, "invalid")
def test_seq(): """Test sequential block.""" some_signal = HDLSignal("reg", "signal", size=1) sens_1 = HDLSensitivityDescriptor(sens_type="rise", sig=some_signal) sens_list = HDLSensitivityList() sens_list.add(sens_1) ass_sig = HDLSignal("reg", "counter", size=2) ass_expr = HDLExpression(ass_sig) + 1 assign = HDLAssignment(ass_sig, ass_expr) seq = HDLSequentialBlock(sens_list) seq.add(assign) print(seq.dumps())
def __init__(self, direction, name, size=1): """Initialize. Args ---- direction: str Port direction size: int, tuple or vector.HDLVectorDescriptor Port description name: str Port name """ super().__init__(direction, name) if isinstance(size, int): # default is [size-1:0] / (size-1 downto 0) if size < 0: raise ValueError("only positive size allowed") self.vector = HDLVectorDescriptor(size - 1, 0) elif isinstance(size, (tuple, list)): if len(size) != 2: raise ValueError("invalid vector " 'dimensions: "{}"'.format(size)) self.vector = HDLVectorDescriptor(*size) elif isinstance(size, HDLVectorDescriptor): self.vector = size elif isinstance(size, HDLExpression): self.vector = HDLVectorDescriptor(left_size=size - 1) else: raise TypeError("size can only be of types: int, list or" " vector.HDLVectorDescriptor") # create internal signal self.signal = HDLSignal(sig_type="comb", sig_name=name, size=size)
def test_sens(): """Test sensitivity list.""" some_signal = HDLSignal("reg", "signal", size=1) sens_1 = HDLSensitivityDescriptor(sens_type="rise", sig=some_signal) sens_list = HDLSensitivityList() sens_list.add(sens_1) print(sens_list.dumps())
def __init__(self, direction, name, ptype): """Initialize.""" super().__init__(direction, name) # create internal signal self.signal = HDLSignal(sig_type="var", sig_name=name, var_type=ptype, size=None)
def test_ifelse(): """Test if-else.""" # create an if-else block gen = VerilogCodeGenerator() sig = HDLSignal(sig_type="comb", sig_name="test", size=1) test_sig = HDLSignal(sig_type="reg", sig_name="counter", size=2) assign_rhs = HDLExpression(test_sig) + 1 assignment = HDLAssignment(signal=test_sig, value=assign_rhs) ifelse = HDLIfElse(condition=sig) ifelse.add_to_if_scope(assignment) # make else assignment = HDLAssignment(signal=test_sig, value=0) ifelse.add_to_else_scope(assignment) print(gen.dump_element(ifelse))
def test_concat(): """Test concatenation.""" sig = HDLSignal("comb", "my_signal", size=4) concat = HDLConcatenation(sig, HDLExpression(0x0C, size=8)) assert len(concat) == 12 concat.append(HDLExpression(0x1, size=1)) # failures with pytest.raises(TypeError): _ = HDLConcatenation(sig, "not_allowed")
def test_assign(): """Test assignment.""" # this module is extensively tested already, being used as a support # class for many others. here we test whatever is missing sig = HDLSignal("comb", "my_signal") assign = HDLAssignment(signal=sig, value=0) print(assign.dumps()) # test fail cases with pytest.raises(TypeError): _ = HDLAssignment("not_allowed", 0)
def lfsr_module(mod): """LFSR Module.""" # signals mod.add([ HDLSignal("comb", "feedback"), HDLSignal("reg", "out_reg", size=8), ]) @HDLBlock(mod) @ParallelBlock() def lfsr_body(): """Build module body.""" # assign feedback signal feedback = not (out[7] ^ out[3]) # assign output out = out_reg # sequential block generation @ClockedBlock(clk) def gen_lfsr(): if rst == 1: out_reg = 0 else: if en == 1: out_reg = [ out[6], out[5], out[4], out[3], out[2], out[1], out[0], feedback, ] else: out_reg = out_reg # add generated body to module mod.extend(*lfsr_body())
def test_always(): """Test always block.""" gen = VerilogCodeGenerator() sig = HDLSignal(sig_type="reg", sig_name="clk", size=1) sens = HDLSensitivityDescriptor(sens_type="rise", sig=sig) sens_list = HDLSensitivityList() sens_list.add(sens) test_sig = HDLSignal(sig_type="reg", sig_name="counter", size=2) rst_assign = HDLAssignment(signal=test_sig, value=0) norm_expr = HDLExpression(test_sig) + 1 norm_assign = HDLAssignment(signal=test_sig, value=norm_expr) rst = HDLSignal(sig_type="reg", sig_name="rst", size=1) ifelse = HDLIfElse(condition=rst) ifelse.add_to_if_scope(rst_assign) ifelse.add_to_else_scope(norm_assign) seq = HDLSequentialBlock(sensitivity_list=sens_list) seq.add(ifelse) print(gen.dump_element(seq))
def _generate_entity(cls, mod_params, backend_name=None): """Generate entity.""" input_count = mod_params["inputNum"] mangled_name = mod_params.get("mangled_name", f"joiner__{input_count}") input_ports = [input_port("clk"), input_port("rst")] data_input_ports = [ input_port(f"jinput{x}", size=DEFAULT_PORT_SIZE) for x in range(0, input_count) ] data_output_port = output_port("joutput", size=DEFAULT_PORT_SIZE) output_ports = [data_output_port] selector_signal = HDLSignal("reg", "selector", size=clog2(input_count)) @HDLModule(mangled_name, ports=input_ports + data_input_ports + output_ports) def gen_module(mod): """Generate the module.""" # add selector signal mod.add(selector_signal) # clocked block for counter @HDLBlock(mod) @ParallelBlock() def module_body(input_count): """Generate the actual implementation.""" @ClockedBlock(clk) def join_seq(): if rst == 1: selector = 0 else: # FIXME(hdltools): selector += 1 does not produce code if selector < input_count - 1: selector = selector + 1 else: selector = 0 # input multiplexer mod.add( get_multiplexer(data_output_port, selector_signal, *data_input_ports)) mod.extend(*module_body(input_count=input_count)) return gen_module()
def test_hdl_expression(): """Test expressions.""" expr_1 = "PARAM-2" expr_2 = "PARAM_X+1" expr_3 = "a and ~b" hdl_expr_1 = HDLExpression(ast.parse(expr_1, mode="eval")) hdl_expr_2 = HDLExpression(ast.parse(expr_2, mode="eval")) hdl_expr_3 = HDLExpression(expr_3) print(hdl_expr_3.dumps()) sum = hdl_expr_1 + hdl_expr_2 neg = ~sum bool_neg = sum.bool_neg() bool_and = hdl_expr_1.bool_and(hdl_expr_2) bool_or = hdl_expr_1.bool_or(hdl_expr_2) print(sum.dumps()) print(neg.dumps()) print(bool_neg.dumps()) print(bool_and.dumps()) print(bool_or.dumps()) _ = hdl_expr_1 & 0x1 _ = 0x1 | hdl_expr_1 _ = 0x1 & hdl_expr_1 _ = 0x1 ^ hdl_expr_1 _ = hdl_expr_1 ^ 0x1 my_signal = HDLSignal("reg", "signal_a", size=2) _ = HDLExpression(HDLIntegerConstant(1)) _ = HDLExpression(1) _ = HDLExpression(my_signal) _ = HDLExpression(HDLSignalSlice(my_signal, 1)) _ = HDLExpression(my_signal[1:0]) # test reduction expr_a = HDLExpression("value_a") expr_b = HDLExpression("value_b") full_expr = expr_a << 0 | expr_b << 16 | HDLExpression(0) case_1 = ast.BinOp(left=ast.Constant(value=0), op=ast.BitOr(), right=ast.Name(id="VAR")) case_2 = ast.BinOp(left=ast.Constant(value=1), op=ast.Mult(), right=ast.Name(id="VAR")) case_3 = ast.BinOp(left=ast.Constant(value=0), op=ast.Mult(), right=ast.Name(id="VAR")) hdl_expr = HDLExpression(ast.Expression(body=case_1)) hdl_expr_2 = HDLExpression(ast.Expression(body=case_2)) hdl_expr_3 = HDLExpression(ast.Expression(body=case_3)) print(hdl_expr.dumps()) print(hdl_expr_2.dumps()) reduced_1 = HDLExpression._reduce_binop(case_1) hdl_expr = HDLExpression(ast.Expression(body=reduced_1)) print(hdl_expr.dumps()) reduced_2 = HDLExpression._reduce_binop(case_2) hdl_expr_2 = HDLExpression(ast.Expression(body=reduced_2)) print(hdl_expr_2.dumps()) reduced_3 = HDLExpression._reduce_binop(case_3) hdl_expr_3 = HDLExpression(ast.Expression(body=reduced_3)) print(hdl_expr_3.dumps()) print(full_expr.dumps()) full_expr.reduce_expr() print(full_expr.dumps())
"""Build structural modules manually.""" from hdltools.abshdl.module import HDLModule, HDLModuleTypedPort from hdltools.abshdl.assign import HDLAssignment from hdltools.abshdl.signal import HDLSignal from hdltools.abshdl.expr import HDLExpression from hdltools.specc.codegen import SpecCCodeGenerator if __name__ == "__main__": # create ports mod_ports = [ HDLModuleTypedPort('in', 'operandA', 'int'), HDLModuleTypedPort('in', 'operandB', 'int'), HDLModuleTypedPort('out', 'result', 'int') ] test_mod = HDLModule('test', mod_ports) test_mod.add(HDLSignal('var', 'test')) # test_mod.add(HDLAssignment(-mod_ports[2], # HDLExpression('operandA')*HDLExpression('operandB'))) gen = SpecCCodeGenerator(indent=True) print(gen.dump_element(test_mod))
"""Usage examples for parallel statements.""" from hdltools.abshdl.assign import HDLAssignment from hdltools.hdllib.patterns import ParallelBlock, ClockedBlock from hdltools.abshdl.signal import HDLSignal from hdltools.abshdl.ifelse import HDLIfElse from hdltools.abshdl.concat import HDLConcatenation from hdltools.verilog.codegen import VerilogCodeGenerator from hdltools.abshdl.highlvl import HDLBlock if __name__ == "__main__": # create some signals clk = HDLSignal("reg", "clk") rst = HDLSignal("comb", "rst") en = HDLSignal("comb", "en") out = HDLSignal("reg", "out", size=8) feedback = HDLSignal("comb", "feedback") # parallel statements @ParallelBlock() def my_par(par, feedback, out, **kwargs): """Parallel statements.""" # assign combinatorial signal par.add([feedback.assign((out[7] ^ out[3]).bool_neg())]) @ClockedBlock(clk) def gen_lfsr(seq): concat = HDLConcatenation( out[6], out[5],
from hdltools.hdllib.patterns import ( ClockedBlock, SequentialBlock, ClockedRstBlock, ) from hdltools.abshdl.assign import HDLAssignment from hdltools.abshdl.signal import HDLSignal from hdltools.abshdl.ifelse import HDLIfElse from hdltools.abshdl.highlvl import HDLBlock if __name__ == "__main__": # declare some signals clk = HDLSignal("reg", "clk") rst = HDLSignal("comb", "rst") counter = HDLSignal("reg", "counter") # manually created sequential block using clocked @SequentialBlock(["rise", clk]) def my_counter_manual(seq): """Test SequentialBlock.""" ifelse = HDLIfElse( rst == 1, if_scope=counter.assign(0), else_scope=counter.assign(counter + 1), ) seq.add(ifelse) print("*Using SequentialBlock*")