def run(self, actions, verilator_includes=None, num_tests=0, _circuit=None): # Set defaults if verilator_includes is None: verilator_includes = [] # Write the verilator driver to file. src = self.generate_code(actions, verilator_includes, num_tests, _circuit) driver_file = self.directory / Path(f"{self.circuit_name}_driver.cpp") with open(driver_file, "w") as f: f.write(src) # Run makefile created by verilator make_cmd = verilator_make_cmd(self.circuit_name) subprocess_run(make_cmd, cwd=self.directory, disp_type=self.disp_type) # Run the executable created by verilator and write the standard # output to a logfile for later review or processing exe_cmd = [f'./obj_dir/V{self.circuit_name}'] result = subprocess_run(exe_cmd, cwd=self.directory, disp_type=self.disp_type) log = Path(self.directory) / 'obj_dir' / f'{self.circuit_name}.log' with open(log, 'w') as f: f.write(result.stdout)
def run(self, actions, power_args=None): # set defaults power_args = power_args if power_args is not None else {} # expand background pokes into regular pokes actions = process_action_list(actions, self.clock_step_delay) # assemble list of sources files vlog_srcs = [] if not self.ext_test_bench: tb_file = self.write_test_bench(actions=actions, power_args=power_args) vlog_srcs += [tb_file] if not self.ext_model_file: vlog_srcs += [self.verilog_file] vlog_srcs += self.include_verilog_libraries # generate simulator commands if self.simulator == 'ncsim': sim_cmd = self.ncsim_cmd(sources=vlog_srcs, cmd_file=self.write_ncsim_tcl()) bin_cmd = None sim_err_str = None elif self.simulator == 'vcs': sim_cmd, bin_file = self.vcs_cmd(sources=vlog_srcs) bin_cmd = [bin_file] sim_err_str = 'Error' elif self.simulator == 'iverilog': sim_cmd, bin_file = self.iverilog_cmd(sources=vlog_srcs) bin_cmd = ['vvp', '-N', bin_file] sim_err_str = 'ERROR' else: raise NotImplementedError(self.simulator) # add any extra flags sim_cmd += self.flags # compile the simulation print('calling subprocess with args', sim_cmd, self.directory, self.sim_env, self.disp_type) completed_sim = subprocess_run(sim_cmd, cwd=self.directory, env=self.sim_env, disp_type=self.disp_type) # run the simulation binary (if applicable) if bin_cmd is not None: completed_sim = subprocess_run(bin_cmd, cwd=self.directory, env=self.sim_env, err_str=sim_err_str, disp_type=self.disp_type) result_text = completed_sim.stdout self.process_reads(result_text)
def run(self, actions, verilator_includes=None, num_tests=0, _circuit=None): # Set defaults if verilator_includes is None: verilator_includes = [] # Write the verilator driver to file. src = self.generate_code(actions, verilator_includes, num_tests, _circuit) driver_file = self.directory / Path(f"{self.circuit_name}_driver.cpp") with open(driver_file, "w") as f: f.write(src) # if use kratos, symbolic link the library to dest folder if self.use_kratos: from kratos_runtime import get_lib_path lib_name = os.path.basename(get_lib_path()) dst_path = os.path.abspath( os.path.join(self.directory, "obj_dir", lib_name)) if not os.path.isfile(dst_path): os.symlink(get_lib_path(), dst_path) # add ld library path env = {"LD_LIBRARY_PATH": os.path.dirname(dst_path)} else: env = None # Run makefile created by verilator make_cmd = verilator_make_cmd(self.circuit_name) subprocess_run(make_cmd, cwd=self.directory, disp_type=self.disp_type) # create the logs folder if necessary logs = Path(self.directory) / "logs" if not os.path.isdir(logs): os.mkdir(logs) # Run the executable created by verilator and write the standard # output to a logfile for later review or processing exe_cmd = [f'./obj_dir/V{self.circuit_name}'] result = subprocess_run(exe_cmd, cwd=self.directory, disp_type=self.disp_type, env=env) log = Path(self.directory) / 'obj_dir' / f'{self.circuit_name}.log' with open(log, 'w') as f: f.write(result.stdout) # post-process GetValue actions self.post_process_get_value_actions(actions)
def __init__(self, circuit, directory="build/", flags=None, skip_compile=False, include_verilog_libraries=None, include_directories=None, magma_output="coreir-verilog", circuit_name=None, magma_opts=None, skip_verilator=False, disp_type='on_error'): """ Params: `include_verilog_libraries`: a list of verilog libraries to include with the -v flag. From the verilator docs: -v <filename> Verilog library `include_directories`: a list of directories to include using the -I flag. From the the verilator docs: -I<dir> Directory to search for includes """ # Set defaults if include_verilog_libraries is None: include_verilog_libraries = [] if magma_opts is None: magma_opts = {} # Save settings self.disp_type = disp_type # Call super constructor super().__init__(circuit, circuit_name, directory, skip_compile, include_verilog_libraries, magma_output, magma_opts) # Compile the design using `verilator`, if not skip if not skip_verilator: driver_file = self.directory / Path( f"{self.circuit_name}_driver.cpp") comp_cmd = verilator_comp_cmd( top=self.circuit_name, verilog_filename=self.verilog_file.name, include_verilog_libraries=self.include_verilog_libraries, include_directories=include_directories, driver_filename=driver_file.name, verilator_flags=flags ) # shell=True since 'verilator' is actually a shell script subprocess_run(comp_cmd, cwd=self.directory, shell=True, disp_type=self.disp_type) # Initialize variables self.debug_includes = set() self.verilator_version = verilator_version(disp_type=self.disp_type)
def run(self, actions): # expand background pokes into regular pokes actions = process_action_list(actions, self.clock_step_delay) # compile the actions comp = self.compile_actions(actions) # write the testbench tb_file = self.write_test_bench(comp) # generate simulator commands if self.simulator == 'ngspice': sim_cmds, raw_file = self.ngspice_cmds(tb_file) elif self.simulator == 'spectre': sim_cmds, raw_file = self.spectre_cmds(tb_file) elif self.simulator == 'hspice': sim_cmds, raw_file = self.hspice_cmds(tb_file) else: raise NotImplementedError(self.simulator) # run the simulation commands for sim_cmd in sim_cmds: res = subprocess_run(sim_cmd, cwd=self.directory, env=self.sim_env, disp_type=self.disp_type) #print(res.stdout) stderr = res.stderr.strip() if stderr != '': print('Stderr from spice simulator:') print(stderr) # process the results if self.simulator in {'ngspice', 'spectre'}: results = nutascii_parse(raw_file) elif self.simulator in {'hspice'}: results = psf_parse(raw_file) else: raise NotImplementedError(self.simulator) #import matplotlib.pyplot as plt #print(results.keys()) #print('HELLO') #in_ = results['in_'] #out = results['out'] #plt.plot(in_.x, in_.y, '-o') #plt.plot(out.x, out.y, '-o') #plt.grid() #plt.show() # print results self.print_results(results=results, prints=comp.prints) # set values on reads self.process_reads(results, comp.reads) # check results self.check_results(results=results, checks=comp.checks)
def run(self, actions): # compile the actions comp = self.compile_actions(actions) # write the testbench tb_file = self.write_test_bench(comp) # generate simulator commands if self.simulator == 'ngspice': cmd, raw_files = self.ngspice_cmds(tb_file) elif self.simulator == 'spectre': cmd, raw_files = self.spectre_cmds(tb_file) elif self.simulator == 'hspice': cmd, raw_files = self.hspice_cmds(tb_file) else: raise NotImplementedError(self.simulator) # run the simulation commands if not self.no_run: subprocess_run(cmd, cwd=self.directory, env=self.sim_env, disp_type=self.disp_type) # process the results for raw_file in raw_files: if self.simulator in {'ngspice'}: results = nut_parse(raw_file) elif self.simulator in {'spectre'}: results = psf_parse(raw_file) elif self.simulator in {'hspice'}: results = hspice_parse(raw_file) else: raise NotImplementedError(self.simulator) # print results self.print_results(results=results, prints=comp.prints) # implement all of the gets self.impl_all_gets(results=results, gets=comp.gets) # check results self.check_results(results=results, checks=comp.checks)
def si_netlist(lib, cell, cds_lib='cds.lib', cwd='.', view='schematic', out='netlist', del_incl=True, env=None): # path wrapping cwd = Path(cwd) out = Path(out) # write si.env file si_env = si_env_tmpl.format(lib=lib, cell=cell, view=view) with open(cwd / 'si.env', 'w') as f: f.write(si_env) # run netlister args = [] args += ['si'] args += ['-cdslib', f'{cds_lib}'] args += ['-batch'] args += ['-command', 'netlist'] subprocess_run(args, cwd=cwd, env=env) # get netlist text and filter out include statementw with open(cwd / 'netlist', 'r') as f: lines = f.readlines() text = '' for line in lines: line_lower = line.strip().lower() if del_incl and line_lower.startswith('.include'): continue else: text += line # write netlist to desired file with open(out, 'w') as f: f.write(text)
def run_vivado_tcl(tcl_file, cwd=None, err_str=None, disp_type='realtime'): # set defaults if err_str is None: err_str = ['CRITICAL WARNING', 'ERROR', 'Fatal'] # build up the command cmd = [] cmd += ['vivado'] cmd += ['-mode', 'batch'] cmd += ['-source', f'{tcl_file}'] cmd += ['-nolog'] cmd += ['-nojournal'] # run TCL script and return the result return subprocess_run(cmd, cwd=cwd, err_str=err_str, disp_type=disp_type)
def __init__(self, circuit, directory="build/", flags=None, skip_compile=None, include_verilog_libraries=None, include_directories=None, magma_output="coreir-verilog", circuit_name=None, magma_opts=None, skip_verilator=False, disp_type='on_error', coverage=False, use_kratos=False, defines=None, parameters=None, ext_model_file=None): """ Params: `include_verilog_libraries`: a list of verilog libraries to include with the -v flag. From the verilator docs: -v <filename> Verilog library `include_directories`: a list of directories to include using the -I flag. From the the verilator docs: -I<dir> Directory to search for includes """ # Set defaults if include_verilog_libraries is None: include_verilog_libraries = [] if magma_opts is None: magma_opts = {} if skip_compile is None: if ext_model_file is None: skip_compile = False else: skip_compile = True magma_opts.setdefault("verilator_compat", True) # Save settings self.disp_type = disp_type self.use_kratos = use_kratos self.parameters = parameters if parameters is not None else {} # Try to import kratos_runtime, if needed # (it may be used in verilator_comp_cmd) if use_kratos: try: import kratos_runtime except ImportError: raise ImportError("Cannot find kratos-runtime in the system. " "Please do \"pip install kratos-runtime\" " "to install.") # Call super constructor super().__init__(circuit, circuit_name, directory, skip_compile, include_verilog_libraries, magma_output, magma_opts, coverage=coverage) # Determine the path to the Verilog file being tested if ext_model_file is not None: verilog_filename = str(ext_model_file) else: verilog_filename = self.verilog_file.name # Compile the design using `verilator`, if not skip if not skip_verilator: driver_file = self.directory / Path( f"{self.circuit_name}_driver.cpp") comp_cmd = verilator_comp_cmd( top=self.circuit_name, verilog_filename=verilog_filename, include_verilog_libraries=self.include_verilog_libraries, include_directories=include_directories, driver_filename=driver_file.name, verilator_flags=flags, coverage=self.coverage, use_kratos=use_kratos, defines=defines, parameters=parameters) # shell=True since 'verilator' is actually a shell script subprocess_run(comp_cmd, cwd=self.directory, shell=True, disp_type=self.disp_type) # Initialize variables self.verilator_version = verilator_version(disp_type=self.disp_type)
def run(self, actions, power_args=None): # assemble list of sources files vlog_srcs = [] if not self.ext_test_bench: tb_file = self.generate_test_bench(actions, power_args) vlog_srcs += [tb_file] if not self.ext_model_file: vlog_srcs += [self.verilog_file] vlog_srcs += self.include_verilog_libraries # generate simulator commands if self.simulator == 'ncsim' or self.simulator == "incisive": # Compile and run simulation cmd_file = self.write_cadence_tcl() sim_cmd = self.ncsim_cmd(sources=vlog_srcs, cmd_file=cmd_file) sim_err_str = None # Skip "bin_cmd" bin_cmd = None bin_err_str = None elif self.simulator == 'xcelium': # Compile and run simulation cmd_file = self.write_cadence_tcl() sim_cmd = self.xcelium_cmd(sources=vlog_srcs, cmd_file=cmd_file) sim_err_str = None # Skip "bin_cmd" bin_cmd = None bin_err_str = None elif self.simulator == 'vivado': # Compile and run simulation cmd_file = self.write_vivado_tcl(sources=vlog_srcs) sim_cmd = self.vivado_cmd(cmd_file=cmd_file) sim_err_str = ['CRITICAL WARNING', 'ERROR', 'Fatal', 'Error'] # Skip "bin_cmd" bin_cmd = None bin_err_str = None elif self.simulator == 'vcs': # Compile simulation # TODO: what error strings are expected at this stage? sim_cmd, bin_file = self.vcs_cmd(sources=vlog_srcs) sim_err_str = None # Run simulation bin_cmd = [bin_file] bin_err_str = ['Error', 'Fatal'] elif self.simulator == 'iverilog': # Compile simulation sim_cmd, bin_file = self.iverilog_cmd(sources=vlog_srcs) sim_err_str = ['syntax error', 'I give up.'] # Run simulation bin_cmd = ['vvp', '-N', bin_file] bin_err_str = ['ERROR', 'FATAL'] else: raise NotImplementedError(self.simulator) # link the library over if using kratos to debug if self.use_kratos: self.link_kratos_lib() if self.skip_run: return # compile the simulation subprocess_run(sim_cmd, cwd=self.directory, env=self.sim_env, err_str=sim_err_str, disp_type=self.disp_type) # run the simulation binary (if applicable) if bin_cmd is not None: subprocess_run(bin_cmd, cwd=self.directory, env=self.sim_env, err_str=bin_err_str, disp_type=self.disp_type) # post-process GetValue actions self.post_process_get_value_actions(actions)