From dee64b346f84b4986607c13fe9c0089792f16eb3 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 3 Nov 2023 11:40:16 +0100 Subject: [PATCH] gen/fhdl: Integrate Migen's Instance verilog generation to be able to customize it to our needs. --- litex/gen/fhdl/instance.py | 55 ++++++++++++++++++++++++++++++++++++++ litex/gen/fhdl/verilog.py | 8 ++++-- 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 litex/gen/fhdl/instance.py diff --git a/litex/gen/fhdl/instance.py b/litex/gen/fhdl/instance.py new file mode 100644 index 000000000..b948d720c --- /dev/null +++ b/litex/gen/fhdl/instance.py @@ -0,0 +1,55 @@ +# +# This file is part of LiteX (Adapted from Migen for LiteX usage). +# +# This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq +# SPDX-License-Identifier: BSD-2-Clause + +from migen.fhdl.structure import * +from migen.fhdl.verilog import _printexpr as verilog_printexpr +from migen.fhdl.specials import * + +# LiteX Instance Verilog Generation ---------------------------------------------------------------- + +def _instance_generate_verilog(instance, ns, add_data_file): + r = instance.of + " " + parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items)) + if parameters: + r += "#(\n" + firstp = True + for p in parameters: + if not firstp: + r += ",\n" + firstp = False + r += "\t." + p.name + "(" + if isinstance(p.value, Constant): + r += verilog_printexpr(ns, p.value)[0] + elif isinstance(p.value, float): + r += str(p.value) + elif isinstance(p.value, Instance.PreformattedParam): + r += p.value + elif isinstance(p.value, str): + r += "\"" + p.value + "\"" + else: + raise TypeError + r += ")" + r += "\n) " + r += ns.get_name(instance) + if parameters: r += " " + r += "(\n" + firstp = True + for p in instance.items: + if isinstance(p, Instance._IO): + name_inst = p.name + name_design = verilog_printexpr(ns, p.expr)[0] + if not firstp: + r += ",\n" + firstp = False + r += "\t." + name_inst + "(" + name_design + ")" + if not firstp: + r += "\n" + if instance.synthesis_directive is not None: + synthesis_directive = "/* synthesis {} */".format(instance.synthesis_directive) + r += ")" + synthesis_directive + ";\n\n" + else: + r += ");\n\n" + return r diff --git a/litex/gen/fhdl/verilog.py b/litex/gen/fhdl/verilog.py index 87cf629d8..bce9ce3cb 100644 --- a/litex/gen/fhdl/verilog.py +++ b/litex/gen/fhdl/verilog.py @@ -2,7 +2,7 @@ # This file is part of LiteX (Adapted from Migen for LiteX usage). # # This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq -# This file is Copyright (c) 2013-2021 Florent Kermarrec +# This file is Copyright (c) 2013-2023 Florent Kermarrec # This file is Copyright (c) 2013-2017 Robert Jordens # This file is Copyright (c) 2016-2018 whitequark # This file is Copyright (c) 2017 Adam Greig @@ -23,7 +23,7 @@ from migen.fhdl.structure import * from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment from migen.fhdl.tools import * from migen.fhdl.conv_output import ConvOutput -from migen.fhdl.specials import Memory +from migen.fhdl.specials import Instance, Memory from litex.gen import LiteXContext from litex.gen.fhdl.namer import build_namespace @@ -529,6 +529,10 @@ def _generate_specials(name, overrides, specials, namespace, add_data_file, attr if isinstance(special, Memory): from litex.gen.fhdl.memory import _memory_generate_verilog pr = _memory_generate_verilog(name, special, namespace, add_data_file) + # Replace Migen Instance's emit_verilog with LiteX's implementation. + elif isinstance(special, Instance): + from litex.gen.fhdl.instance import _instance_generate_verilog + pr = _instance_generate_verilog(special, namespace, add_data_file) else: pr = call_special_classmethod(overrides, special, "emit_verilog", namespace, add_data_file) if pr is None: