back.rtlil: fix typo.
[nmigen.git] / nmigen / back / rtlil.py
1 import io
2 import textwrap
3 from collections import defaultdict, OrderedDict
4 from contextlib import contextmanager
5
6 from ..tools import bits_for
7 from ..hdl import ast, ir, mem, xfrm
8
9
10 class _Namer:
11 def __init__(self):
12 super().__init__()
13 self._index = 0
14 self._names = set()
15
16 def _make_name(self, name, local):
17 if name is None:
18 self._index += 1
19 name = "${}".format(self._index)
20 elif not local and name[0] not in "\\$":
21 name = "\\{}".format(name)
22 while name in self._names:
23 self._index += 1
24 name = "{}${}".format(name, self._index)
25 self._names.add(name)
26 return name
27
28
29 class _Bufferer:
30 _escape_map = str.maketrans({
31 "\"": "\\\"",
32 "\\": "\\\\",
33 "\t": "\\t",
34 "\r": "\\r",
35 "\n": "\\n",
36 })
37 def __init__(self):
38 super().__init__()
39 self._buffer = io.StringIO()
40
41 def __str__(self):
42 return self._buffer.getvalue()
43
44 def _append(self, fmt, *args, **kwargs):
45 self._buffer.write(fmt.format(*args, **kwargs))
46
47 def attribute(self, name, value, indent=0):
48 if isinstance(value, str):
49 self._append("{}attribute \\{} \"{}\"\n",
50 " " * indent, name, value.translate(self._escape_map))
51 else:
52 self._append("{}attribute \\{} {}\n",
53 " " * indent, name, int(value))
54
55 def _src(self, src):
56 if src:
57 self.attribute("src", src)
58
59
60 class _Builder(_Namer, _Bufferer):
61 def module(self, name=None, attrs={}):
62 name = self._make_name(name, local=False)
63 return _ModuleBuilder(self, name, attrs)
64
65
66 class _ModuleBuilder(_Namer, _Bufferer):
67 def __init__(self, rtlil, name, attrs):
68 super().__init__()
69 self.rtlil = rtlil
70 self.name = name
71 self.attrs = {"generator": "nMigen"}
72 self.attrs.update(attrs)
73
74 def __enter__(self):
75 for name, value in self.attrs.items():
76 self.attribute(name, value, indent=0)
77 self._append("module {}\n", self.name)
78 return self
79
80 def __exit__(self, *args):
81 self._append("end\n")
82 self.rtlil._buffer.write(str(self))
83
84 def attribute(self, name, value, indent=1):
85 super().attribute(name, value, indent)
86
87 def wire(self, width, port_id=None, port_kind=None, name=None, src=""):
88 self._src(src)
89 name = self._make_name(name, local=False)
90 if port_id is None:
91 self._append(" wire width {} {}\n", width, name)
92 else:
93 assert port_kind in ("input", "output", "inout")
94 self._append(" wire width {} {} {} {}\n", width, port_kind, port_id, name)
95 return name
96
97 def connect(self, lhs, rhs):
98 self._append(" connect {} {}\n", lhs, rhs)
99
100 def memory(self, width, size, name=None, src=""):
101 self._src(src)
102 name = self._make_name(name, local=False)
103 self._append(" memory width {} size {} {}\n", width, size, name)
104 return name
105
106 def cell(self, kind, name=None, params={}, ports={}, src=""):
107 self._src(src)
108 name = self._make_name(name, local=False)
109 self._append(" cell {} {}\n", kind, name)
110 for param, value in params.items():
111 if isinstance(value, str):
112 self._append(" parameter \\{} \"{}\"\n",
113 param, value.translate(self._escape_map))
114 else:
115 self._append(" parameter \\{} {:d}\n",
116 param, value)
117 for port, wire in ports.items():
118 self._append(" connect {} {}\n", port, wire)
119 self._append(" end\n")
120 return name
121
122 def process(self, name=None, src=""):
123 name = self._make_name(name, local=True)
124 return _ProcessBuilder(self, name, src)
125
126
127 class _ProcessBuilder(_Bufferer):
128 def __init__(self, rtlil, name, src):
129 super().__init__()
130 self.rtlil = rtlil
131 self.name = name
132 self.src = src
133
134 def __enter__(self):
135 self._src(self.src)
136 self._append(" process {}\n", self.name)
137 return self
138
139 def __exit__(self, *args):
140 self._append(" end\n")
141 self.rtlil._buffer.write(str(self))
142
143 def case(self):
144 return _CaseBuilder(self, indent=2)
145
146 def sync(self, kind, cond=None):
147 return _SyncBuilder(self, kind, cond)
148
149
150 class _CaseBuilder:
151 def __init__(self, rtlil, indent):
152 self.rtlil = rtlil
153 self.indent = indent
154
155 def __enter__(self):
156 return self
157
158 def __exit__(self, *args):
159 pass
160
161 def assign(self, lhs, rhs):
162 self.rtlil._append("{}assign {} {}\n", " " * self.indent, lhs, rhs)
163
164 def switch(self, cond):
165 return _SwitchBuilder(self.rtlil, cond, self.indent)
166
167
168 class _SwitchBuilder:
169 def __init__(self, rtlil, cond, indent):
170 self.rtlil = rtlil
171 self.cond = cond
172 self.indent = indent
173
174 def __enter__(self):
175 self.rtlil._append("{}switch {}\n", " " * self.indent, self.cond)
176 return self
177
178 def __exit__(self, *args):
179 self.rtlil._append("{}end\n", " " * self.indent)
180
181 def case(self, value=None):
182 if value is None:
183 self.rtlil._append("{}case\n", " " * (self.indent + 1))
184 else:
185 self.rtlil._append("{}case {}'{}\n", " " * (self.indent + 1),
186 len(value), value)
187 return _CaseBuilder(self.rtlil, self.indent + 2)
188
189
190 class _SyncBuilder:
191 def __init__(self, rtlil, kind, cond):
192 self.rtlil = rtlil
193 self.kind = kind
194 self.cond = cond
195
196 def __enter__(self):
197 if self.cond is None:
198 self.rtlil._append(" sync {}\n", self.kind)
199 else:
200 self.rtlil._append(" sync {} {}\n", self.kind, self.cond)
201 return self
202
203 def __exit__(self, *args):
204 pass
205
206 def update(self, lhs, rhs):
207 self.rtlil._append(" update {} {}\n", lhs, rhs)
208
209
210 def src(src_loc):
211 file, line = src_loc
212 return "{}:{}".format(file, line)
213
214
215 class LegalizeValue(Exception):
216 def __init__(self, value, branches):
217 self.value = value
218 self.branches = list(branches)
219
220
221 class _ValueCompilerState:
222 def __init__(self, rtlil):
223 self.rtlil = rtlil
224 self.wires = ast.SignalDict()
225 self.driven = ast.SignalDict()
226 self.ports = ast.SignalDict()
227
228 self.expansions = ast.ValueDict()
229
230 def add_driven(self, signal, sync):
231 self.driven[signal] = sync
232
233 def add_port(self, signal, kind):
234 assert kind in ("i", "o", "io")
235 if kind == "i":
236 kind = "input"
237 elif kind == "o":
238 kind = "output"
239 elif kind == "io":
240 kind = "inout"
241 self.ports[signal] = (len(self.ports), kind)
242
243 def resolve(self, signal, prefix=None):
244 if signal in self.wires:
245 return self.wires[signal]
246
247 if signal in self.ports:
248 port_id, port_kind = self.ports[signal]
249 else:
250 port_id = port_kind = None
251 if prefix is not None:
252 wire_name = "{}_{}".format(prefix, signal.name)
253 else:
254 wire_name = signal.name
255
256 for attr_name, attr_signal in signal.attrs.items():
257 self.rtlil.attribute(attr_name, attr_signal)
258 wire_curr = self.rtlil.wire(width=signal.nbits, name=wire_name,
259 port_id=port_id, port_kind=port_kind,
260 src=src(signal.src_loc))
261 if signal in self.driven:
262 wire_next = self.rtlil.wire(width=signal.nbits, name=wire_curr + "$next",
263 src=src(signal.src_loc))
264 else:
265 wire_next = None
266 self.wires[signal] = (wire_curr, wire_next)
267
268 return wire_curr, wire_next
269
270 def resolve_curr(self, signal, prefix=None):
271 wire_curr, wire_next = self.resolve(signal, prefix)
272 return wire_curr
273
274 def expand(self, value):
275 if not self.expansions:
276 return value
277 return self.expansions.get(value, value)
278
279 @contextmanager
280 def expand_to(self, value, expansion):
281 try:
282 assert value not in self.expansions
283 self.expansions[value] = expansion
284 yield
285 finally:
286 del self.expansions[value]
287
288
289 class _ValueCompiler(xfrm.ValueVisitor):
290 def __init__(self, state):
291 self.s = state
292
293 def on_value(self, value):
294 return super().on_value(self.s.expand(value))
295
296 def on_unknown(self, value):
297 if value is None:
298 return None
299 else:
300 super().on_unknown(value)
301
302 def on_ClockSignal(self, value):
303 raise NotImplementedError # :nocov:
304
305 def on_ResetSignal(self, value):
306 raise NotImplementedError # :nocov:
307
308 def on_Record(self, value):
309 return self(ast.Cat(value.fields.values()))
310
311 def on_Cat(self, value):
312 return "{{ {} }}".format(" ".join(reversed([self(o) for o in value.parts])))
313
314 def _prepare_value_for_Slice(self, value):
315 raise NotImplementedError # :nocov:
316
317 def on_Slice(self, value):
318 if value.start == 0 and value.end == len(value.value):
319 return self(value.value)
320
321 sigspec = self._prepare_value_for_Slice(value.value)
322 if value.start + 1 == value.end:
323 return "{} [{}]".format(sigspec, value.start)
324 else:
325 return "{} [{}:{}]".format(sigspec, value.end - 1, value.start)
326
327 def on_ArrayProxy(self, value):
328 index = self.s.expand(value.index)
329 if isinstance(index, ast.Const):
330 if index.value < len(value.elems):
331 elem = value.elems[index.value]
332 else:
333 elem = value.elems[-1]
334 return self.match_shape(elem, *value.shape())
335 else:
336 raise LegalizeValue(value.index, range(len(value.elems)))
337
338
339 class _RHSValueCompiler(_ValueCompiler):
340 operator_map = {
341 (1, "~"): "$not",
342 (1, "-"): "$neg",
343 (1, "b"): "$reduce_bool",
344 (2, "+"): "$add",
345 (2, "-"): "$sub",
346 (2, "*"): "$mul",
347 (2, "/"): "$div",
348 (2, "%"): "$mod",
349 (2, "**"): "$pow",
350 (2, "<<"): "$sshl",
351 (2, ">>"): "$sshr",
352 (2, "&"): "$and",
353 (2, "^"): "$xor",
354 (2, "|"): "$or",
355 (2, "=="): "$eq",
356 (2, "!="): "$ne",
357 (2, "<"): "$lt",
358 (2, "<="): "$le",
359 (2, ">"): "$gt",
360 (2, ">="): "$ge",
361 (3, "m"): "$mux",
362 }
363
364 def on_Const(self, value):
365 if isinstance(value.value, str):
366 return "{}'{}".format(value.nbits, value.value)
367 else:
368 value_twos_compl = value.value & ((1 << value.nbits) - 1)
369 return "{}'{:0{}b}".format(value.nbits, value_twos_compl, value.nbits)
370
371 def on_Signal(self, value):
372 wire_curr, wire_next = self.s.resolve(value)
373 return wire_curr
374
375 def on_Operator_unary(self, value):
376 arg, = value.operands
377 arg_bits, arg_sign = arg.shape()
378 res_bits, res_sign = value.shape()
379 res = self.s.rtlil.wire(width=res_bits)
380 self.s.rtlil.cell(self.operator_map[(1, value.op)], ports={
381 "\\A": self(arg),
382 "\\Y": res,
383 }, params={
384 "A_SIGNED": arg_sign,
385 "A_WIDTH": arg_bits,
386 "Y_WIDTH": res_bits,
387 }, src=src(value.src_loc))
388 return res
389
390 def match_shape(self, value, new_bits, new_sign):
391 if isinstance(value, ast.Const):
392 return self(ast.Const(value.value, (new_bits, new_sign)))
393
394 value_bits, value_sign = value.shape()
395 if new_bits <= value_bits:
396 return self(ast.Slice(value, 0, new_bits))
397
398 res = self.s.rtlil.wire(width=new_bits)
399 self.s.rtlil.cell("$pos", ports={
400 "\\A": self(value),
401 "\\Y": res,
402 }, params={
403 "A_SIGNED": value_sign,
404 "A_WIDTH": value_bits,
405 "Y_WIDTH": new_bits,
406 }, src=src(value.src_loc))
407 return res
408
409 def on_Operator_binary(self, value):
410 lhs, rhs = value.operands
411 lhs_bits, lhs_sign = lhs.shape()
412 rhs_bits, rhs_sign = rhs.shape()
413 if lhs_sign == rhs_sign:
414 lhs_wire = self(lhs)
415 rhs_wire = self(rhs)
416 else:
417 lhs_sign = rhs_sign = True
418 lhs_bits = rhs_bits = max(lhs_bits, rhs_bits)
419 lhs_wire = self.match_shape(lhs, lhs_bits, lhs_sign)
420 rhs_wire = self.match_shape(rhs, rhs_bits, rhs_sign)
421 res_bits, res_sign = value.shape()
422 res = self.s.rtlil.wire(width=res_bits)
423 self.s.rtlil.cell(self.operator_map[(2, value.op)], ports={
424 "\\A": lhs_wire,
425 "\\B": rhs_wire,
426 "\\Y": res,
427 }, params={
428 "A_SIGNED": lhs_sign,
429 "A_WIDTH": lhs_bits,
430 "B_SIGNED": rhs_sign,
431 "B_WIDTH": rhs_bits,
432 "Y_WIDTH": res_bits,
433 }, src=src(value.src_loc))
434 return res
435
436 def on_Operator_mux(self, value):
437 sel, val1, val0 = value.operands
438 val1_bits, val1_sign = val1.shape()
439 val0_bits, val0_sign = val0.shape()
440 res_bits, res_sign = value.shape()
441 val1_bits = val0_bits = res_bits = max(val1_bits, val0_bits, res_bits)
442 val1_wire = self.match_shape(val1, val1_bits, val1_sign)
443 val0_wire = self.match_shape(val0, val0_bits, val0_sign)
444 res = self.s.rtlil.wire(width=res_bits)
445 self.s.rtlil.cell("$mux", ports={
446 "\\A": val0_wire,
447 "\\B": val1_wire,
448 "\\S": self(sel),
449 "\\Y": res,
450 }, params={
451 "WIDTH": res_bits
452 }, src=src(value.src_loc))
453 return res
454
455 def on_Operator(self, value):
456 if len(value.operands) == 1:
457 return self.on_Operator_unary(value)
458 elif len(value.operands) == 2:
459 return self.on_Operator_binary(value)
460 elif len(value.operands) == 3:
461 assert value.op == "m"
462 return self.on_Operator_mux(value)
463 else:
464 raise TypeError # :nocov:
465
466 def _prepare_value_for_Slice(self, value):
467 if isinstance(value, (ast.Signal, ast.Slice, ast.Cat)):
468 sigspec = self(value)
469 else:
470 sigspec = self.s.rtlil.wire(len(value))
471 self.s.rtlil.connect(sigspec, self(value))
472 return sigspec
473
474 def on_Part(self, value):
475 lhs, rhs = value.value, value.offset
476 lhs_bits, lhs_sign = lhs.shape()
477 rhs_bits, rhs_sign = rhs.shape()
478 res_bits, res_sign = value.shape()
479 res = self.s.rtlil.wire(width=res_bits)
480 # Note: Verilog's x[o+:w] construct produces a $shiftx cell, not a $shift cell.
481 # However, Migen's semantics defines the out-of-range bits to be zero, so it is correct
482 # to use a $shift cell here instead, even though it produces less idiomatic Verilog.
483 self.s.rtlil.cell("$shift", ports={
484 "\\A": self(lhs),
485 "\\B": self(rhs),
486 "\\Y": res,
487 }, params={
488 "A_SIGNED": lhs_sign,
489 "A_WIDTH": lhs_bits,
490 "B_SIGNED": rhs_sign,
491 "B_WIDTH": rhs_bits,
492 "Y_WIDTH": res_bits,
493 }, src=src(value.src_loc))
494 return res
495
496 def on_Repl(self, value):
497 return "{{ {} }}".format(" ".join(self(value.value) for _ in range(value.count)))
498
499
500 class _LHSValueCompiler(_ValueCompiler):
501 def on_Const(self, value):
502 raise TypeError # :nocov:
503
504 def on_Operator(self, value):
505 raise TypeError # :nocov:
506
507 def match_shape(self, value, new_bits, new_sign):
508 assert value.shape() == (new_bits, new_sign)
509 return self(value)
510
511 def on_Signal(self, value):
512 wire_curr, wire_next = self.s.resolve(value)
513 if wire_next is None:
514 raise ValueError("No LHS wire for non-driven signal {}".format(repr(value)))
515 return wire_next
516
517 def _prepare_value_for_Slice(self, value):
518 assert isinstance(value, (ast.Signal, ast.Slice, ast.Cat))
519 return self(value)
520
521 def on_Part(self, value):
522 offset = self.s.expand(value.offset)
523 if isinstance(offset, ast.Const):
524 return self(ast.Slice(value.value, offset.value, offset.value + value.width))
525 else:
526 raise LegalizeValue(value.offset, range((1 << len(value.offset)) - 1))
527
528 def on_Repl(self, value):
529 raise TypeError # :nocov:
530
531
532 class _StatementCompiler(xfrm.StatementVisitor):
533 def __init__(self, state, rhs_compiler, lhs_compiler):
534 self.state = state
535 self.rhs_compiler = rhs_compiler
536 self.lhs_compiler = lhs_compiler
537
538 self._case = None
539 self._test_cache = {}
540 self._has_rhs = False
541
542 @contextmanager
543 def case(self, switch, value):
544 try:
545 old_case = self._case
546 with switch.case(value) as self._case:
547 yield
548 finally:
549 self._case = old_case
550
551 def _check_rhs(self, value):
552 if self._has_rhs or next(iter(value._rhs_signals()), None) is not None:
553 self._has_rhs = True
554
555 def on_Assign(self, stmt):
556 self._check_rhs(stmt.rhs)
557
558 lhs_bits, lhs_sign = stmt.lhs.shape()
559 rhs_bits, rhs_sign = stmt.rhs.shape()
560 if lhs_bits == rhs_bits:
561 rhs_sigspec = self.rhs_compiler(stmt.rhs)
562 else:
563 # In RTLIL, LHS and RHS of assignment must have exactly same width.
564 rhs_sigspec = self.rhs_compiler.match_shape(
565 stmt.rhs, lhs_bits, lhs_sign)
566 self._case.assign(self.lhs_compiler(stmt.lhs), rhs_sigspec)
567
568 def on_Switch(self, stmt):
569 self._check_rhs(stmt.test)
570
571 if stmt not in self._test_cache:
572 self._test_cache[stmt] = self.rhs_compiler(stmt.test)
573 test_sigspec = self._test_cache[stmt]
574
575 with self._case.switch(test_sigspec) as switch:
576 for value, stmts in stmt.cases.items():
577 with self.case(switch, value):
578 self.on_statements(stmts)
579
580 def on_statement(self, stmt):
581 try:
582 super().on_statement(stmt)
583 except LegalizeValue as legalize:
584 with self._case.switch(self.rhs_compiler(legalize.value)) as switch:
585 bits, sign = legalize.value.shape()
586 tests = ["{:0{}b}".format(v, bits) for v in legalize.branches]
587 tests[-1] = "-" * bits
588 for branch, test in zip(legalize.branches, tests):
589 with self.case(switch, test):
590 branch_value = ast.Const(branch, (bits, sign))
591 with self.state.expand_to(legalize.value, branch_value):
592 super().on_statement(stmt)
593
594 def on_statements(self, stmts):
595 for stmt in stmts:
596 self.on_statement(stmt)
597
598
599 def convert_fragment(builder, fragment, name, top):
600 if isinstance(fragment, ir.Instance):
601 port_map = OrderedDict()
602 for port_name, value in fragment.named_ports.items():
603 port_map["\\{}".format(port_name)] = value
604
605 if fragment.type[0] == "$":
606 return fragment.type, port_map
607 else:
608 return "\\{}".format(fragment.type), port_map
609
610 with builder.module(name or "anonymous", attrs={"top": 1} if top else {}) as module:
611 compiler_state = _ValueCompilerState(module)
612 rhs_compiler = _RHSValueCompiler(compiler_state)
613 lhs_compiler = _LHSValueCompiler(compiler_state)
614 stmt_compiler = _StatementCompiler(compiler_state, rhs_compiler, lhs_compiler)
615
616 verilog_trigger = None
617 verilog_trigger_sync_emitted = False
618
619 # Register all signals driven in the current fragment. This must be done first, as it
620 # affects further codegen; e.g. whether sig$next signals will be generated and used.
621 for domain, signal in fragment.iter_drivers():
622 compiler_state.add_driven(signal, sync=domain is not None)
623
624 # Transform all signals used as ports in the current fragment eagerly and outside of
625 # any hierarchy, to make sure they get sensible (non-prefixed) names.
626 for signal in fragment.ports:
627 compiler_state.add_port(signal, fragment.ports[signal])
628 compiler_state.resolve_curr(signal)
629
630 # Transform all clocks clocks and resets eagerly and outside of any hierarchy, to make
631 # sure they get sensible (non-prefixed) names. This does not affect semantics.
632 for domain, _ in fragment.iter_sync():
633 cd = fragment.domains[domain]
634 compiler_state.resolve_curr(cd.clk)
635 if cd.rst is not None:
636 compiler_state.resolve_curr(cd.rst)
637
638 # Transform all subfragments to their respective cells. Transforming signals connected
639 # to their ports into wires eagerly makes sure they get sensible (prefixed with submodule
640 # name) names.
641 memories = OrderedDict()
642 for subfragment, sub_name in fragment.subfragments:
643 if not subfragment.ports:
644 continue
645
646 sub_params = OrderedDict()
647 if hasattr(subfragment, "parameters"):
648 for param_name, param_value in subfragment.parameters.items():
649 if isinstance(param_value, mem.Memory):
650 memory = param_value
651 if memory not in memories:
652 memories[memory] = module.memory(width=memory.width, size=memory.depth,
653 name=memory.name)
654 addr_bits = bits_for(memory.depth)
655 data_parts = []
656 for addr in range(memory.depth):
657 if addr < len(memory.init):
658 data = memory.init[addr]
659 else:
660 data = 0
661 data_parts.append("{:0{}b}".format(data, memory.width))
662 module.cell("$meminit", ports={
663 "\\ADDR": rhs_compiler(ast.Const(0, addr_bits)),
664 "\\DATA": "{}'".format(memory.width * memory.depth) +
665 "".join(reversed(data_parts)),
666 }, params={
667 "MEMID": memories[memory],
668 "ABITS": addr_bits,
669 "WIDTH": memory.width,
670 "WORDS": memory.depth,
671 "PRIORITY": 0,
672 })
673
674 param_value = memories[memory]
675
676 sub_params[param_name] = param_value
677
678 sub_type, sub_port_map = \
679 convert_fragment(builder, subfragment, top=False, name=sub_name)
680
681 sub_ports = OrderedDict()
682 for port, value in sub_port_map.items():
683 for signal in value._rhs_signals():
684 compiler_state.resolve_curr(signal, prefix=sub_name)
685 sub_ports[port] = rhs_compiler(value)
686
687 module.cell(sub_type, name=sub_name, ports=sub_ports, params=sub_params)
688
689 # If we emit all of our combinatorial logic into a single RTLIL process, Verilog
690 # simulators will break horribly, because Yosys write_verilog transforms RTLIL processes
691 # into always @* blocks with blocking assignment, and that does not create delta cycles.
692 #
693 # Therefore, we translate the fragment as many times as there are independent groups
694 # of signals (a group is a transitive closure of signals that appear together on LHS),
695 # splitting them into many RTLIL (and thus Verilog) processes.
696 lhs_grouper = xfrm.LHSGroupAnalyzer()
697 lhs_grouper.on_statements(fragment.statements)
698
699 for group, group_signals in lhs_grouper.groups().items():
700 lhs_group_filter = xfrm.LHSGroupFilter(group_signals)
701
702 with module.process(name="$group_{}".format(group)) as process:
703 with process.case() as case:
704 # For every signal in comb domain, assign \sig$next to the reset value.
705 # For every signal in sync domains, assign \sig$next to the current
706 # value (\sig).
707 for domain, signal in fragment.iter_drivers():
708 if signal not in group_signals:
709 continue
710 if domain is None:
711 prev_value = ast.Const(signal.reset, signal.nbits)
712 else:
713 prev_value = signal
714 case.assign(lhs_compiler(signal), rhs_compiler(prev_value))
715
716 # Convert statements into decision trees.
717 stmt_compiler._case = case
718 stmt_compiler._has_rhs = False
719 stmt_compiler(lhs_group_filter(fragment.statements))
720
721 # Verilog `always @*` blocks will not run if `*` does not match anything, i.e.
722 # if the implicit sensitivity list is empty. We check this while translating,
723 # by looking for any signals on RHS. If there aren't any, we add some logic
724 # whose only purpose is to trigger Verilog simulators when it converts
725 # through RTLIL and to Verilog, by populating the sensitivity list.
726 if not stmt_compiler._has_rhs:
727 if verilog_trigger is None:
728 verilog_trigger = \
729 module.wire(1, name="$verilog_initial_trigger")
730 case.assign(verilog_trigger, verilog_trigger)
731
732 # For every signal in the sync domain, assign \sig's initial value (which will
733 # end up as the \init reg attribute) to the reset value.
734 with process.sync("init") as sync:
735 for domain, signal in fragment.iter_sync():
736 if signal not in group_signals:
737 continue
738 wire_curr, wire_next = compiler_state.resolve(signal)
739 sync.update(wire_curr, rhs_compiler(ast.Const(signal.reset, signal.nbits)))
740
741 # The Verilog simulator trigger needs to change at time 0, so if we haven't
742 # yet done that in some process, do it.
743 if verilog_trigger and not verilog_trigger_sync_emitted:
744 sync.update(verilog_trigger, "1'0")
745 verilog_trigger_sync_emitted = True
746
747 # For every signal in every domain, assign \sig to \sig$next. The sensitivity list,
748 # however, differs between domains: for comb domains, it is `always`, for sync
749 # domains with sync reset, it is `posedge clk`, for sync domains with async reset
750 # it is `posedge clk or posedge rst`.
751 for domain, signals in fragment.drivers.items():
752 signals = signals & group_signals
753 if not signals:
754 continue
755
756 triggers = []
757 if domain is None:
758 triggers.append(("always",))
759 else:
760 cd = fragment.domains[domain]
761 triggers.append(("posedge", compiler_state.resolve_curr(cd.clk)))
762 if cd.async_reset:
763 triggers.append(("posedge", compiler_state.resolve_curr(cd.rst)))
764
765 for trigger in triggers:
766 with process.sync(*trigger) as sync:
767 for signal in signals:
768 wire_curr, wire_next = compiler_state.resolve(signal)
769 sync.update(wire_curr, wire_next)
770
771 # Finally, collect the names we've given to our ports in RTLIL, and correlate these with
772 # the signals represented by these ports. If we are a submodule, this will be necessary
773 # to create a cell for us in the parent module.
774 port_map = OrderedDict()
775 for signal in fragment.ports:
776 port_map[compiler_state.resolve_curr(signal)] = signal
777
778 return module.name, port_map
779
780
781 def convert(fragment, name="top", **kwargs):
782 fragment = fragment.prepare(**kwargs)
783 builder = _Builder()
784 convert_fragment(builder, fragment, name=name, top=True)
785 return str(builder)