From b7a1888a36d4b6457268cb6d5a4cb4edb8859b86 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 2 Dec 2015 12:37:53 +0100 Subject: [PATCH] gen/fhdl/verilog: add regular comb parameter to allow implementation of simulation code (for icarus) We will remove that when we will be using new migen simulator --- litex/gen/fhdl/verilog.py | 61 ++++++++++++++++++++++++-------- litex/gen/sim/generic.py | 1 + litex/soc/integration/builder.py | 11 +++--- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/litex/gen/fhdl/verilog.py b/litex/gen/fhdl/verilog.py index 018e48aa..bb0c4443 100644 --- a/litex/gen/fhdl/verilog.py +++ b/litex/gen/fhdl/verilog.py @@ -9,7 +9,7 @@ from litex.gen.fhdl.bitcontainer import bits_for from litex.gen.fhdl.namer import build_namespace from litex.gen.fhdl.conv_output import ConvOutput -# TODO: clean up simulation hack +# TODO: remove printcomb_simulation when we will be using new migen simulator _reserved_keywords = { "always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1", @@ -207,10 +207,10 @@ def _printheader(f, ios, name, ns, return r -def _printcomb(f, ns, - display_run, - dummy_signal, - blocking_assign): +def _printcomb_simulation(f, ns, + display_run, + dummy_signal, + blocking_assign): r = "" if f.comb: if dummy_signal: @@ -251,20 +251,44 @@ def _printcomb(f, ns, if display_run: r += "\t$display(\"Running comb block #" + str(n) + "\");\n" if blocking_assign: - r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n" - r += _printnode(ns, _AT_BLOCKING, 1, stmts, t) + r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n" + r += _printnode(ns, _AT_BLOCKING, 1, stmts, t) else: - r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n" - r += _printnode(ns, _AT_NONBLOCKING, 1, stmts, t) + r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n" + r += _printnode(ns, _AT_NONBLOCKING, 1, stmts, t) if dummy_signal: - r += syn_off - r += "\t" + ns.get_name(dummy_d) + " = " + ns.get_name(dummy_s) + ";\n" - r += syn_on + r += syn_off + r += "\t" + ns.get_name(dummy_d) + " = " + ns.get_name(dummy_s) + ";\n" + r += syn_on r += "end\n" r += "\n" return r +def _printcomb_regular(f, ns, blocking_assign): + r = "" + if f.comb: + groups = group_by_targets(f.comb) + + for n, g in enumerate(groups): + if len(g[1]) == 1 and isinstance(g[1][0], _Assign): + r += "assign " + _printnode(ns, _AT_BLOCKING, 0, g[1][0]) + else: + r += "always @(*) begin\n" + if blocking_assign: + for t in g[0]: + r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n" + r += _printnode(ns, _AT_BLOCKING, 1, g[1]) + else: + for t in g[0]: + r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n" + r += _printnode(ns, _AT_NONBLOCKING, 1, g[1]) + r += "end\n" + r += "\n" + return r + + + def _printsync(f, ns): r = "" for k, v in sorted(f.sync.items(), key=itemgetter(0)): @@ -331,7 +355,8 @@ def convert(f, ios=None, name="top", display_run=False, reg_initialization=True, dummy_signal=True, - blocking_assign=False): + blocking_assign=False, + regular_comb=True): r = ConvOutput() if not isinstance(f, _Fragment): f = f.get_fragment() @@ -361,10 +386,16 @@ def convert(f, ios=None, name="top", ns.clock_domains = f.clock_domains r.ns = ns - src = "/* Machine-generated using LiteX gen*/\n" + src = "/* Machine-generated using LiteX gen " + src += "(regular)" if regular_comb else "(simulation)" + src += " */\n" src += _printheader(f, ios, name, ns, reg_initialization=reg_initialization) - src += _printcomb(f, ns, + if regular_comb: + src += _printcomb_regular(f, ns, + blocking_assign=blocking_assign) + else: + src += _printcomb_simulation(f, ns, display_run=display_run, dummy_signal=dummy_signal, blocking_assign=blocking_assign) diff --git a/litex/gen/sim/generic.py b/litex/gen/sim/generic.py index c0ed3c54..1144ac88 100644 --- a/litex/gen/sim/generic.py +++ b/litex/gen/sim/generic.py @@ -102,6 +102,7 @@ class Simulator: c_fragment = verilog.convert(fragment, ios=self.top_level.ios, name=self.top_level.dut_type, + regular_comb=False, **vopts) self.namespace = c_fragment.ns diff --git a/litex/soc/integration/builder.py b/litex/soc/integration/builder.py index b209e706..9b2117fc 100644 --- a/litex/soc/integration/builder.py +++ b/litex/soc/integration/builder.py @@ -130,7 +130,7 @@ class Builder: boot_data.append(struct.unpack(">I", w)[0]) self.soc.initialize_rom(boot_data) - def build(self): + def build(self, toolchain_path=None, **kwargs): self.soc.finalize() os.makedirs(self.output_dir, exist_ok=True) @@ -145,12 +145,11 @@ class Builder: self._generate_software() self._initialize_rom() - if self.gateware_toolchain_path is None: - kwargs = dict() - else: - kwargs = {"toolchain_path": self.gateware_toolchain_path} + if self.gateware_toolchain_path is not None: + toolchain_path = self.gateware_toolchain_path self.soc.build(build_dir=os.path.join(self.output_dir, "gateware"), - run=self.compile_gateware, **kwargs) + run=self.compile_gateware, toolchain_path=toolchain_path, + **kwargs) def builder_args(parser): -- 2.30.2