back.rtlil: emit \src attributes for processes via Switch and Assign.
The locations are unfortunately not very precise, but they provide some improvement over status quo.
This commit is contained in:
parent
e351e27206
commit
82903e493a
4 changed files with 57 additions and 13 deletions
|
|
@ -55,9 +55,9 @@ class _Bufferer:
|
|||
self._append("{}attribute \\{} {}\n",
|
||||
" " * indent, name, int(value))
|
||||
|
||||
def _src(self, src):
|
||||
def _src(self, src, **kwargs):
|
||||
if src:
|
||||
self.attribute("src", src)
|
||||
self.attribute("src", src, **kwargs)
|
||||
|
||||
|
||||
class _Builder(_Namer, _Bufferer):
|
||||
|
|
@ -142,7 +142,7 @@ class _ProcessBuilder(_Bufferer):
|
|||
self.src = src
|
||||
|
||||
def __enter__(self):
|
||||
self._src(self.src)
|
||||
self._src(self.src, indent=1)
|
||||
self._append(" process {}\n", self.name)
|
||||
return self
|
||||
|
||||
|
|
@ -222,6 +222,10 @@ def src(src_loc):
|
|||
return "{}:{}".format(file, line)
|
||||
|
||||
|
||||
def srcs(src_locs):
|
||||
return "|".join(sorted(map(src, src_locs)))
|
||||
|
||||
|
||||
class LegalizeValue(Exception):
|
||||
def __init__(self, value, branches):
|
||||
self.value = value
|
||||
|
|
@ -579,6 +583,34 @@ class _LHSValueCompiler(_ValueCompiler):
|
|||
raise TypeError # :nocov:
|
||||
|
||||
|
||||
class _StatementLocator(xfrm.StatementVisitor):
|
||||
def __init__(self):
|
||||
self.src_locs = set()
|
||||
|
||||
def on_Assign(self, stmt):
|
||||
self.src_locs.add(stmt.src_loc)
|
||||
|
||||
def on_Switch(self, stmt):
|
||||
self.src_locs.add(stmt.src_loc)
|
||||
for stmts in stmt.cases.values():
|
||||
self.on_statements(stmts)
|
||||
|
||||
def on_ignored(self, stmt):
|
||||
pass
|
||||
|
||||
on_Assert = on_ignored
|
||||
on_Assume = on_ignored
|
||||
|
||||
def on_statements(self, stmts):
|
||||
for stmt in stmts:
|
||||
self.on_statement(stmt)
|
||||
|
||||
def __call__(self, stmt):
|
||||
self.on_statement(stmt)
|
||||
src_locs, self.src_locs = self.src_locs, set()
|
||||
return src_locs
|
||||
|
||||
|
||||
class _StatementCompiler(xfrm.StatementVisitor):
|
||||
def __init__(self, state, rhs_compiler, lhs_compiler):
|
||||
self.state = state
|
||||
|
|
@ -689,6 +721,7 @@ def convert_fragment(builder, fragment, hierarchy):
|
|||
compiler_state = _ValueCompilerState(module)
|
||||
rhs_compiler = _RHSValueCompiler(compiler_state)
|
||||
lhs_compiler = _LHSValueCompiler(compiler_state)
|
||||
stmt_locator = _StatementLocator()
|
||||
stmt_compiler = _StatementCompiler(compiler_state, rhs_compiler, lhs_compiler)
|
||||
|
||||
verilog_trigger = None
|
||||
|
|
@ -778,8 +811,10 @@ def convert_fragment(builder, fragment, hierarchy):
|
|||
|
||||
for group, group_signals in lhs_grouper.groups().items():
|
||||
lhs_group_filter = xfrm.LHSGroupFilter(group_signals)
|
||||
group_stmts = lhs_group_filter(fragment.statements)
|
||||
|
||||
with module.process(name="$group_{}".format(group)) as process:
|
||||
with module.process(name="$group_{}".format(group),
|
||||
src=srcs(stmt_locator(group_stmts))) as process:
|
||||
with process.case() as case:
|
||||
# For every signal in comb domain, assign \sig$next to the reset value.
|
||||
# For every signal in sync domains, assign \sig$next to the current
|
||||
|
|
@ -796,7 +831,7 @@ def convert_fragment(builder, fragment, hierarchy):
|
|||
# Convert statements into decision trees.
|
||||
stmt_compiler._case = case
|
||||
stmt_compiler._has_rhs = False
|
||||
stmt_compiler(lhs_group_filter(fragment.statements))
|
||||
stmt_compiler(group_stmts)
|
||||
|
||||
# Verilog `always @*` blocks will not run if `*` does not match anything, i.e.
|
||||
# if the implicit sensitivity list is empty. We check this while translating,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue