fhdl/verilog: Create _print_cat/_print_replicate, start cleaning up convert.

This commit is contained in:
Florent Kermarrec 2021-10-15 14:25:33 +02:00
parent 2c98ad94b5
commit 8aad25ae2b
1 changed files with 93 additions and 43 deletions

View File

@ -167,6 +167,17 @@ def _print_slice(ns, node):
r, s = _print_expression(ns, node.value) r, s = _print_expression(ns, node.value)
return r + sr, s return r + sr, s
# Print Cat ----------------------------------------------------------------------------------------
def _print_cat(ns, node):
l = [_print_expression(ns, v)[0] for v in reversed(node.l)]
return "{" + ", ".join(l) + "}", False
# Print Replicate ----------------------------------------------------------------------------------
def _print_replicate(ns, node):
return "{" + str(node.n) + "{" + _print_expression(ns, node.v)[0] + "}}", False
# Print Expression --------------------------------------------------------------------------------- # Print Expression ---------------------------------------------------------------------------------
def _print_expression(ns, node): def _print_expression(ns, node):
@ -188,14 +199,15 @@ def _print_expression(ns, node):
# Cat. # Cat.
elif isinstance(node, Cat): elif isinstance(node, Cat):
l = [_print_expression(ns, v)[0] for v in reversed(node.l)] return _print_cat(ns, node)
return "{" + ", ".join(l) + "}", False
# Replicate. # Replicate.
elif isinstance(node, Replicate): elif isinstance(node, Replicate):
return "{" + str(node.n) + "{" + _print_expression(ns, node.v)[0] + "}}", False return _print_replicate(ns, node)
# Unknown.
else: else:
raise TypeError("Expression of unrecognized type: '{}'".format(type(node).__name__)) raise TypeError(f"Expression of unrecognized type: '{type(node).__name__}'")
# Print Node --------------------------------------------------------------------------------------- # Print Node ---------------------------------------------------------------------------------------
@ -293,11 +305,11 @@ def _list_comb_wires(f):
def _print_module(f, ios, name, ns, attr_translate, def _print_module(f, ios, name, ns, attr_translate,
reg_initialization): reg_initialization):
sigs = list_signals(f) | list_special_ios(f, True, True, True) sigs = list_signals(f) | list_special_ios(f, ins=True, outs=True, inouts=True)
special_outs = list_special_ios(f, False, True, True) special_outs = list_special_ios(f, ins=False, outs=True, inouts=True)
inouts = list_special_ios(f, False, False, 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 = "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):
@ -455,67 +467,105 @@ class DummyAttrTranslate(dict):
def __getitem__(self, k): def __getitem__(self, k):
return (k, "true") return (k, "true")
def convert(f, ios=None, name="top", def convert(f, ios=set(), name="top",
special_overrides = dict(), special_overrides = dict(),
attr_translate = DummyAttrTranslate(), attr_translate = DummyAttrTranslate(),
create_clock_domains = True, create_clock_domains = True,
display_run = False, display_run = False,
reg_initialization = True, reg_initialization = True,
dummy_signal = True, dummy_signal = True,
blocking_assign = False, blocking_assign = False,
regular_comb = True): regular_comb = True):
# Create ConvOutput.
r = ConvOutput() r = ConvOutput()
# Convert to FHDL's fragments is not already done.
if not isinstance(f, _Fragment): if not isinstance(f, _Fragment):
f = f.get_fragment() f = f.get_fragment()
if ios is None:
ios = set()
# Verify/Create Clock Domains.
for cd_name in sorted(list_clock_domains(f)): for cd_name in sorted(list_clock_domains(f)):
# Try to get Clock Domain.
try: try:
f.clock_domains[cd_name] f.clock_domains[cd_name]
except KeyError: # If not found, create it if enabled:
except:
if create_clock_domains: if create_clock_domains:
cd = ClockDomain(cd_name) cd = ClockDomain(cd_name)
f.clock_domains.append(cd) f.clock_domains.append(cd)
ios |= {cd.clk, cd.rst} ios |= {cd.clk, cd.rst}
# Or raise Error.
else: else:
msg = f"""Unresolved clock domain {cd_name}, availables:\n""" msg = f"""Unresolved clock domain {cd_name}, availables:\n"""
for f in f.clock_domains: for f in f.clock_domains:
msg += f"- {f.name}\n" msg += f"- {f.name}\n"
raise Exception(msg) raise Exception(msg)
# Lower complex slices.
f = lower_complex_slices(f) f = lower_complex_slices(f)
# Insert resets.
insert_resets(f) insert_resets(f)
f = lower_basics(f)
f, lowered_specials = lower_specials(special_overrides, f) # Lower basics.
f = lower_basics(f) f = lower_basics(f)
# Lower specials.
f, lowered_specials = lower_specials(special_overrides, f)
# Lower basics (for basics included in specials).
f = lower_basics(f)
# IOs backtrace/naming.
for io in sorted(ios, key=lambda x: x.duid): for io in sorted(ios, key=lambda x: x.duid):
if io.name_override is None: if io.name_override is None:
io_name = io.backtrace[-1][0] io_name = io.backtrace[-1][0]
if io_name: if io_name:
io.name_override = io_name io.name_override = io_name
ns = build_namespace(list_signals(f) \
| list_special_ios(f, True, True, True) \ # Build NameSpace.
| ios, _ieee_1800_2017_verilog_reserved_keywords) # ----------------
ns = build_namespace(
signals = (
list_signals(f) |
list_special_ios(f, ins=True, outs=True, inouts=True) |
ios),
reserved_keywords = _ieee_1800_2017_verilog_reserved_keywords
)
ns.clock_domains = f.clock_domains ns.clock_domains = f.clock_domains
# Build Verilog.
# --------------
verilog = generated_banner("//")
# Module Top.
verilog += _print_module(f, ios, name, ns, attr_translate, reg_initialization=reg_initialization)
# Combinatorial Logic.
if regular_comb:
verilog += _print_combinatorial_logic_synth(f, ns,
blocking_assign = blocking_assign
)
else:
verilog += _print_combinatorial_logic_sim(f, ns,
display_run = display_run,
dummy_signal = dummy_signal,
blocking_assign = blocking_assign
)
# Synchronous Logic.
verilog += _print_synchronous_logic(f, ns)
# Specials
verilog += _print_specials(special_overrides, f.specials - lowered_specials,
ns, r.add_data_file, attr_translate)
# Module End.
verilog += "endmodule\n"
r.set_main_source(verilog)
r.ns = ns r.ns = ns
src = generated_banner("//")
src += _print_module(f, ios, name, ns, attr_translate,
reg_initialization=reg_initialization)
if regular_comb:
src += _print_combinatorial_logic_synth(f, ns,
blocking_assign=blocking_assign)
else:
src += _print_combinatorial_logic_sim(f, ns,
display_run=display_run,
dummy_signal=dummy_signal,
blocking_assign=blocking_assign)
src += _print_synchronous_logic(f, ns)
src += _print_specials(special_overrides, f.specials - lowered_specials,
ns, r.add_data_file, attr_translate)
src += "endmodule\n"
r.set_main_source(src)
return r return r