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