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