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