Пример #1
0
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")
Пример #2
0
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)
Пример #3
0
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)
Пример #4
0
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)
Пример #5
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)
Пример #6
0
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)
Пример #7
0
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()
Пример #8
0
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)
Пример #9
0
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
Пример #10
0
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()
Пример #11
0
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)
Пример #12
0
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)
Пример #13
0
def run():
    relog.step("Running synthesis")
    executor.sh_exec("yosys %s" % SYNTH_SCRIPT, SYNTH_LOG, MAX_TIMEOUT=300)
Пример #14
0
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
Пример #15
0
# 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: