diff --git a/mibuild/platforms/sim.py b/mibuild/platforms/sim.py index a0f83a5d4..3572872c5 100644 --- a/mibuild/platforms/sim.py +++ b/mibuild/platforms/sim.py @@ -1,5 +1,5 @@ from mibuild.generic_platform import * -from mibuild.sim.verilator import VerilatorPlatform +from mibuild.sim import SimPlatform class SimPins(Pins): def __init__(self, n): @@ -31,13 +31,13 @@ _io = [ ), ] -class Platform(VerilatorPlatform): +class Platform(SimPlatform): is_sim = True default_clk_name = "sys_clk" default_clk_period = 1000 # on modern computers simulate at ~ 1MHz def __init__(self): - VerilatorPlatform.__init__(self, "SIM", _io) + SimPlatform.__init__(self, "SIM", _io) def do_finalize(self, fragment): pass diff --git a/mibuild/sim/__init__.py b/mibuild/sim/__init__.py index e69de29bb..439f0a8e1 100644 --- a/mibuild/sim/__init__.py +++ b/mibuild/sim/__init__.py @@ -0,0 +1 @@ +from mibuild.sim.platform import SimPlatform diff --git a/mibuild/sim/common.py b/mibuild/sim/common.py new file mode 100644 index 000000000..38741fd4b --- /dev/null +++ b/mibuild/sim/common.py @@ -0,0 +1 @@ +sim_special_overrides = {} diff --git a/mibuild/sim/platform.py b/mibuild/sim/platform.py new file mode 100644 index 000000000..b781f3c3c --- /dev/null +++ b/mibuild/sim/platform.py @@ -0,0 +1,19 @@ +from mibuild.generic_platform import GenericPlatform +from mibuild.sim import common, verilator + +class SimPlatform(GenericPlatform): + def __init__(self, *args, toolchain="verilator", **kwargs): + GenericPlatform.__init__(self, *args, **kwargs) + if toolchain == "verilator": + self.toolchain = verilator.SimVerilatorToolchain() + else: + raise ValueError("Unknown toolchain") + + def get_verilog(self, *args, special_overrides=dict(), **kwargs): + so = dict(common.sim_special_overrides) + so.update(special_overrides) + return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs) + + def build(self, *args, **kwargs): + return self.toolchain.build(self, *args, **kwargs) + diff --git a/mibuild/sim/verilator.py b/mibuild/sim/verilator.py index 4d94ada38..b3d221d52 100644 --- a/mibuild/sim/verilator.py +++ b/mibuild/sim/verilator.py @@ -7,13 +7,16 @@ from migen.fhdl.std import * from migen.fhdl.structure import _Fragment from mibuild.generic_platform import * -def _build_tb(platform, serial, template): +from mibuild import tools +from mibuild.sim import common + +def _build_tb(platform, vns, serial, template): def io_name(ressource, subsignal=None): res = platform.lookup_request(ressource) if subsignal is not None: res = getattr(res, subsignal) - return platform.vns.get_name(res) + return vns.get_name(res) ios = """ #define SYS_CLK dut->{sys_clk} @@ -79,7 +82,7 @@ def _build_tb(platform, serial, template): f.close() tools.write_to_file("dut_tb.cpp", content) -def _build_sim(platform, build_name, include_paths, sim_path, serial, verbose): +def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbose): include = "" for path in include_paths: include += "-I"+path+" " @@ -95,7 +98,7 @@ make -j -C obj_dir/ -f Vdut.mk Vdut build_script_file = "build_" + build_name + ".sh" tools.write_to_file(build_script_file, build_script_contents, force_unix=True) - _build_tb(platform, serial, os.path.join("..", sim_path,"dut_tb.cpp")) + _build_tb(platform, vns, serial, os.path.join("..", sim_path,"dut_tb.cpp")) if verbose: r = subprocess.call(["bash", build_script_file]) else: @@ -112,32 +115,34 @@ def _run_sim(build_name): if r != 0: raise OSError("Subprocess failed") -class VerilatorPlatform(GenericPlatform): +class SimVerilatorToolchain: # XXX fir sim_path - def build(self, soc, build_dir="build", build_name="top", + def build(self, platform, fragment, build_dir="build", build_name="top", sim_path="../migen/mibuild/sim/", serial="console", run=True, verbose=False): tools.mkdir_noerror(build_dir) os.chdir(build_dir) - self.soc = soc - fragment = soc.get_fragment() - self.finalize(fragment) - v_src, vns = self.get_verilog(fragment) - named_sc, named_pc = self.resolve_signals(vns) - self.vns = vns + if not isinstance(fragment, _Fragment): + fragment = fragment.get_fragment() + platform.finalize(fragment) + + v_src, vns = platform.get_verilog(fragment) + named_sc, named_pc = platform.resolve_signals(vns) v_file = "dut.v" tools.write_to_file(v_file, v_src) include_paths = [] - for source in self.sources: + for source in platform.sources: path = os.path.dirname(source[0]).replace("\\", "\/") if path not in include_paths: include_paths.append(path) - include_paths += self.verilog_include_paths - _build_sim(self, build_name, include_paths, sim_path, serial, verbose) + include_paths += platform.verilog_include_paths + _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbose) if run: _run_sim(build_name) os.chdir("..") + + return vns