From 942e50b992728da7227e8f99d384450eef89a55b Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 28 Oct 2021 20:14:35 +0200 Subject: [PATCH] fhdl/verilog: Improve code presentation. - Add a LiteX Header/Trailer. - Add _print_signal function. - Add more infos to the Header. - Add separators between blocks of code. - Align Wire/Reg definition. --- litex/gen/fhdl/memory.py | 6 +-- litex/gen/fhdl/verilog.py | 90 ++++++++++++++++++++++++++++++++++----- 2 files changed, 83 insertions(+), 13 deletions(-) diff --git a/litex/gen/fhdl/memory.py b/litex/gen/fhdl/memory.py index 19fd6793f..34b53078b 100644 --- a/litex/gen/fhdl/memory.py +++ b/litex/gen/fhdl/memory.py @@ -44,9 +44,9 @@ def memory_emit_verilog(memory, ns, add_data_file): # Memory Description. # ------------------- - r += "//" + "-"*80 + "\n" + r += "//" + "-"*78 + "\n" r += f"// Memory {gn(memory)}: {memory.depth}-words x {memory.width}-bit\n" - r += "//" + "-"*80 + "\n" + r += "//" + "-"*78 + "\n" for n, port in enumerate(memory.ports): r += f"// Port {n} | " if port.async_read: @@ -150,6 +150,6 @@ def memory_emit_verilog(memory, ns, add_data_file): # Read-First/No-Change mode: Data already Read on Data Register. if port.mode in [READ_FIRST, NO_CHANGE]: r += f"assign {gn(port.dat_r)} = {gn(data_regs[n])};\n" - r += "//" + "-"*80 + "\n\n" + r += "\n\n" return r diff --git a/litex/gen/fhdl/verilog.py b/litex/gen/fhdl/verilog.py index 33020394c..5973ba372 100644 --- a/litex/gen/fhdl/verilog.py +++ b/litex/gen/fhdl/verilog.py @@ -13,6 +13,9 @@ # This file is Copyright (c) 2018 Robin Ole Heinemann # SPDX-License-Identifier: BSD-2-Clause +import time +import datetime + from functools import partial from operator import itemgetter import collections @@ -24,7 +27,50 @@ from migen.fhdl.namer import build_namespace from migen.fhdl.conv_output import ConvOutput from migen.fhdl.specials import Memory -from litex.build.tools import generated_banner +from litex.build.tools import get_litex_git_revision + +# ------------------------------------------------------------------------------------------------ # +# BANNER/TRAILER/SEPARATORS # +# ------------------------------------------------------------------------------------------------ # + +def _print_banner(filename, device): + return """\ +// ----------------------------------------------------------------------------- +// Auto-Generated by: __ _ __ _ __ +// / / (_) /____ | |/_/ +// / /__/ / __/ -_)> < +// /____/_/\\__/\\__/_/|_| +// Build your hardware, easily! +// https://github.com/enjoy-digital/litex +// +// Filename : {filename}.v +// Device : {device} +// LiteX sha1 : {revision} +// Date : {date} +//------------------------------------------------------------------------------\n +""".format( + device = device, + filename = filename, + revision = get_litex_git_revision(), + date = datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S") +) + +def _print_trailer(): + return """ +// ----------------------------------------------------------------------------- +// Auto-Generated by LiteX on {date}. +//------------------------------------------------------------------------------ +""".format( + date=datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S") +) + +def _print_separator(msg=""): + r = "\n" + r += "//" + "-"*78 + "\n" + r += f"// {msg}\n" + r += "//" + "-"*78 + "\n" + r += "\n" + return r # ------------------------------------------------------------------------------------------------ # # RESERVED KEYWORDS # @@ -333,7 +379,8 @@ def _print_module(f, ios, name, ns, attr_translate): inouts = list_special_ios(f, ins=False, outs=False, inouts=True) targets = list_targets(f) | special_outs wires = _list_comb_wires(f) | special_outs - r = "module " + name + "(\n" + + r = f"module {name} (\n" firstp = True for sig in sorted(ios, key=lambda x: x.duid): if not firstp: @@ -346,18 +393,29 @@ def _print_module(f, ios, name, ns, attr_translate): sig.name = ns.get_name(sig) if sig in inouts: sig.direction = "inout" - r += "\tinout wire " + _print_signal(ns, sig) + r += "\tinout wire " + _print_signal(ns, sig) elif sig in targets: - sig.direction = "output" + sig.direction = "output " if sig in wires: r += "\toutput wire " + _print_signal(ns, sig) else: sig.type = "reg" - r += "\toutput reg " + _print_signal(ns, sig) + r += "\toutput reg " + _print_signal(ns, sig) else: sig.direction = "input" - r += "\tinput wire " + _print_signal(ns, sig) + r += "\tinput wire " + _print_signal(ns, sig) r += "\n);\n\n" + + return r + +def _print_signals(f, ios, name, ns, attr_translate): + sigs = list_signals(f) | list_special_ios(f, ins=True, outs=True, inouts=True) + special_outs = list_special_ios(f, ins=False, outs=True, inouts=True) + inouts = list_special_ios(f, ins=False, outs=False, inouts=True) + targets = list_targets(f) | special_outs + wires = _list_comb_wires(f) | special_outs + + r = "" for sig in sorted(sigs - ios, key=lambda x: x.duid): attr = _print_attribute(sig.attr, attr_translate) if attr: @@ -365,8 +423,7 @@ def _print_module(f, ios, name, ns, attr_translate): if sig in wires: r += "wire " + _print_signal(ns, sig) + ";\n" else: - r += "reg " + _print_signal(ns, sig) + " = " + _print_expression(ns, sig.reset)[0] + ";\n" - r += "\n" + r += "reg " + _print_signal(ns, sig) + " = " + _print_expression(ns, sig.reset)[0] + ";\n" return r # ------------------------------------------------------------------------------------------------ # @@ -525,27 +582,40 @@ def convert(f, ios=set(), name="top", platform=None, # Build Verilog. # -------------- - verilog = generated_banner("//") + verilog = "" + verilog += _print_banner( + filename = name, + device = getattr(platform, "device", "Unknown") + ) - # Module Top. + # Module Definition. + verilog += _print_separator("Module") verilog += _print_module(f, ios, name, ns, attr_translate) + # Module Signals. + verilog += _print_separator("Signals") + verilog += _print_signals(f, ios, name, ns, attr_translate) + # Combinatorial Logic. + verilog += _print_separator("Combinatorial Logic") if regular_comb: verilog += _print_combinatorial_logic_synth(f, ns) else: verilog += _print_combinatorial_logic_sim(f, ns) # Synchronous Logic. + verilog += _print_separator("Synchronous Logic") verilog += _print_synchronous_logic(f, ns) # Specials + verilog += _print_separator("Specialized Logic") verilog += _print_specials(special_overrides, f.specials - lowered_specials, ns, r.add_data_file, attr_translate) # Module End. verilog += "endmodule\n" + verilog += _print_trailer() r.set_main_source(verilog) r.ns = ns