def _run_case(): class DUT(Component): def construct(s): s.mem = bytearray(1 << 29) s.mem[-1] = 1 s.mem[-2] = 123 s.mem[1] = 12 s.in_ = InPort(Bits32) s.out = OutPort(Bits32) @update def upblk(): s.out @= s.in_ + 1 def line_trace(s): return f"{s.in_} > {s.out}" m = DUT() m.elaborate() m.set_metadata(VerilogTranslationImportPass.enable, True) m.apply(VerilogPlaceholderPass()) m = VerilogTranslationImportPass()(m) m.apply(DefaultPassGroup()) m.sim_reset() m.in_ @= Bits32(123) m.sim_tick() assert m.out == 124 m.finalize() gc.collect() print("python process memory usage:", resource.getrusage(resource.RUSAGE_SELF).ru_maxrss // 1024, " MB")
def local_do_test( _m ): _m.elaborate() _m.yosys_translate_import = True _m.apply( VerilogPlaceholderPass() ) m = TranslationImportPass()( _m ) sim = TestVectorSimulator( m, _m._test_vectors, _m._tv_in, _m._tv_out ) sim.run_test()
def test_reg_infer_external_trace(do_test): # Test Verilog line trace class VRegTrace(Component, VerilogPlaceholder): def construct(s): s.in_ = InPort(Bits32) s.out = OutPort(Bits32) s.set_metadata(VerilogPlaceholderPass.port_map, { s.in_: "d", s.out: "q", }) s.set_metadata(VerilogTranslationImportPass.enable, True) a = VRegTrace() a.elaborate() a.apply(VerilogPlaceholderPass()) a = VerilogTranslationImportPass()(a) a.apply(DefaultPassGroup()) assert a.line_trace() == 'q = 0' a.in_ @= Bits32(1) a.sim_tick() assert a.line_trace() == 'q = 1' a.in_ @= Bits32(2) a.sim_tick() assert a.line_trace() == 'q = 2' a.in_ @= Bits32(-1) a.sim_tick() # 0xFFFFFFFF unsigned assert a.line_trace() == 'q = 4294967295' a.sim_tick() a.finalize()
def test_reg_external_trace(do_test): # Test Verilog line trace class RegTrace(Component, Placeholder): def construct(s): s.in_ = InPort(Bits32) s.out = OutPort(Bits32) s.config_placeholder = VerilogPlaceholderConfigs( src_file=dirname(__file__) + '/VRegTrace.v', top_module='VRegTrace', port_map={ "in_": "d", "out": "q", }) s.config_verilog_import = VerilatorImportConfigs( vl_line_trace=True, ) s.verilog_translate_import = True a = RegTrace() a.elaborate() a.apply(VerilogPlaceholderPass()) a = TranslationImportPass()(a) a.apply(SimulationPass()) a.in_ = Bits32(1) a.tick() assert a.line_trace() == 'q = 0' a.in_ = Bits32(2) a.tick() assert a.line_trace() == 'q = 1' a.in_ = Bits32(-1) a.tick() assert a.line_trace() == 'q = 2' a.tick() # 0xFFFFFFFF unsigned assert a.line_trace() == 'q = 4294967295'
def local_do_test(_m): _m.elaborate() _m.apply(VerilogPlaceholderPass()) m = TranslationImportPass()(_m) m.verilog_tbgen = '1234' m.apply(VerilogTBGenPass()) sim = TestVectorSimulator(m, _m._test_vectors, _m._tv_in, _m._tv_out) sim.run_test()
def local_do_test( _m ): _m.elaborate() if not hasattr( _m, "_no_trans_import" ): _m.set_metadata( YosysTranslationImportPass.enable, True ) _m.apply( VerilogPlaceholderPass() ) m = YosysTranslationImportPass()( _m ) sim = TestVectorSimulator( m, _m._tvs, _m._tv_in, _m._tv_out ) sim.run_test()
def run_test(case): _m = case.DUT() _m.elaborate() _m.set_metadata(VerilogTranslationImportPass.enable, True) _m.apply(VerilogPlaceholderPass()) m = VerilogTranslationImportPass()(_m) sim = TestVectorSimulator(m, case.TV, case.TV_IN, case.TV_OUT) sim.run_test()
def run_sim(model, dump_vcd=None, test_verilog=False, line_trace=True, max_cycles=5000): # Setup the model model.elaborate() if dump_vcd: model.config_tracing = TracingConfigs(tracing='vcd', vcd_file_name=dump_vcd) if test_verilog: if not hasattr(model, 'config_verilog_import'): model.config_verilog_import = VerilatorImportConfigs( vl_xinit=test_verilog, ) else: model.config_verilog_import = VerilatorImportConfigs( vl_xinit=test_verilog, ) model.verilog_translate_import = True model.apply(VerilogPlaceholderPass()) model = TranslationImportPass()(model) # Create a simulator model.apply(SimulationPass()) # Reset model model.sim_reset(print_line_trace=line_trace) # Run simulation while not model.done() and model.simulated_cycles < max_cycles: if line_trace: model.print_line_trace() model.tick() # Force a test failure if we timed out assert model.simulated_cycles < max_cycles # Extra ticks to make VCD easier to read model.tick() model.tick() model.tick()
def test_verilate(dump_vcd, test_verilog): # Conflat the model model = SortUnitFlatRTL(8) # Configure the model config_model(model, dump_vcd, test_verilog) # Apply necessary passes model.apply(VerilogPlaceholderPass()) model = TranslationImportPass()(model) # Create and reset simulator model.apply(SimulationPass()) model.sim_reset() print("") # Helper function def t(in_val, in_, out_val, out): model.in_val = b1(in_val) for i, v in enumerate(in_): model.in_[i] = b8(v) model.eval_combinational() print(model.line_trace()) assert model.out_val == out_val if (out_val): for i, v in enumerate(out): assert model.out[i] == v model.tick() # Cycle-by-cycle tests t(0, [0x00, 0x00, 0x00, 0x00], 0, [0x00, 0x00, 0x00, 0x00]) t(1, [0x03, 0x09, 0x04, 0x01], 0, [0x00, 0x00, 0x00, 0x00]) t(1, [0x10, 0x23, 0x02, 0x41], 0, [0x00, 0x00, 0x00, 0x00]) t(1, [0x02, 0x55, 0x13, 0x07], 0, [0x00, 0x00, 0x00, 0x00]) t(0, [0x00, 0x00, 0x00, 0x00], 1, [0x01, 0x03, 0x04, 0x09]) t(0, [0x00, 0x00, 0x00, 0x00], 1, [0x02, 0x10, 0x23, 0x41]) t(0, [0x00, 0x00, 0x00, 0x00], 1, [0x02, 0x07, 0x13, 0x55]) t(0, [0x00, 0x00, 0x00, 0x00], 0, [0x00, 0x00, 0x00, 0x00]) t(0, [0x00, 0x00, 0x00, 0x00], 0, [0x00, 0x00, 0x00, 0x00])
def run_test(case): try: _m = case.DUT() _m.elaborate() _m.verilog_translate_import = True _m.apply(VerilogPlaceholderPass()) m = TranslationImportPass()(_m) sim = TestVectorSimulator(m, case.TEST_VECTOR, case.TV_IN, case.TV_OUT) sim.run_test() finally: try: m.finalize() except UnboundLocalError: # This test fails due to translation errors pass
def test_bitstruct_same_name_different_fields(): class A: @bitstruct class A: a: Bits32 class B: @bitstruct class A: a: Bits16 class InIfc(Interface): def construct(s, Type): s.in_ = InPort(Type) class OutIfc(Interface): def construct(s, Type): s.out = OutPort(Type) class DUT(Component): def construct(s): s.in1 = InIfc(A.A) s.in2 = InIfc(B.A) s.out2 = OutPort(Bits16) s.out2 //= s.in2.in_.a class TMP(Component): def construct(s): s.out = OutPort(B.A) @update def drive(): s.out @= 0 class Top(Component): def construct(s): s.dut = DUT() s.tmp = TMP() s.tmp.out //= s.dut.in2.in_ m = Top() m.elaborate() m.dut.set_metadata(VerilogTranslationImportPass.enable, True) m.apply(VerilogPlaceholderPass()) m = VerilogTranslationImportPass()(m) m.dut.finalize()
def run_test_vector_sim(model, test_vectors, dump_vcd=None, test_verilog=False, line_trace=True): # First row in test vectors contains port names if isinstance(test_vectors[0], str): port_names = test_vectors[0].split() else: port_names = test_vectors[0] # Remaining rows contain the actual test vectors test_vectors = test_vectors[1:] # Setup the model model.elaborate() if dump_vcd: model.config_tracing = TracingConfigs(tracing='vcd', vcd_file_name=dump_vcd) if test_verilog: if not hasattr(model, 'config_verilog_import'): model.config_verilog_import = VerilatorImportConfigs( vl_xinit=test_verilog, ) else: model.config_verilog_import.vl_xinit = test_verilog model.verilog_translate_import = True model.apply(VerilogPlaceholderPass()) model = TranslationImportPass()(model) # Create a simulator model.apply(SimulationPass()) # Reset model model.sim_reset(print_line_trace=line_trace) # Run the simulation row_num = 0 in_ids = [] out_ids = [] groups = [None] * len(port_names) types = [None] * len(port_names) # Preprocess default type # Special case for lists of ports # NOTE THAT WE ONLY SUPPORT 1D ARRAY and no interface for i, port_full_name in enumerate(port_names): if port_full_name[-1] == "*": out_ids.append(i) port_name = port_full_name[:-1] else: in_ids.append(i) port_name = port_full_name if '[' in port_name: # Get tokens of the full name m = re.match(r'(\w+)\[(\d+)\]', port_name) if not m: raise Exception( f"Could not parse port name: {port_name}. " f"Currently we don't support interface or high-D array.") groups[i] = g = (True, m.group(1), int(m.group(2))) # Get type of all the ports t = type(getattr(model, g[1])[int(g[2])]) types[i] = None if is_bitstruct_class(t) else t else: groups[i] = (False, port_name) t = type(getattr(model, port_name)) types[i] = None if is_bitstruct_class(t) else t for row in test_vectors: row_num += 1 # Apply test inputs for i in in_ids: in_value = row[i] t = types[i] if t: in_value = t(in_value) g = groups[i] if g[0]: getattr(model, g[1])[g[2]] = in_value else: setattr(model, g[1], in_value) # Evaluate combinational concurrent blocks model.eval_combinational() # Display line trace output if line_trace: model.print_line_trace() # Check test outputs for i in out_ids: ref_value = row[i] if ref_value == '?': continue g = groups[i] if g[0]: out_value = getattr(model, g[1])[g[2]] else: out_value = getattr(model, g[1]) if out_value != ref_value: error_msg = """ run_test_vector_sim received an incorrect value! - row number : {row_number} - port name : {port_name} - expected value : {expected_msg} - actual value : {actual_msg} """ raise RunTestVectorSimError( error_msg.format(row_number=row_num, port_name=port_name, expected_msg=ref_value, actual_msg=out_value)) # Tick the simulation model.tick() # Extra ticks to make VCD easier to read model.tick() model.tick() model.tick()
[1, 43, 1, 0, 42, 0], [0, 44, 0, 1, 43, 1], [1, 44, 1, 0, 43, 0], [0, 45, 0, 1, 44, 1], [1, 45, 1, 0, 44, 0], ] q._test_vectors = test_vector q._tv_in = tv_in q._tv_out = tv_out do_test(q) def test_CaseConnectArrayBits32FooIfcComp(): case = CaseConnectArrayBits32FooIfcComp try: _m = case.DUT() _m.elaborate() _m.verilog_translate_import = True _m.apply(VerilogPlaceholderPass()) m = TranslationImportPass()(_m) m.verilog_tbgen = True m.apply(VerilogTBGenPass()) sim = TestVectorSimulator(m, case.TEST_VECTOR, case.TV_IN, case.TV_OUT) sim.run_test() finally: try: m.finalize() except UnboundLocalError: # This test fails due to translation errors pass