X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=litex%2Fbuild%2Fsim%2Fverilator.py;h=f068d08d1f899c08b0d03d4983973cfba2c1343c;hb=5a0bb6ee017f78a38a314747d55a95dbe10622c3;hp=608a2f62c7aa11f78f16bfc59c37b5cd3981924b;hpb=e3935b481e9de6b1189408869867a6a099d1dae1;p=litex.git diff --git a/litex/build/sim/verilator.py b/litex/build/sim/verilator.py index 608a2f62..f068d08d 100644 --- a/litex/build/sim/verilator.py +++ b/litex/build/sim/verilator.py @@ -1,5 +1,5 @@ -# This file is Copyright (c) 2015-2016 Florent Kermarrec -# 2017 Pierre-Olivier Vauboin +# This file is Copyright (c) 2015-2019 Florent Kermarrec +# This file is Copyright (c) 2017 Pierre-Olivier Vauboin # License: BSD import os @@ -60,7 +60,7 @@ def _generate_sim_cpp_struct(name, index, siglist): return content -def _generate_sim_cpp(platform): +def _generate_sim_cpp(platform, trace=False, trace_start=0, trace_end=-1): content = """\ #include #include @@ -69,13 +69,28 @@ def _generate_sim_cpp(platform): #include #include "dut_header.h" -extern "C" void litex_sim_init(void **out) +extern "C" void litex_sim_init_tracer(void *vdut, long start, long end); +extern "C" void litex_sim_tracer_dump(); + +extern "C" void litex_sim_dump() { +""" + if trace: + content += """\ + litex_sim_tracer_dump(); +""" + content += """\ +}} + +extern "C" void litex_sim_init(void **out) +{{ Vdut *dut; dut = new Vdut; -""" + litex_sim_init_tracer(dut, {}, {}); + +""".format(trace_start, trace_end) for args in platform.sim_requested: content += _generate_sim_cpp_struct(*args) @@ -90,7 +105,6 @@ def _generate_sim_variables(include_paths): include = "" for path in include_paths: include += "-I"+path+" " - content = """\ SRC_DIR = {} INC_DIR = {} @@ -103,16 +117,26 @@ def _generate_sim_config(config): tools.write_to_file("sim_config.js", content) -def _build_sim(platform, build_name, threads, verbose): +def _build_sim(build_name, sources, threads, coverage, opt_level="O3", trace_fst=False): makefile = os.path.join(core_directory, 'Makefile') + cc_srcs = [] + for filename, language, library in sources: + cc_srcs.append("--cc " + filename + " ") build_script_contents = """\ rm -rf obj_dir/ -make -C . -f {} {} -mkdir -p modules && cp obj_dir/*.so modules -""".format(makefile, "THREADS={}".format(threads) if int(threads) > 1 else "") +make -C . -f {} {} {} {} {} {} +""".format(makefile, + "CC_SRCS=\"{}\"".format("".join(cc_srcs)), + "THREADS={}".format(threads) if int(threads) > 1 else "", + "COVERAGE=1" if coverage else "", + "OPT_LEVEL={}".format(opt_level), + "TRACE_FST=1" if trace_fst else "", + ) build_script_file = "build_" + build_name + ".sh" tools.write_to_file(build_script_file, build_script_contents, force_unix=True) +def _compile_sim(build_name, verbose): + build_script_file = "build_" + build_name + ".sh" p = subprocess.Popen(["bash", build_script_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output, _ = p.communicate() output = output.decode('utf-8') @@ -125,7 +149,6 @@ mkdir -p modules && cp obj_dir/*.so modules if verbose: print(output) - def _run_sim(build_name, as_root=False): run_script_contents = "sudo " if as_root else "" run_script_contents += "obj_dir/Vdut" @@ -139,46 +162,58 @@ def _run_sim(build_name, as_root=False): if r != 0: raise OSError("Subprocess failed") except: - if sys.platform != "win32": - termios.tcsetattr(sys.stdin.fileno(), termios.TCSAFLUSH, termios_settings) + pass + if sys.platform != "win32": + termios.tcsetattr(sys.stdin.fileno(), termios.TCSAFLUSH, termios_settings) class SimVerilatorToolchain: def build(self, platform, fragment, build_dir="build", build_name="dut", - toolchain_path=None, serial="console", build=True, run=True, threads=1, - verbose=True, sim_config=None): + serial="console", build=True, run=True, threads=1, + verbose=True, sim_config=None, coverage=False, opt_level="O0", + trace=False, trace_fst=False, trace_start=0, trace_end=-1): + # create build directory os.makedirs(build_dir, exist_ok=True) os.chdir(build_dir) if build: + # finalize design if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() platform.finalize(fragment) - v_output = platform.get_verilog(fragment, + # generate top module + top_output = platform.get_verilog(fragment, name=build_name, dummy_signal=False, regular_comb=False, blocking_assign=True) - named_sc, named_pc = platform.resolve_signals(v_output.ns) - v_output.write(build_name + ".v") - - include_paths = [] - for source in platform.sources: - path = os.path.dirname(source[0]).replace("\\", "\/") - if path not in include_paths: - include_paths.append(path) - include_paths += platform.verilog_include_paths + named_sc, named_pc = platform.resolve_signals(top_output.ns) + top_file = build_name + ".v" + top_output.write(top_file) + platform.add_source(top_file) + + # generate cpp header/main/variables _generate_sim_h(platform) - _generate_sim_cpp(platform) - _generate_sim_variables(include_paths) + _generate_sim_cpp(platform, trace, trace_start, trace_end) + _generate_sim_variables(platform.verilog_include_paths) + + # generate sim config if sim_config: _generate_sim_config(sim_config) - _build_sim(platform, build_name, threads, verbose) + # build + _build_sim(build_name, platform.sources, threads, coverage, opt_level, trace_fst) + # run if run: - _run_sim(build_name, as_root=sim_config.has_module("ethernet")) + _compile_sim(build_name, verbose) + run_as_root = False + if sim_config.has_module("ethernet"): + run_as_root = True + if sim_config.has_module("xgmii_ethernet"): + run_as_root = True + _run_sim(build_name, as_root=run_as_root) os.chdir("../../") if build: - return v_output.ns \ No newline at end of file + return top_output.ns