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.
This commit is contained in:
Florent Kermarrec 2021-10-28 20:14:35 +02:00
parent 08a9392c54
commit 942e50b992
2 changed files with 83 additions and 13 deletions

View File

@ -44,9 +44,9 @@ def memory_emit_verilog(memory, ns, add_data_file):
# Memory Description. # Memory Description.
# ------------------- # -------------------
r += "//" + "-"*80 + "\n" r += "//" + "-"*78 + "\n"
r += f"// Memory {gn(memory)}: {memory.depth}-words x {memory.width}-bit\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): for n, port in enumerate(memory.ports):
r += f"// Port {n} | " r += f"// Port {n} | "
if port.async_read: 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. # Read-First/No-Change mode: Data already Read on Data Register.
if port.mode in [READ_FIRST, NO_CHANGE]: if port.mode in [READ_FIRST, NO_CHANGE]:
r += f"assign {gn(port.dat_r)} = {gn(data_regs[n])};\n" r += f"assign {gn(port.dat_r)} = {gn(data_regs[n])};\n"
r += "//" + "-"*80 + "\n\n" r += "\n\n"
return r return r

View File

@ -13,6 +13,9 @@
# This file is Copyright (c) 2018 Robin Ole Heinemann <robin.ole.heinemann@t-online.de> # This file is Copyright (c) 2018 Robin Ole Heinemann <robin.ole.heinemann@t-online.de>
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
import time
import datetime
from functools import partial from functools import partial
from operator import itemgetter from operator import itemgetter
import collections import collections
@ -24,7 +27,50 @@ from migen.fhdl.namer import build_namespace
from migen.fhdl.conv_output import ConvOutput from migen.fhdl.conv_output import ConvOutput
from migen.fhdl.specials import Memory 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 # # 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) inouts = list_special_ios(f, ins=False, outs=False, inouts=True)
targets = list_targets(f) | special_outs targets = list_targets(f) | special_outs
wires = _list_comb_wires(f) | special_outs wires = _list_comb_wires(f) | special_outs
r = "module " + name + "(\n"
r = f"module {name} (\n"
firstp = True firstp = True
for sig in sorted(ios, key=lambda x: x.duid): for sig in sorted(ios, key=lambda x: x.duid):
if not firstp: if not firstp:
@ -346,18 +393,29 @@ def _print_module(f, ios, name, ns, attr_translate):
sig.name = ns.get_name(sig) sig.name = ns.get_name(sig)
if sig in inouts: if sig in inouts:
sig.direction = "inout" sig.direction = "inout"
r += "\tinout wire " + _print_signal(ns, sig) r += "\tinout wire " + _print_signal(ns, sig)
elif sig in targets: elif sig in targets:
sig.direction = "output" sig.direction = "output "
if sig in wires: if sig in wires:
r += "\toutput wire " + _print_signal(ns, sig) r += "\toutput wire " + _print_signal(ns, sig)
else: else:
sig.type = "reg" sig.type = "reg"
r += "\toutput reg " + _print_signal(ns, sig) r += "\toutput reg " + _print_signal(ns, sig)
else: else:
sig.direction = "input" sig.direction = "input"
r += "\tinput wire " + _print_signal(ns, sig) r += "\tinput wire " + _print_signal(ns, sig)
r += "\n);\n\n" 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): for sig in sorted(sigs - ios, key=lambda x: x.duid):
attr = _print_attribute(sig.attr, attr_translate) attr = _print_attribute(sig.attr, attr_translate)
if attr: if attr:
@ -365,8 +423,7 @@ def _print_module(f, ios, name, ns, attr_translate):
if sig in wires: if sig in wires:
r += "wire " + _print_signal(ns, sig) + ";\n" r += "wire " + _print_signal(ns, sig) + ";\n"
else: else:
r += "reg " + _print_signal(ns, sig) + " = " + _print_expression(ns, sig.reset)[0] + ";\n" r += "reg " + _print_signal(ns, sig) + " = " + _print_expression(ns, sig.reset)[0] + ";\n"
r += "\n"
return r return r
# ------------------------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------------------------ #
@ -525,27 +582,40 @@ def convert(f, ios=set(), name="top", platform=None,
# Build Verilog. # 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) 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. # Combinatorial Logic.
verilog += _print_separator("Combinatorial Logic")
if regular_comb: if regular_comb:
verilog += _print_combinatorial_logic_synth(f, ns) verilog += _print_combinatorial_logic_synth(f, ns)
else: else:
verilog += _print_combinatorial_logic_sim(f, ns) verilog += _print_combinatorial_logic_sim(f, ns)
# Synchronous Logic. # Synchronous Logic.
verilog += _print_separator("Synchronous Logic")
verilog += _print_synchronous_logic(f, ns) verilog += _print_synchronous_logic(f, ns)
# Specials # Specials
verilog += _print_separator("Specialized Logic")
verilog += _print_specials(special_overrides, f.specials - lowered_specials, verilog += _print_specials(special_overrides, f.specials - lowered_specials,
ns, r.add_data_file, attr_translate) ns, r.add_data_file, attr_translate)
# Module End. # Module End.
verilog += "endmodule\n" verilog += "endmodule\n"
verilog += _print_trailer()
r.set_main_source(verilog) r.set_main_source(verilog)
r.ns = ns r.ns = ns