def prepare(files, params): relog.step("Listing files") # create the list of sources INCLUDE_DIRS = resolve_includes(files) CURRENT_DIR = os.getcwd() PLATFORM_NAME = os.getenv("PLATFORM") PLATFORM_DIR = CURRENT_DIR[:CURRENT_DIR.find(PLATFORM_NAME) + len(PLATFORM_NAME)] with open(SRCS, "w+") as fp: # add vh extension to verilog fp.write("-vlog_ext .v,.vp,.vh,.vs\n") fp.write("-sysv_ext .sv,.svp,.svh,.svi,.sva\n") # define include_dirs for include_dir in INCLUDE_DIRS: fp.write("-incdir %s\n" % include_dir) fp.write("-incdir %s\n" % PLATFORM_DIR) if "TIMESCALE" in PARAMS: fp.write("-timescale %s\n" % PARAMS["TIMESCALE"]) if "SIM_FLAGS" in PARAMS: for flag in PARAMS["SIM_FLAGS"]: tf = transform_flags(flag) if tf and tf[:2] not in ("-m", "-M"): fp.write("%s\n" % tf) # add files for file in files: if not file.endswith("h"): fp.write("%s\n" % file) else: fp.write(f"-incdir {os.path.dirname(file)}\n") # estimate appropriate flags return ("verilog-ams" if any(["AMS" in m for m in MIMES]) else "2012" if any(["SYS" in m for m in MIMES]) else "2001")
def run(asc: str): relog.step("Running simulation") os.makedirs(DEFAULT_TMPDIR, exist_ok=True) # use the appropriate program # depending on the platform log = asc.replace(".asc", ".log") if sys.platform == "darwin": ltspice = "/Applications/LTspice.app/Contents/MacOS/LTspice" elif sys.platform == "unix" or "linux" in sys.platform: ltspice = 'wine64 "%s"' % utils.wine.locate("XVIIx64.exe") # to speed up wine # wine reg add 'HKEY_CURRENT_USER\Software\Wine\Direct3D' /v MaxVersionGL /t REG_DWORD /d 0x30003 /f # winetricks orm=backbuffer glsl=disable for NVIDIA driver # do not allow the WM to decorate window window_path = io.StringIO() executor.sh_exec("winepath -w '%s'" % asc, window_path, NOERR=True, NOOUT=True) asc = utils.normpath(window_path.getvalue().strip()) else: ltspice = "XVIIx64.exe" # start the simulation gen = executor.ish_exec('%s -Run "%s"' % (ltspice, asc), SIM_LOG, MAX_TIMEOUT=300, NOERR=True) proc = next(gen) # watch the log file to determine when # the simulation ends sim_done = watch_log(log) if proc: proc.kill() return 0, not sim_done # relog.get_stats(SIM_LOG)
def run_sim(files, params): # update global variables Config.add_configs(os.path.join(TOOLS_DIR, "tools.config")) DEFAULT_TMPDIR = utils.get_tmp_folder("sim") WAVE_FORMAT = Config.iverilog.get("format") WAVE = os.path.join(DEFAULT_TMPDIR, "run.%s" % WAVE_FORMAT) # prepare scripts flags = prepare(files, params) compile(*flags) relog.step("Running simulation") VVP_FLAGS = [] if "SIM_FLAGS" in params: for flag in params["SIM_FLAGS"]: tf = transform_flags(flag) if tf and tf[:2] in ("-m", "-M"): VVP_FLAGS.append(tf) VVP_FLAGS = " ".join(VVP_FLAGS) executor.sh_exec( "vvp -i %s %s -%s" % (EXE, VVP_FLAGS, WAVE_FORMAT), SIM_LOG, MAX_TIMEOUT=300, SHOW_CMD=True, ) # move the dumpfile to TMPDIR if os.path.exists(WAVE): os.remove(WAVE) if os.path.exists("./dump.%s" % WAVE_FORMAT): os.rename("./dump.%s" % WAVE_FORMAT, WAVE) return relog.get_stats(SIM_LOG)
def main(format: str = "vcd"): relog.step("Search waveforms") vcd_path = None view = None for path in Path(DEFAULT_TMPDIR).rglob("**/*.%s" % format): vcd_path = path break relog.info(vcd_path) for path in Path(os.path.dirname(DEFAULT_TMPDIR)).rglob("**/*.gtkw"): view = path break relog.info("loading view %s" % view) # define what to open file_to_read = view if view else vcd_path relog.step("Open waveforms") if sys.platform == "linux" or sys.platform == "linux2": # linux executor.sh_exec("gtkwave '%s'" % file_to_read, MAX_TIMEOUT=-1, SHELL=False) elif sys.platform == "darwin": # OS X executor.sh_exec("open -a gtkwave '%s'" % file_to_read, MAX_TIMEOUT=-1, SHELL=False) elif sys.platform == "win32": # Windows... executor.sh_exec("gtkwave '%s'" % file_to_read, MAX_TIMEOUT=-1, SHELL=False) else: relog.error("Unknown operating system") return (0, 0)
def run_lint(files, params): # update global variables Config.add_configs(os.path.join(TOOLS_DIR, "tools.config")) DEFAULT_TMPDIR = utils.get_tmp_folder("lint") # prepare scripts flags = prepare(files, params) compile(*flags) relog.step("Linting files") relog.display_log(PARSER_LOG) return relog.get_stats(SIM_LOG)
def prepare(files, params): relog.step("Preparation") os.makedirs(DEFAULT_TMPDIR, exist_ok=True) with open(SYNTH_SCRIPT, "w+") as fp: for file, mime in files: # code files not ignored if not any([ign in file for ign in IGNORED]): if mime == "VERILOG": fp.write("read_verilog %s\n" % file) elif mime == "LIBERTY": fp.write("read_liberty %s\n" % file)
def prepare(files, PARAMS): relog.step("Prepation") # create the list of sources FILES = [f for f, m in files] MIMES = list(set([m for f, m in files])) INCLUDE_DIRS = resolve_includes(FILES) CURRENT_DIR = os.getcwd() PLATFORM_NAME = os.getenv("PLATFORM") PLATFORM_DIR = CURRENT_DIR[:CURRENT_DIR.find(PLATFORM_NAME) + len(PLATFORM_NAME)] with open(SRCS, "w+") as fp: for include_dir in INCLUDE_DIRS: fp.write("+incdir+%s\n" % include_dir) fp.write("+incdir+%s\n" % PLATFORM_DIR) if "TIMESCALE" in PARAMS: fp.write("+timescale+%s\n" % PARAMS["TIMESCALE"]) if "SIM_FLAGS" in PARAMS: for flag in PARAMS["SIM_FLAGS"]: tf = transform_flags(flag) if tf and tf[:2] not in ("-m", "-M"): fp.write("%s\n" % tf) for file in FILES: if is_digital(file) and get_type(file) not in [ "ASSERTIONS", "LIBERTY" ]: fp.write("%s\n" % file) # estimate appropriate flags generation = "2012" if any(["SYS" in m for m in MIMES]) else "2001" flags = Config.iverilog.get("flags").split() flags.extend([ "-gverilog-ams" if any([ "AMS" in m or "-gverilog-ams" in m for m in chain(MIMES, PARAMS.get("SIM_FLAGS", "")) ]) else "-gno-verilog-ams", "-gassertions" if any([ "ASSERT" in m or "-gassert" in m for m in chain(MIMES, PARAMS.get("SIM_FLAGS", "")) ]) else "-gno-assertions", "-gspecify" if any(["-gspec" in p for p in PARAMS.get("SIM_FLAGS", "")]) else "", "-Wtimescale" if any(["-Wtimes" in p for p in PARAMS.get("SIM_FLAGS", "")]) else "", ]) flags = list(set(flags)) # declare needed external VPI modules VVP_FLAGS = [] if "SIM_FLAGS" in PARAMS: for flag in PARAMS["SIM_FLAGS"]: tf = transform_flags(flag) if tf and tf[:2] in ("-m"): VVP_FLAGS.append(tf) return generation, " ".join(chain(flags, VVP_FLAGS)).strip()
def run_sim(files, params): Config.add_config(os.path.join(TOOLS_DIR, "tools.config")) WAVE_FORMAT = Config.xcellium.get("format") DEFAULT_TMPDIR = utils.get_tmp_folder("sim") SRCS = os.path.join(DEFAULT_TMPDIR, "srcs.list") PARSER_LOG = os.path.join(DEFAULT_TMPDIR, "parser.log") SIM_LOG = os.path.join(DEFAULT_TMPDIR, "sim.log") WAVE = os.path.join(DEFAULT_TMPDIR, "run.%s" % WAVE_FORMAT) # generate scripts gen = prepare(files, params) flags = " ".join(chain([gen], Config.ncsim.get("flags").split())) # run simulation relog.step("Running simulation") executor.sh_exec("xrun %s -f %s" % (flags, SRCS), PARSER_LOG, MAX_TIMEOUT=300)
def compile(generation, flags): # create the executable sim relog.step("Compiling files") # remove inherited timescale flags try: executor.sh_exec( "iverilog -g%s %s -o %s -c %s" % (generation, flags, EXE, SRCS), PARSER_LOG, MAX_TIMEOUT=20, SHOW_CMD=True, ) # ignore return code error # as message is already displayed in stdout # and in the log file except subprocess.CalledProcessError: pass
def main(files, params, format: str = "verilog", top: str = None): prepare(files, params) # fill mako template ext = EXTENSIONS.get(format) if top is None: top = params.get("SYNTH_MODULE")[-1] data = { "top_module": top, "techno": evaluate_bash_var(os.environ["TECH_LIB"]), "netlist": "%s_after_synthesis.%s" % (top, ext), "format": format } data.update(os.environ) # generate yosys script relog.step("Merging synthesis files") _tmp = Template(filename=os.path.join(TOOLS_DIR, "./extra.ys.mako")) with open(SYNTH_SCRIPT, "a+") as fp: fp.write(_tmp.render_unicode(**data)) run()
def run(raw: str): relog.step("Open waveforms") os.makedirs(DEFAULT_TMPDIR, exist_ok=True) # use the appropriate program # depending on the platform if sys.platform == "darwin": ltspice = "/Applications/LTspice.app/Contents/MacOS/LTspice" elif sys.platform == "unix" or "linux" in sys.platform: ltspice = 'wine64 "%s"' % utils.wine.locate("XVIIx64.exe") window_path = io.StringIO() executor.sh_exec("winepath -w '%s'" % raw, window_path, NOERR=True, NOOUT=True) raw = window_path.getvalue().strip().replace("\\", "/") else: ltspice = "XVIIx64.exe" # start the simulation print(raw) executor.sh_exec("%s %s" % (ltspice, raw), SIM_LOG, NOERR=True) return 0, 0 # relog.get_stats(SIM_LOG)
def main(files, PARAMS): # top module top = "tb" if os.path.isfile(PARAMS["TOP_MODULE"]): top, _, _, _ = verilog.find_modules(PARAMS["TOP_MODULE"])[0] # generate script to load files and add parameters n_i = prepare(files, PARAMS) # scoring relog.step("Scoring simulations") for k in range(n_i): COV_K_DATABASE = COV_DATABASE.replace(".cdd", "_%d.cdd" % k) executor.sh_exec( "covered score -f %s -o %s" % (SCORE_SCRIPT % k, COV_K_DATABASE), COV_LOG, mode="a+", MAX_TIMEOUT=300, SHOW_CMD=True, ) # register dbs with open(DB_LIST, "w+") as list: list.writelines( [COV_DATABASE.replace(".cdd", "_%d.cdd" % k) for k in range(n_i)]) # merging into first db if n_i > 1: relog.step("Merging") executor.sh_exec( "covered merge -f %s" % DB_LIST, COV_LOG, "a+", MAX_TIMEOUT=240, SHOW_CMD=True, ) # reporting relog.step("Generating report") executor.sh_exec("covered report -m ltcfram -d s %s" % COV_DATABASE.replace(".cdd", "_0.cdd"), COV_REPORT, MAX_TIMEOUT=30, SHOW_CMD=False) return relog.get_stats(COV_LOG)
def run(): relog.step("Running synthesis") executor.sh_exec("yosys %s" % SYNTH_SCRIPT, SYNTH_LOG, MAX_TIMEOUT=300)
def prepare(files, PARAMS): relog.step("Prepation") # create temporary directory os.makedirs(DEFAULT_TMPDIR, exist_ok=True) # find simulation waveforms (vcd, ...) WAVE = None for wavefile in Path(os.path.dirname(DEFAULT_TMPDIR)).rglob("**/*.vcd"): WAVE = str(wavefile) _, WAVE_FORMAT = os.path.splitext(WAVE) WAVE_FORMAT = WAVE_FORMAT[1:] break if WAVE is None: relog.error("run a simulation first with vcd output") exit(0) # create the list of sources FILES = [f for f, m in files] MIMES = list(set([m for f, m in files])) INCLUDE_DIRS = resolve_includes(FILES) # generate data modules = PARAMS["COV_MODULES"][0].split( " ") if "COV_MODULES" in PARAMS else ["top"] instances = verilog.find_instances(PARAMS["TOP_MODULE"]) top_module, *_ = verilog.find_modules(PARAMS["TOP_MODULE"])[0] instances = [(mod, instance) for mod, pa, instance, po in instances if mod in modules] generation = 3 if any(["SYS" in m for m in MIMES]) else 2 excludes = PARAMS["IP_MODULES"][0].split( " ") if "IP_MODULES" in PARAMS else [] # generate scripts if instances: for k, instance in enumerate(instances): data = { "modules": modules, "instance": instance, "generation": generation, "excludes": excludes, "includes": INCLUDE_DIRS, "files": FILES, "vcd": WAVE, "top": top_module } # generate command file _tmp = Template( filename=os.path.join(TOOLS_DIR, "./score.cmd.mako")) with open(SCORE_SCRIPT % k, "w+") as fp: fp.write(_tmp.render_unicode(**data)) return len(instances) else: data = { "modules": modules, "instance": "", "generation": generation, "excludes": excludes, "includes": INCLUDE_DIRS, "files": FILES, "vcd": WAVE, "top": top_module } # generate command file _tmp = Template(filename=os.path.join(TOOLS_DIR, "./score.cmd.mako")) with open(SCORE_SCRIPT % 0, "w+") as fp: fp.write(_tmp.render_unicode(**data)) return 1
# the tool is wrapped with a perl script # without shebang lines verilator = shutil.which("verilator") def transform_flags(flags: str) -> str: flags = flags.strip() if "-DEFINE " in flags: flags = flags.replace("-DEFINE ", "+define+") if "-define " in flags: flags = flags.replace("-define ", "+define+") return flags if __name__ == "__main__": relog.step("Listing files") # create temporary directory DEFAULT_TMPDIR = utils.get_tmp_folder() SRCS = os.path.join(DEFAULT_TMPDIR, "srcs.list") EXE = os.path.join(DEFAULT_TMPDIR, "run.cpp") PARSER_LOG = os.path.join(DEFAULT_TMPDIR, "parser.log") SIM_LOG = os.path.join(DEFAULT_TMPDIR, "sim.log") WAVE = os.path.join(DEFAULT_TMPDIR, "run.vcd") os.makedirs(DEFAULT_TMPDIR, exist_ok=True) # create the list of sources PARAMS, MIMES, FILES = utils.get_sources(relog.filter_stream(sys.stdin), None) INCLUDE_DIRS = resolve_includes(FILES) with open(SRCS, "w+") as fp: for include_dir in INCLUDE_DIRS: fp.write("+incdir+%s\n" % include_dir) if "SIM_FLAGS" in PARAMS: