3 from collections
import defaultdict
, OrderedDict
4 from contextlib
import contextmanager
6 from ..tools
import bits_for
, flatten
7 from ..hdl
import ast
, rec
, ir
, mem
, xfrm
19 def _make_name(self
, name
, local
):
22 name
= "${}".format(self
._index
)
23 elif not local
and name
[0] not in "\\$":
24 name
= "\\{}".format(name
)
25 while name
in self
._names
:
27 name
= "{}${}".format(name
, self
._index
)
32 class _BufferedBuilder
:
35 self
._buffer
= io
.StringIO()
38 return self
._buffer
.getvalue()
40 def _append(self
, fmt
, *args
, **kwargs
):
41 self
._buffer
.write(fmt
.format(*args
, **kwargs
))
44 class _ProxiedBuilder
:
45 def _append(self
, *args
, **kwargs
):
46 self
.rtlil
._append
(*args
, **kwargs
)
50 _escape_map
= str.maketrans({
58 def _attribute(self
, name
, value
, *, indent
=0):
59 if isinstance(value
, str):
60 self
._append
("{}attribute \\{} \"{}\"\n",
61 " " * indent
, name
, value
.translate(self
._escape
_map
))
63 self
._append
("{}attribute \\{} {}\n",
64 " " * indent
, name
, int(value
))
66 def _attributes(self
, attrs
, *, src
=None, **kwargs
):
67 for name
, value
in attrs
.items():
68 self
._attribute
(name
, value
, **kwargs
)
70 self
._attribute
("src", src
, **kwargs
)
73 class _Builder(_Namer
, _BufferedBuilder
):
74 def module(self
, name
=None, attrs
={}):
75 name
= self
._make
_name
(name
, local
=False)
76 return _ModuleBuilder(self
, name
, attrs
)
79 class _ModuleBuilder(_Namer
, _BufferedBuilder
, _AttrBuilder
):
80 def __init__(self
, rtlil
, name
, attrs
):
84 self
.attrs
= {"generator": "nMigen"}
85 self
.attrs
.update(attrs
)
88 self
._attributes
(self
.attrs
)
89 self
._append
("module {}\n", self
.name
)
92 def __exit__(self
, *args
):
94 self
.rtlil
._buffer
.write(str(self
))
96 def wire(self
, width
, port_id
=None, port_kind
=None, name
=None, attrs
={}, src
=""):
97 self
._attributes
(attrs
, src
=src
, indent
=1)
98 name
= self
._make
_name
(name
, local
=False)
100 self
._append
(" wire width {} {}\n", width
, name
)
102 assert port_kind
in ("input", "output", "inout")
103 self
._append
(" wire width {} {} {} {}\n", width
, port_kind
, port_id
, name
)
106 def connect(self
, lhs
, rhs
):
107 self
._append
(" connect {} {}\n", lhs
, rhs
)
109 def memory(self
, width
, size
, name
=None, attrs
={}, src
=""):
110 self
._attributes
(attrs
, src
=src
, indent
=1)
111 name
= self
._make
_name
(name
, local
=False)
112 self
._append
(" memory width {} size {} {}\n", width
, size
, name
)
115 def cell(self
, kind
, name
=None, params
={}, ports
={}, attrs
={}, src
=""):
116 self
._attributes
(attrs
, src
=src
, indent
=1)
117 name
= self
._make
_name
(name
, local
=False)
118 self
._append
(" cell {} {}\n", kind
, name
)
119 for param
, value
in params
.items():
120 if isinstance(value
, str):
121 self
._append
(" parameter \\{} \"{}\"\n",
122 param
, value
.translate(self
._escape
_map
))
123 elif isinstance(value
, int):
124 self
._append
(" parameter \\{} {:d}\n",
126 elif isinstance(value
, ast
.Const
):
127 self
._append
(" parameter \\{} {}'{:b}\n",
128 param
, len(value
), value
.value
)
131 for port
, wire
in ports
.items():
132 self
._append
(" connect {} {}\n", port
, wire
)
133 self
._append
(" end\n")
136 def process(self
, name
=None, attrs
={}, src
=""):
137 name
= self
._make
_name
(name
, local
=True)
138 return _ProcessBuilder(self
, name
, attrs
, src
)
141 class _ProcessBuilder(_BufferedBuilder
, _AttrBuilder
):
142 def __init__(self
, rtlil
, name
, attrs
, src
):
150 self
._attributes
(self
.attrs
, src
=self
.src
, indent
=1)
151 self
._append
(" process {}\n", self
.name
)
154 def __exit__(self
, *args
):
155 self
._append
(" end\n")
156 self
.rtlil
._buffer
.write(str(self
))
159 return _CaseBuilder(self
, indent
=2)
161 def sync(self
, kind
, cond
=None):
162 return _SyncBuilder(self
, kind
, cond
)
165 class _CaseBuilder(_ProxiedBuilder
):
166 def __init__(self
, rtlil
, indent
):
173 def __exit__(self
, *args
):
176 def assign(self
, lhs
, rhs
):
177 self
._append
("{}assign {} {}\n", " " * self
.indent
, lhs
, rhs
)
179 def switch(self
, cond
, attrs
={}, src
=""):
180 return _SwitchBuilder(self
.rtlil
, cond
, attrs
, src
, self
.indent
)
183 class _SwitchBuilder(_ProxiedBuilder
, _AttrBuilder
):
184 def __init__(self
, rtlil
, cond
, attrs
, src
, indent
):
192 self
._attributes
(self
.attrs
, src
=self
.src
, indent
=self
.indent
)
193 self
._append
("{}switch {}\n", " " * self
.indent
, self
.cond
)
196 def __exit__(self
, *args
):
197 self
._append
("{}end\n", " " * self
.indent
)
199 def case(self
, *values
):
201 self
._append
("{}case\n", " " * (self
.indent
+ 1))
203 self
._append
("{}case {}\n", " " * (self
.indent
+ 1),
204 ", ".join("{}'{}".format(len(value
), value
) for value
in values
))
205 return _CaseBuilder(self
.rtlil
, self
.indent
+ 2)
208 class _SyncBuilder(_ProxiedBuilder
):
209 def __init__(self
, rtlil
, kind
, cond
):
215 if self
.cond
is None:
216 self
._append
(" sync {}\n", self
.kind
)
218 self
._append
(" sync {} {}\n", self
.kind
, self
.cond
)
221 def __exit__(self
, *args
):
224 def update(self
, lhs
, rhs
):
225 self
._append
(" update {} {}\n", lhs
, rhs
)
230 return "{}:{}".format(file, line
)
234 return "|".join(sorted(map(src
, src_locs
)))
237 class LegalizeValue(Exception):
238 def __init__(self
, value
, branches
, src_loc
):
240 self
.branches
= list(branches
)
241 self
.src_loc
= src_loc
244 class _ValueCompilerState
:
245 def __init__(self
, rtlil
):
247 self
.wires
= ast
.SignalDict()
248 self
.driven
= ast
.SignalDict()
249 self
.ports
= ast
.SignalDict()
250 self
.anys
= ast
.ValueDict()
252 self
.expansions
= ast
.ValueDict()
254 def add_driven(self
, signal
, sync
):
255 self
.driven
[signal
] = sync
257 def add_port(self
, signal
, kind
):
258 assert kind
in ("i", "o", "io")
265 self
.ports
[signal
] = (len(self
.ports
), kind
)
267 def resolve(self
, signal
, prefix
=None):
268 if signal
in self
.wires
:
269 return self
.wires
[signal
]
271 if signal
in self
.ports
:
272 port_id
, port_kind
= self
.ports
[signal
]
274 port_id
= port_kind
= None
275 if prefix
is not None:
276 wire_name
= "{}_{}".format(prefix
, signal
.name
)
278 wire_name
= signal
.name
280 wire_curr
= self
.rtlil
.wire(width
=signal
.nbits
, name
=wire_name
,
281 port_id
=port_id
, port_kind
=port_kind
,
283 src
=src(signal
.src_loc
))
284 if signal
in self
.driven
and self
.driven
[signal
]:
285 wire_next
= self
.rtlil
.wire(width
=signal
.nbits
, name
=wire_curr
+ "$next",
286 src
=src(signal
.src_loc
))
289 self
.wires
[signal
] = (wire_curr
, wire_next
)
291 return wire_curr
, wire_next
293 def resolve_curr(self
, signal
, prefix
=None):
294 wire_curr
, wire_next
= self
.resolve(signal
, prefix
)
297 def expand(self
, value
):
298 if not self
.expansions
:
300 return self
.expansions
.get(value
, value
)
303 def expand_to(self
, value
, expansion
):
305 assert value
not in self
.expansions
306 self
.expansions
[value
] = expansion
309 del self
.expansions
[value
]
312 class _ValueCompiler(xfrm
.ValueVisitor
):
313 def __init__(self
, state
):
316 def on_unknown(self
, value
):
320 super().on_unknown(value
)
322 def on_ClockSignal(self
, value
):
323 raise NotImplementedError # :nocov:
325 def on_ResetSignal(self
, value
):
326 raise NotImplementedError # :nocov:
328 def on_Sample(self
, value
):
329 raise NotImplementedError # :nocov:
331 def on_Record(self
, value
):
332 return self(ast
.Cat(value
.fields
.values()))
334 def on_Cat(self
, value
):
335 return "{{ {} }}".format(" ".join(reversed([self(o
) for o
in value
.parts
])))
337 def _prepare_value_for_Slice(self
, value
):
338 raise NotImplementedError # :nocov:
340 def on_Slice(self
, value
):
341 if value
.start
== 0 and value
.end
== len(value
.value
):
342 return self(value
.value
)
344 sigspec
= self
._prepare
_value
_for
_Slice
(value
.value
)
345 if value
.start
== value
.end
:
347 elif value
.start
+ 1 == value
.end
:
348 return "{} [{}]".format(sigspec
, value
.start
)
350 return "{} [{}:{}]".format(sigspec
, value
.end
- 1, value
.start
)
352 def on_ArrayProxy(self
, value
):
353 index
= self
.s
.expand(value
.index
)
354 if isinstance(index
, ast
.Const
):
355 if index
.value
< len(value
.elems
):
356 elem
= value
.elems
[index
.value
]
358 elem
= value
.elems
[-1]
359 return self
.match_shape(elem
, *value
.shape())
361 raise LegalizeValue(value
.index
, range(len(value
.elems
)), value
.src_loc
)
364 class _RHSValueCompiler(_ValueCompiler
):
368 (1, "b"): "$reduce_bool",
389 def on_value(self
, value
):
390 return super().on_value(self
.s
.expand(value
))
392 def on_Const(self
, value
):
393 if isinstance(value
.value
, str):
394 return "{}'{}".format(value
.nbits
, value
.value
)
396 value_twos_compl
= value
.value
& ((1 << value
.nbits
) - 1)
397 return "{}'{:0{}b}".format(value
.nbits
, value_twos_compl
, value
.nbits
)
399 def on_AnyConst(self
, value
):
400 if value
in self
.s
.anys
:
401 return self
.s
.anys
[value
]
403 res_bits
, res_sign
= value
.shape()
404 res
= self
.s
.rtlil
.wire(width
=res_bits
)
405 self
.s
.rtlil
.cell("$anyconst", ports
={
409 }, src
=src(value
.src_loc
))
410 self
.s
.anys
[value
] = res
413 def on_AnySeq(self
, value
):
414 if value
in self
.s
.anys
:
415 return self
.s
.anys
[value
]
417 res_bits
, res_sign
= value
.shape()
418 res
= self
.s
.rtlil
.wire(width
=res_bits
)
419 self
.s
.rtlil
.cell("$anyseq", ports
={
423 }, src
=src(value
.src_loc
))
424 self
.s
.anys
[value
] = res
427 def on_Signal(self
, value
):
428 wire_curr
, wire_next
= self
.s
.resolve(value
)
431 def on_Operator_unary(self
, value
):
432 arg
, = value
.operands
433 arg_bits
, arg_sign
= arg
.shape()
434 res_bits
, res_sign
= value
.shape()
435 res
= self
.s
.rtlil
.wire(width
=res_bits
)
436 self
.s
.rtlil
.cell(self
.operator_map
[(1, value
.op
)], ports
={
440 "A_SIGNED": arg_sign
,
443 }, src
=src(value
.src_loc
))
446 def match_shape(self
, value
, new_bits
, new_sign
):
447 if isinstance(value
, ast
.Const
):
448 return self(ast
.Const(value
.value
, (new_bits
, new_sign
)))
450 value_bits
, value_sign
= value
.shape()
451 if new_bits
<= value_bits
:
452 return self(ast
.Slice(value
, 0, new_bits
))
454 res
= self
.s
.rtlil
.wire(width
=new_bits
)
455 self
.s
.rtlil
.cell("$pos", ports
={
459 "A_SIGNED": value_sign
,
460 "A_WIDTH": value_bits
,
462 }, src
=src(value
.src_loc
))
465 def on_Operator_binary(self
, value
):
466 lhs
, rhs
= value
.operands
467 lhs_bits
, lhs_sign
= lhs
.shape()
468 rhs_bits
, rhs_sign
= rhs
.shape()
469 if lhs_sign
== rhs_sign
:
473 lhs_sign
= rhs_sign
= True
474 lhs_bits
= rhs_bits
= max(lhs_bits
, rhs_bits
)
475 lhs_wire
= self
.match_shape(lhs
, lhs_bits
, lhs_sign
)
476 rhs_wire
= self
.match_shape(rhs
, rhs_bits
, rhs_sign
)
477 res_bits
, res_sign
= value
.shape()
478 res
= self
.s
.rtlil
.wire(width
=res_bits
)
479 self
.s
.rtlil
.cell(self
.operator_map
[(2, value
.op
)], ports
={
484 "A_SIGNED": lhs_sign
,
486 "B_SIGNED": rhs_sign
,
489 }, src
=src(value
.src_loc
))
492 def on_Operator_mux(self
, value
):
493 sel
, val1
, val0
= value
.operands
494 val1_bits
, val1_sign
= val1
.shape()
495 val0_bits
, val0_sign
= val0
.shape()
496 res_bits
, res_sign
= value
.shape()
497 val1_bits
= val0_bits
= res_bits
= max(val1_bits
, val0_bits
, res_bits
)
498 val1_wire
= self
.match_shape(val1
, val1_bits
, val1_sign
)
499 val0_wire
= self
.match_shape(val0
, val0_bits
, val0_sign
)
500 res
= self
.s
.rtlil
.wire(width
=res_bits
)
501 self
.s
.rtlil
.cell("$mux", ports
={
508 }, src
=src(value
.src_loc
))
511 def on_Operator(self
, value
):
512 if len(value
.operands
) == 1:
513 return self
.on_Operator_unary(value
)
514 elif len(value
.operands
) == 2:
515 return self
.on_Operator_binary(value
)
516 elif len(value
.operands
) == 3:
517 assert value
.op
== "m"
518 return self
.on_Operator_mux(value
)
520 raise TypeError # :nocov:
522 def _prepare_value_for_Slice(self
, value
):
523 if isinstance(value
, (ast
.Signal
, ast
.Slice
, ast
.Cat
)):
524 sigspec
= self(value
)
526 sigspec
= self
.s
.rtlil
.wire(len(value
))
527 self
.s
.rtlil
.connect(sigspec
, self(value
))
530 def on_Part(self
, value
):
531 lhs
, rhs
= value
.value
, value
.offset
532 lhs_bits
, lhs_sign
= lhs
.shape()
533 rhs_bits
, rhs_sign
= rhs
.shape()
534 res_bits
, res_sign
= value
.shape()
535 res
= self
.s
.rtlil
.wire(width
=res_bits
)
536 # Note: Verilog's x[o+:w] construct produces a $shiftx cell, not a $shift cell.
537 # However, Migen's semantics defines the out-of-range bits to be zero, so it is correct
538 # to use a $shift cell here instead, even though it produces less idiomatic Verilog.
539 self
.s
.rtlil
.cell("$shift", ports
={
544 "A_SIGNED": lhs_sign
,
546 "B_SIGNED": rhs_sign
,
549 }, src
=src(value
.src_loc
))
552 def on_Repl(self
, value
):
553 return "{{ {} }}".format(" ".join(self(value
.value
) for _
in range(value
.count
)))
556 class _LHSValueCompiler(_ValueCompiler
):
557 def on_Const(self
, value
):
558 raise TypeError # :nocov:
560 def on_AnyConst(self
, value
):
561 raise TypeError # :nocov:
563 def on_AnySeq(self
, value
):
564 raise TypeError # :nocov:
566 def on_Operator(self
, value
):
567 raise TypeError # :nocov:
569 def match_shape(self
, value
, new_bits
, new_sign
):
570 assert value
.shape() == (new_bits
, new_sign
)
573 def on_Signal(self
, value
):
574 if value
not in self
.s
.driven
:
575 raise ValueError("No LHS wire for non-driven signal {}".format(repr(value
)))
576 wire_curr
, wire_next
= self
.s
.resolve(value
)
577 return wire_next
or wire_curr
579 def _prepare_value_for_Slice(self
, value
):
580 assert isinstance(value
, (ast
.Signal
, ast
.Slice
, ast
.Cat
, rec
.Record
))
583 def on_Part(self
, value
):
584 offset
= self
.s
.expand(value
.offset
)
585 if isinstance(offset
, ast
.Const
):
586 return self(ast
.Slice(value
.value
, offset
.value
, offset
.value
+ value
.width
))
588 raise LegalizeValue(value
.offset
, range((1 << len(value
.offset
))), value
.src_loc
)
590 def on_Repl(self
, value
):
591 raise TypeError # :nocov:
594 class _StatementCompiler(xfrm
.StatementVisitor
):
595 def __init__(self
, state
, rhs_compiler
, lhs_compiler
):
597 self
.rhs_compiler
= rhs_compiler
598 self
.lhs_compiler
= lhs_compiler
601 self
._test
_cache
= {}
602 self
._has
_rhs
= False
605 def case(self
, switch
, values
):
607 old_case
= self
._case
608 with switch
.case(*values
) as self
._case
:
611 self
._case
= old_case
613 def _check_rhs(self
, value
):
614 if self
._has
_rhs
or next(iter(value
._rhs
_signals
()), None) is not None:
617 def on_Assign(self
, stmt
):
618 self
._check
_rhs
(stmt
.rhs
)
620 lhs_bits
, lhs_sign
= stmt
.lhs
.shape()
621 rhs_bits
, rhs_sign
= stmt
.rhs
.shape()
622 if lhs_bits
== rhs_bits
:
623 rhs_sigspec
= self
.rhs_compiler(stmt
.rhs
)
625 # In RTLIL, LHS and RHS of assignment must have exactly same width.
626 rhs_sigspec
= self
.rhs_compiler
.match_shape(
627 stmt
.rhs
, lhs_bits
, lhs_sign
)
628 self
._case
.assign(self
.lhs_compiler(stmt
.lhs
), rhs_sigspec
)
630 def on_Assert(self
, stmt
):
631 self(stmt
._check
.eq(stmt
.test
))
634 en_wire
= self
.rhs_compiler(stmt
._en
)
635 check_wire
= self
.rhs_compiler(stmt
._check
)
636 self
.state
.rtlil
.cell("$assert", ports
={
639 }, src
=src(stmt
.src_loc
))
641 def on_Assume(self
, stmt
):
642 self(stmt
._check
.eq(stmt
.test
))
645 en_wire
= self
.rhs_compiler(stmt
._en
)
646 check_wire
= self
.rhs_compiler(stmt
._check
)
647 self
.state
.rtlil
.cell("$assume", ports
={
650 }, src
=src(stmt
.src_loc
))
652 def on_Switch(self
, stmt
):
653 self
._check
_rhs
(stmt
.test
)
655 if stmt
not in self
._test
_cache
:
656 self
._test
_cache
[stmt
] = self
.rhs_compiler(stmt
.test
)
657 test_sigspec
= self
._test
_cache
[stmt
]
659 with self
._case
.switch(test_sigspec
, src
=src(stmt
.src_loc
)) as switch
:
660 for values
, stmts
in stmt
.cases
.items():
661 with self
.case(switch
, values
):
662 self
.on_statements(stmts
)
664 def on_statement(self
, stmt
):
666 super().on_statement(stmt
)
667 except LegalizeValue
as legalize
:
668 with self
._case
.switch(self
.rhs_compiler(legalize
.value
),
669 src
=src(legalize
.src_loc
)) as switch
:
670 bits
, sign
= legalize
.value
.shape()
671 tests
= ["{:0{}b}".format(v
, bits
) for v
in legalize
.branches
]
672 tests
[-1] = "-" * bits
673 for branch
, test
in zip(legalize
.branches
, tests
):
674 with self
.case(switch
, (test
,)):
675 branch_value
= ast
.Const(branch
, (bits
, sign
))
676 with self
.state
.expand_to(legalize
.value
, branch_value
):
677 super().on_statement(stmt
)
679 def on_statements(self
, stmts
):
681 self
.on_statement(stmt
)
684 def convert_fragment(builder
, fragment
, hierarchy
):
685 if isinstance(fragment
, ir
.Instance
):
686 port_map
= OrderedDict()
687 for port_name
, (value
, dir) in fragment
.named_ports
.items():
688 port_map
["\\{}".format(port_name
)] = value
690 if fragment
.type[0] == "$":
691 return fragment
.type, port_map
693 return "\\{}".format(fragment
.type), port_map
695 module_name
= hierarchy
[-1] or "anonymous"
696 module_attrs
= OrderedDict()
697 if len(hierarchy
) == 1:
698 module_attrs
["top"] = 1
699 module_attrs
["nmigen.hierarchy"] = ".".join(name
or "anonymous" for name
in hierarchy
)
701 with builder
.module(module_name
, attrs
=module_attrs
) as module
:
702 compiler_state
= _ValueCompilerState(module
)
703 rhs_compiler
= _RHSValueCompiler(compiler_state
)
704 lhs_compiler
= _LHSValueCompiler(compiler_state
)
705 stmt_compiler
= _StatementCompiler(compiler_state
, rhs_compiler
, lhs_compiler
)
707 verilog_trigger
= None
708 verilog_trigger_sync_emitted
= False
710 # Register all signals driven in the current fragment. This must be done first, as it
711 # affects further codegen; e.g. whether \sig$next signals will be generated and used.
712 for domain
, signal
in fragment
.iter_drivers():
713 compiler_state
.add_driven(signal
, sync
=domain
is not None)
715 # Transform all signals used as ports in the current fragment eagerly and outside of
716 # any hierarchy, to make sure they get sensible (non-prefixed) names.
717 for signal
in fragment
.ports
:
718 compiler_state
.add_port(signal
, fragment
.ports
[signal
])
719 compiler_state
.resolve_curr(signal
)
721 # Transform all clocks clocks and resets eagerly and outside of any hierarchy, to make
722 # sure they get sensible (non-prefixed) names. This does not affect semantics.
723 for domain
, _
in fragment
.iter_sync():
724 cd
= fragment
.domains
[domain
]
725 compiler_state
.resolve_curr(cd
.clk
)
726 if cd
.rst
is not None:
727 compiler_state
.resolve_curr(cd
.rst
)
729 # Transform all subfragments to their respective cells. Transforming signals connected
730 # to their ports into wires eagerly makes sure they get sensible (prefixed with submodule
732 memories
= OrderedDict()
733 for subfragment
, sub_name
in fragment
.subfragments
:
734 if not subfragment
.ports
:
737 sub_params
= OrderedDict()
738 if hasattr(subfragment
, "parameters"):
739 for param_name
, param_value
in subfragment
.parameters
.items():
740 if isinstance(param_value
, mem
.Memory
):
742 if memory
not in memories
:
743 memories
[memory
] = module
.memory(width
=memory
.width
, size
=memory
.depth
,
745 addr_bits
= bits_for(memory
.depth
)
747 data_mask
= (1 << memory
.width
) - 1
748 for addr
in range(memory
.depth
):
749 if addr
< len(memory
.init
):
750 data
= memory
.init
[addr
] & data_mask
753 data_parts
.append("{:0{}b}".format(data
, memory
.width
))
754 module
.cell("$meminit", ports
={
755 "\\ADDR": rhs_compiler(ast
.Const(0, addr_bits
)),
756 "\\DATA": "{}'".format(memory
.width
* memory
.depth
) +
757 "".join(reversed(data_parts
)),
759 "MEMID": memories
[memory
],
761 "WIDTH": memory
.width
,
762 "WORDS": memory
.depth
,
766 param_value
= memories
[memory
]
768 sub_params
[param_name
] = param_value
770 sub_type
, sub_port_map
= \
771 convert_fragment(builder
, subfragment
, hierarchy
=hierarchy
+ (sub_name
,))
773 sub_ports
= OrderedDict()
774 for port
, value
in sub_port_map
.items():
775 for signal
in value
._rhs
_signals
():
776 compiler_state
.resolve_curr(signal
, prefix
=sub_name
)
777 sub_ports
[port
] = rhs_compiler(value
)
779 module
.cell(sub_type
, name
=sub_name
, ports
=sub_ports
, params
=sub_params
,
780 attrs
=subfragment
.attrs
)
782 # If we emit all of our combinatorial logic into a single RTLIL process, Verilog
783 # simulators will break horribly, because Yosys write_verilog transforms RTLIL processes
784 # into always @* blocks with blocking assignment, and that does not create delta cycles.
786 # Therefore, we translate the fragment as many times as there are independent groups
787 # of signals (a group is a transitive closure of signals that appear together on LHS),
788 # splitting them into many RTLIL (and thus Verilog) processes.
789 lhs_grouper
= xfrm
.LHSGroupAnalyzer()
790 lhs_grouper
.on_statements(fragment
.statements
)
792 for group
, group_signals
in lhs_grouper
.groups().items():
793 lhs_group_filter
= xfrm
.LHSGroupFilter(group_signals
)
794 group_stmts
= lhs_group_filter(fragment
.statements
)
796 with module
.process(name
="$group_{}".format(group
)) as process
:
797 with process
.case() as case
:
798 # For every signal in comb domain, assign \sig$next to the reset value.
799 # For every signal in sync domains, assign \sig$next to the current
801 for domain
, signal
in fragment
.iter_drivers():
802 if signal
not in group_signals
:
805 prev_value
= ast
.Const(signal
.reset
, signal
.nbits
)
808 case
.assign(lhs_compiler(signal
), rhs_compiler(prev_value
))
810 # Convert statements into decision trees.
811 stmt_compiler
._case
= case
812 stmt_compiler
._has
_rhs
= False
813 stmt_compiler(group_stmts
)
815 # Verilog `always @*` blocks will not run if `*` does not match anything, i.e.
816 # if the implicit sensitivity list is empty. We check this while translating,
817 # by looking for any signals on RHS. If there aren't any, we add some logic
818 # whose only purpose is to trigger Verilog simulators when it converts
819 # through RTLIL and to Verilog, by populating the sensitivity list.
820 if not stmt_compiler
._has
_rhs
:
821 if verilog_trigger
is None:
823 module
.wire(1, name
="$verilog_initial_trigger")
824 case
.assign(verilog_trigger
, verilog_trigger
)
826 # For every signal in the sync domain, assign \sig's initial value (which will
827 # end up as the \init reg attribute) to the reset value.
828 with process
.sync("init") as sync
:
829 for domain
, signal
in fragment
.iter_sync():
830 if signal
not in group_signals
:
832 wire_curr
, wire_next
= compiler_state
.resolve(signal
)
833 sync
.update(wire_curr
, rhs_compiler(ast
.Const(signal
.reset
, signal
.nbits
)))
835 # The Verilog simulator trigger needs to change at time 0, so if we haven't
836 # yet done that in some process, do it.
837 if verilog_trigger
and not verilog_trigger_sync_emitted
:
838 sync
.update(verilog_trigger
, "1'0")
839 verilog_trigger_sync_emitted
= True
841 # For every signal in every sync domain, assign \sig to \sig$next. The sensitivity
842 # list, however, differs between domains: for domains with sync reset, it is
843 # `posedge clk`, for sync domains with async reset it is `posedge clk or
845 for domain
, signals
in fragment
.drivers
.items():
849 signals
= signals
& group_signals
853 cd
= fragment
.domains
[domain
]
856 triggers
.append(("posedge", compiler_state
.resolve_curr(cd
.clk
)))
858 triggers
.append(("posedge", compiler_state
.resolve_curr(cd
.rst
)))
860 for trigger
in triggers
:
861 with process
.sync(*trigger
) as sync
:
862 for signal
in signals
:
863 wire_curr
, wire_next
= compiler_state
.resolve(signal
)
864 sync
.update(wire_curr
, wire_next
)
866 # Any signals that are used but neither driven nor connected to an input port always
867 # assume their reset values. We need to assign the reset value explicitly, since only
868 # driven sync signals are handled by the logic above.
870 # Because this assignment is done at a late stage, a single Signal object can get assigned
871 # many times, once in each module it is used. This is a deliberate decision; the possible
872 # alternatives are to add ports for undriven signals (which requires choosing one module
873 # to drive it to reset value arbitrarily) or to replace them with their reset value (which
874 # removes valuable source location information).
875 driven
= ast
.SignalSet()
876 for domain
, signals
in fragment
.iter_drivers():
877 driven
.update(flatten(signal
._lhs
_signals
() for signal
in signals
))
878 driven
.update(fragment
.iter_ports(dir="i"))
879 driven
.update(fragment
.iter_ports(dir="io"))
880 for subfragment
, sub_name
in fragment
.subfragments
:
881 driven
.update(subfragment
.iter_ports(dir="o"))
882 driven
.update(subfragment
.iter_ports(dir="io"))
884 for wire
in compiler_state
.wires
:
887 wire_curr
, _
= compiler_state
.wires
[wire
]
888 module
.connect(wire_curr
, rhs_compiler(ast
.Const(wire
.reset
, wire
.nbits
)))
890 # Finally, collect the names we've given to our ports in RTLIL, and correlate these with
891 # the signals represented by these ports. If we are a submodule, this will be necessary
892 # to create a cell for us in the parent module.
893 port_map
= OrderedDict()
894 for signal
in fragment
.ports
:
895 port_map
[compiler_state
.resolve_curr(signal
)] = signal
897 return module
.name
, port_map
900 def convert(fragment
, name
="top", platform
=None, **kwargs
):
901 fragment
= ir
.Fragment
.get(fragment
, platform
).prepare(**kwargs
)
903 convert_fragment(builder
, fragment
, hierarchy
=(name
,))