diff --git a/amaranth/hdl/_dsl.py b/amaranth/hdl/_dsl.py index 506ba8d..b753ae1 100644 --- a/amaranth/hdl/_dsl.py +++ b/amaranth/hdl/_dsl.py @@ -503,9 +503,11 @@ class Module(_ModuleBuilderRoot, Elaboratable): if_tests, if_bodies = data["tests"], data["bodies"] if_src_locs = data["src_locs"] - domains = set() + # Use dict to ensure deterministic iteration. + domains = {} for if_case in if_bodies: - domains |= set(if_case) + for domain in if_case: + domains[domain] = None for domain in domains: tests, cases = [], OrderedDict() @@ -528,9 +530,10 @@ class Module(_ModuleBuilderRoot, Elaboratable): switch_test, switch_cases = data["test"], data["cases"] switch_case_src_locs = data["case_src_locs"] - domains = set() + domains = {} for stmts in switch_cases.values(): - domains |= set(stmts) + for domain in stmts: + domains[domain] = None for domain in domains: domain_cases = OrderedDict() @@ -561,9 +564,10 @@ class Module(_ModuleBuilderRoot, Elaboratable): self._top_comb_statements.append( sig.eq(Operator("==", [fsm_signal, fsm_encoding[name]], src_loc_at=0))) - domains = set() + domains = {} for stmts in fsm_states.values(): - domains |= set(stmts) + for domain in stmts: + domains[domain] = None for domain in domains: domain_states = OrderedDict() diff --git a/amaranth/hdl/_nir.py b/amaranth/hdl/_nir.py index 6e5aee1..eefce58 100644 --- a/amaranth/hdl/_nir.py +++ b/amaranth/hdl/_nir.py @@ -383,10 +383,10 @@ class Top(Cell): def __repr__(self): ports = [] - for (name, val) in self.ports_o.items(): - ports.append(f"(output {name!r} {val})") for (name, (start, width)) in self.ports_i.items(): ports.append(f"(input {name!r} {start}:{start+width})") + for (name, val) in self.ports_o.items(): + ports.append(f"(output {name!r} {val})") for (name, (start, width)) in self.ports_io.items(): ports.append(f"(inout {name!r} {start}:{start+width})") ports = " ".join(ports) @@ -533,7 +533,7 @@ class ArrayMux(Cell): self.index = netlist.resolve_value(self.index) def __repr__(self): - elems = " ".join(repr(elem) for elem in elems) + elems = " ".join(repr(elem) for elem in self.elems) return f"(array_mux {self.width} {self.index} ({elems}))" diff --git a/tests/test_hdl_ir.py b/tests/test_hdl_ir.py index 299344a..8c37a7a 100644 --- a/tests/test_hdl_ir.py +++ b/tests/test_hdl_ir.py @@ -106,7 +106,7 @@ class FragmentPortsTestCase(FHDLTestCase): self.assertRepr(nl, """ ( (module 0 None ('top') (input 's1' 0.2) (output 'c1' 0.2)) - (cell 0 0 (top (output 'c1' 0.2) (input 's1' 2:3))) + (cell 0 0 (top (input 's1' 2:3) (output 'c1' 0.2))) ) """) @@ -123,7 +123,7 @@ class FragmentPortsTestCase(FHDLTestCase): ( (module 0 None ('top') (input 's1' 0.2) (output 'c1' 1.0)) (module 1 0 ('top' 'f2') (input 's1' 0.2) (output 'c1' 1.0)) - (cell 0 0 (top (output 'c1' 1.0) (input 's1' 2:3))) + (cell 0 0 (top (input 's1' 2:3) (output 'c1' 1.0))) (cell 1 1 (~ 0.2)) ) """) @@ -210,7 +210,7 @@ class FragmentPortsTestCase(FHDLTestCase): (module 8 0 ('top' 'f2') (input 's1' 0.2) (output 's2' 10.0)) - (cell 0 0 (top (output 'c1' 5.0) (output 'c2' 2.0) (output 'c3' 1.0) (input 's1' 2:3))) + (cell 0 0 (top (input 's1' 2:3) (output 'c1' 5.0) (output 'c2' 2.0) (output 'c3' 1.0))) (cell 1 3 (~ 2.0)) (cell 2 4 (~ 6.0)) (cell 3 4 (assignment_list 1'd0 (1 0:1 1'd1))) @@ -234,7 +234,7 @@ class FragmentPortsTestCase(FHDLTestCase): self.assertRepr(nl, """ ( (module 0 None ('top') (input 'b' 0.2) (inout 'c' 0.3) (output 'a' 1'd0)) - (cell 0 0 (top (output 'a' 1'd0) (input 'b' 2:3) (inout 'c' 3:4))) + (cell 0 0 (top (input 'b' 2:3) (output 'a' 1'd0) (inout 'c' 3:4))) ) """) @@ -253,7 +253,7 @@ class FragmentPortsTestCase(FHDLTestCase): self.assertRepr(nl, """ ( (module 0 None ('top') (input 'clk' 0.2) (input 'rst' 0.3) (output 'ctr' 5.0:4)) - (cell 0 0 (top (output 'ctr' 5.0:4) (input 'clk' 2:3) (input 'rst' 3:4))) + (cell 0 0 (top (input 'clk' 2:3) (input 'rst' 3:4) (output 'ctr' 5.0:4))) (cell 1 0 (+ (cat 5.0:4 1'd0) 5'd1)) (cell 2 0 (matches 0.3 1)) (cell 3 0 (priority_match 1 2.0)) @@ -271,7 +271,7 @@ class FragmentPortsTestCase(FHDLTestCase): self.assertRepr(nl, """ ( (module 0 None ('top') (input 'clk' 0.2) (input 'rst' 0.3) (output 'ctr' 5.0:4)) - (cell 0 0 (top (output 'ctr' 5.0:4) (input 'clk' 2:3) (input 'rst' 3:4))) + (cell 0 0 (top (input 'clk' 2:3) (input 'rst' 3:4) (output 'ctr' 5.0:4))) (cell 1 0 (+ (cat 5.0:4 1'd0) 5'd1)) (cell 2 0 (matches 0.3 1)) (cell 3 0 (priority_match 1 2.0)) @@ -301,9 +301,9 @@ class FragmentPortsTestCase(FHDLTestCase): (input 'b' 0.6:10) (output 'c' 1.4:7)) (cell 0 0 (top - (output 'c' 1.4:7) (input 'a' 2:6) - (input 'b' 6:10))) + (input 'b' 6:10) + (output 'c' 1.4:7))) (cell 1 1 (* (cat 0.2:6 4'd0) (cat 0.6:10 4'd0))) ) """) @@ -339,9 +339,9 @@ class FragmentPortsTestCase(FHDLTestCase): (output 'port$1$0' 1.0:4) (output 'port$1$4' 1.4:8)) (cell 0 0 (top + (input 'a' 2:6) (output 'c' 1.0:4) (output 'd' 1.4:8) - (input 'a' 2:6) (inout 'b' 6:10))) (cell 1 1 (instance 't' 'i' (param 'p' 'meow') @@ -860,8 +860,8 @@ class InstanceTestCase(FHDLTestCase): (output 'o' 1.0:4) ) (cell 0 0 (top - (output 'o' 1.0:4) (input 'i' 2:5) + (output 'o' 1.0:4) (inout 'io' 5:10) )) (cell 1 0 (instance 'gadget' 'my_gadget' @@ -944,8 +944,8 @@ class InstanceTestCase(FHDLTestCase): (output 'o' 1.0:4) ) (cell 0 0 (top - (output 'o' 1.0:4) (input 'i' 2:5) + (output 'o' 1.0:4) (inout 'io' 5:10) )) (cell 1 0 (instance 'gadget' 'my_gadget' @@ -1150,9 +1150,9 @@ class IOBufferTestCase(FHDLTestCase): (output 'i' 1.0:4) ) (cell 0 0 (top - (output 'i' 1.0:4) (input 'o' 6:10) (input 'oe' 10:11) + (output 'i' 1.0:4) (inout 'pad' 2:6) )) (cell 1 0 (iob 0.2:6 0.6:10 0.10)) @@ -1207,8 +1207,8 @@ class AssignTestCase(FHDLTestCase): (output 's1' 0.2:10) ) (cell 0 0 (top - (output 's1' 0.2:10) (input 's2' 2:10) + (output 's1' 0.2:10) )) ) """) @@ -1230,8 +1230,8 @@ class AssignTestCase(FHDLTestCase): (output 's1' 0.2:10) ) (cell 0 0 (top - (output 's1' 0.2:10) (input 's2' 2:12) + (output 's1' 0.2:10) )) ) """) @@ -1253,8 +1253,8 @@ class AssignTestCase(FHDLTestCase): (output 's1' (cat 0.2:8 2'd0)) ) (cell 0 0 (top - (output 's1' (cat 0.2:8 2'd0)) (input 's2' 2:8) + (output 's1' (cat 0.2:8 2'd0)) )) ) """) @@ -1276,8 +1276,8 @@ class AssignTestCase(FHDLTestCase): (output 's1' (cat 0.2:8 0.7 0.7)) ) (cell 0 0 (top - (output 's1' (cat 0.2:8 0.7 0.7)) (input 's2' 2:8) + (output 's1' (cat 0.2:8 0.7 0.7)) )) ) """) @@ -1299,8 +1299,8 @@ class AssignTestCase(FHDLTestCase): (output 's1' 1.0:8) ) (cell 0 0 (top - (output 's1' 1.0:8) (input 's2' 2:6) + (output 's1' 1.0:8) )) (cell 1 0 (assignment_list 8'd0 (1 2:6 0.2:6))) ) @@ -1325,9 +1325,9 @@ class AssignTestCase(FHDLTestCase): (output 's1' 10.0:8) ) (cell 0 0 (top - (output 's1' 10.0:8) (input 's2' 2:6) (input 's3' 6:10) + (output 's1' 10.0:8) )) (cell 1 0 (matches 0.6:10 0000)) (cell 2 0 (matches 0.6:10 0001)) @@ -1370,9 +1370,9 @@ class AssignTestCase(FHDLTestCase): (output 's1' 6.0:8) ) (cell 0 0 (top - (output 's1' 6.0:8) (input 's2' 2:6) (input 's3' 6:8) + (output 's1' 6.0:8) )) (cell 1 0 (matches 0.6:8 00)) (cell 2 0 (matches 0.6:8 01)) @@ -1407,9 +1407,9 @@ class AssignTestCase(FHDLTestCase): (output 's1' 6.0:16) ) (cell 0 0 (top - (output 's1' 6.0:16) (input 's2' 2:6) (input 's3' 6:10) + (output 's1' 6.0:16) )) (cell 1 0 (matches 0.6:10 0000)) (cell 2 0 (matches 0.6:10 0001)) @@ -1444,9 +1444,9 @@ class AssignTestCase(FHDLTestCase): (output 's1' 7.0:17) ) (cell 0 0 (top - (output 's1' 7.0:17) (input 's2' 2:6) (input 's3' 6:10) + (output 's1' 7.0:17) )) (cell 1 0 (matches 0.6:10 0000)) (cell 2 0 (matches 0.6:10 0001)) @@ -1487,10 +1487,10 @@ class AssignTestCase(FHDLTestCase): (output 's3' 0.10:14) ) (cell 0 0 (top + (input 's4' 2:14) (output 's1' 0.2:6) (output 's2' 0.6:10) (output 's3' 0.10:14) - (input 's4' 2:14) )) ) """) @@ -1518,10 +1518,10 @@ class AssignTestCase(FHDLTestCase): (output 's3' (cat 0.7 0.7 0.7 0.7)) ) (cell 0 0 (top + (input 's4' 2:8) (output 's1' 0.2:6) (output 's2' (cat 0.6:8 0.7 0.7)) (output 's3' (cat 0.7 0.7 0.7 0.7)) - (input 's4' 2:8) )) ) """) @@ -1546,9 +1546,9 @@ class AssignTestCase(FHDLTestCase): (output 's2' 0.2:10) ) (cell 0 0 (top + (input 's3' 2:10) (output 's1' 0.2:10) (output 's2' 0.2:10) - (input 's3' 2:10) )) ) """) @@ -1577,11 +1577,11 @@ class AssignTestCase(FHDLTestCase): (output 's3' 7.0:8) ) (cell 0 0 (top + (input 's4' 2:10) + (input 's5' 10:18) (output 's1' 5.0:8) (output 's2' 6.0:8) (output 's3' 7.0:8) - (input 's4' 2:10) - (input 's5' 10:18) )) (cell 1 0 (matches 0.2:10 00000000)) (cell 2 0 (matches 0.2:10 00000001)) @@ -1610,8 +1610,8 @@ class AssignTestCase(FHDLTestCase): (output 's1' 1.0:12) ) (cell 0 0 (top - (output 's1' 1.0:12) (input 's2' 2:6) + (output 's1' 1.0:12) )) (cell 1 0 (assignment_list 12'd0 (1 3:7 0.2:6))) ) @@ -1646,12 +1646,12 @@ class AssignTestCase(FHDLTestCase): (output 's4' 2.0:4) ) (cell 0 0 (top - (output 's2' 1.0:4) - (output 's3' 0.13:17) - (output 's4' 2.0:4) (input 's1' 2:6) (input 's5' 6:10) (input 's6' 10:18) + (output 's2' 1.0:4) + (output 's3' 0.13:17) + (output 's4' 2.0:4) )) (cell 1 0 (assignment_list 4'd0 (1 1:4 0.10:13))) (cell 2 0 (assignment_list 4'd0 (1 0:2 (cat 0.17 1'd0)))) @@ -1677,9 +1677,9 @@ class AssignTestCase(FHDLTestCase): (output 's1' 10.0:8) ) (cell 0 0 (top - (output 's1' 10.0:8) (input 's2' 2:6) (input 's3' 6:10) + (output 's1' 10.0:8) )) (cell 1 0 (matches 0.6:10 0000)) (cell 2 0 (matches 0.6:10 0001)) @@ -1720,9 +1720,9 @@ class AssignTestCase(FHDLTestCase): (output 's1' 4.0:8) ) (cell 0 0 (top - (output 's1' 4.0:8) (input 's2' 2:6) (input 's3' 6:10) + (output 's1' 4.0:8) )) (cell 1 0 (matches 0.6:10 0000)) (cell 2 0 (matches 0.6:10 0001)) @@ -1758,11 +1758,11 @@ class AssignTestCase(FHDLTestCase): (output 's3' 7.0:8) ) (cell 0 0 (top + (input 's4' 2:10) + (input 's5' 10:18) (output 's1' 5.0:8) (output 's2' 6.0:8) (output 's3' 7.0:8) - (input 's4' 2:10) - (input 's5' 10:18) )) (cell 1 0 (matches 0.2:10 00000000)) (cell 2 0 (matches 0.2:10 00000001)) @@ -1793,9 +1793,9 @@ class AssignTestCase(FHDLTestCase): (output 's1' 8.0:8) ) (cell 0 0 (top - (output 's1' 8.0:8) (input 's2' 2:6) (input 's3' 6:10) + (output 's1' 8.0:8) )) (cell 1 0 (matches 0.6:10 0000)) (cell 2 0 (matches 0.6:10 0001)) @@ -1834,9 +1834,9 @@ class AssignTestCase(FHDLTestCase): (output 's1' 8.0:12) ) (cell 0 0 (top - (output 's1' 8.0:12) (input 's2' 2:6) (input 's3' 6:10) + (output 's1' 8.0:12) )) (cell 1 0 (matches 0.6:10 0000)) (cell 2 0 (matches 0.6:10 0001)) @@ -1875,11 +1875,1307 @@ class AssignTestCase(FHDLTestCase): (output 's2' 2.0:8) ) (cell 0 0 (top + (input 's3' 2:10) (output 's1' 1.0:8) (output 's2' 2.0:8) - (input 's3' 2:10) )) (cell 1 0 (assignment_list 8'd0 (1 2:7 0.2:7))) (cell 2 0 (assignment_list 8'd0 (1 2:7 0.2:7))) ) """) + +class RhsTestCase(FHDLTestCase): + def test_const(self): + o1 = Signal(8) + o2 = Signal(8) + m = Module() + m.d.comb += o1.eq(13) + m.d.comb += o2.eq(-13) + nl = build_netlist(Fragment.get(m, None), [o1, o2]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (output 'o1' 8'd13) + (output 'o2' 8'd243) + ) + (cell 0 0 (top + (output 'o1' 8'd13) + (output 'o2' 8'd243) + )) + ) + """) + + def test_operator_signed(self): + o1 = Signal(8) + o2 = Signal(8) + i1 = Signal(unsigned(4)) + i2 = Signal(signed(4)) + m = Module() + m.d.comb += o1.eq(i1.as_signed()) + m.d.comb += o2.eq(i2.as_unsigned()) + nl = build_netlist(Fragment.get(m, None), [i1, i2, o1, o2]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i1' 0.2:6) + (input 'i2' 0.6:10) + (output 'o1' (cat 0.2:6 0.5 0.5 0.5 0.5)) + (output 'o2' (cat 0.6:10 4'd0)) + ) + (cell 0 0 (top + (input 'i1' 2:6) + (input 'i2' 6:10) + (output 'o1' (cat 0.2:6 0.5 0.5 0.5 0.5)) + (output 'o2' (cat 0.6:10 4'd0)) + )) + ) + """) + + def test_operator_unary(self): + o1 = Signal(8) + o2 = Signal(8) + o3 = Signal(8) + o4 = Signal(8) + o5 = Signal(8) + o6 = Signal(8) + o7 = Signal(2) + o8 = Signal(2) + o9 = Signal(2) + o10 = Signal(2) + o11 = Signal(2) + o12 = Signal(2) + o13 = Signal(2) + o14 = Signal(2) + i1 = Signal(unsigned(4)) + i2 = Signal(signed(4)) + m = Module() + m.d.comb += o1.eq(+i1) + m.d.comb += o2.eq(+i2) + m.d.comb += o3.eq(-i1) + m.d.comb += o4.eq(-i2) + m.d.comb += o5.eq(~i1) + m.d.comb += o6.eq(~i2) + m.d.comb += o7.eq(i1.all()) + m.d.comb += o8.eq(i2.all()) + m.d.comb += o9.eq(i1.any()) + m.d.comb += o10.eq(i2.any()) + m.d.comb += o11.eq(i1.xor()) + m.d.comb += o12.eq(i2.xor()) + m.d.comb += o13.eq(i1.bool()) + m.d.comb += o14.eq(i2.bool()) + nl = build_netlist(Fragment.get(m, None), + [i1, i2, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i1' 0.2:6) + (input 'i2' 0.6:10) + (output 'o1' (cat 0.2:6 4'd0)) + (output 'o2' (cat 0.6:10 0.9 0.9 0.9 0.9)) + (output 'o3' (cat 1.0:5 1.4 1.4 1.4)) + (output 'o4' (cat 2.0:5 2.4 2.4 2.4)) + (output 'o5' (cat 3.0:4 4'd0)) + (output 'o6' (cat 4.0:4 4.3 4.3 4.3 4.3)) + (output 'o7' (cat 5.0 1'd0)) + (output 'o8' (cat 6.0 1'd0)) + (output 'o9' (cat 7.0 1'd0)) + (output 'o10' (cat 8.0 1'd0)) + (output 'o11' (cat 9.0 1'd0)) + (output 'o12' (cat 10.0 1'd0)) + (output 'o13' (cat 11.0 1'd0)) + (output 'o14' (cat 12.0 1'd0)) + ) + (cell 0 0 (top + (input 'i1' 2:6) + (input 'i2' 6:10) + (output 'o1' (cat 0.2:6 4'd0)) + (output 'o2' (cat 0.6:10 0.9 0.9 0.9 0.9)) + (output 'o3' (cat 1.0:5 1.4 1.4 1.4)) + (output 'o4' (cat 2.0:5 2.4 2.4 2.4)) + (output 'o5' (cat 3.0:4 4'd0)) + (output 'o6' (cat 4.0:4 4.3 4.3 4.3 4.3)) + (output 'o7' (cat 5.0 1'd0)) + (output 'o8' (cat 6.0 1'd0)) + (output 'o9' (cat 7.0 1'd0)) + (output 'o10' (cat 8.0 1'd0)) + (output 'o11' (cat 9.0 1'd0)) + (output 'o12' (cat 10.0 1'd0)) + (output 'o13' (cat 11.0 1'd0)) + (output 'o14' (cat 12.0 1'd0)) + )) + (cell 1 0 (- (cat 0.2:6 1'd0))) + (cell 2 0 (- (cat 0.6:10 0.9))) + (cell 3 0 (~ 0.2:6)) + (cell 4 0 (~ 0.6:10)) + (cell 5 0 (r& 0.2:6)) + (cell 6 0 (r& 0.6:10)) + (cell 7 0 (r| 0.2:6)) + (cell 8 0 (r| 0.6:10)) + (cell 9 0 (r^ 0.2:6)) + (cell 10 0 (r^ 0.6:10)) + (cell 11 0 (b 0.2:6)) + (cell 12 0 (b 0.6:10)) + ) + """) + + def test_operator_binary_bitwise(self): + i8u = Signal(8) + i9u = Signal(9) + i8s = Signal(signed(8)) + i9s = Signal(signed(9)) + i1 = Signal() + o1 = Signal(12) + o2 = Signal(12) + o3 = Signal(12) + o4 = Signal(12) + o5 = Signal(12) + o6 = Signal(12) + o7 = Signal(12) + o8 = Signal(12) + o9 = Signal(12) + o10 = Signal(12) + o11 = Signal(12) + o12 = Signal(12) + o13 = Signal(12) + o14 = Signal(12) + o15 = Signal(12) + o16 = Signal(12) + m = Module() + m.d.comb += o1.eq(i8u & i8u) + m.d.comb += o2.eq(i8u & i9u) + m.d.comb += o3.eq(i8u & i8s) + m.d.comb += o4.eq(i8u & i9s) + m.d.comb += o5.eq(i9u | i8u) + m.d.comb += o6.eq(i9u | i9u) + m.d.comb += o7.eq(i9u | i8s) + m.d.comb += o8.eq(i9u | i9s) + m.d.comb += o9.eq(i8s ^ i8u) + m.d.comb += o10.eq(i8s ^ i9u) + m.d.comb += o11.eq(i8s ^ i8s) + m.d.comb += o12.eq(i8s ^ i9s) + m.d.comb += o13.eq(Mux(i1, i9s, i8u)) + m.d.comb += o14.eq(Mux(i1, i9s, i9u)) + m.d.comb += o15.eq(Mux(i1, i9s, i8s)) + m.d.comb += o16.eq(Mux(i1, i9s, i9s)) + nl = build_netlist(Fragment.get(m, None), [ + i8u, i9u, i8s, i9s, i1, + o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i9u' 0.10:19) + (input 'i8s' 0.19:27) + (input 'i9s' 0.27:36) + (input 'i1' 0.36) + (output 'o1' (cat 1.0:8 4'd0)) + (output 'o2' (cat 2.0:9 3'd0)) + (output 'o3' (cat 3.0:9 3.8 3.8 3.8)) + (output 'o4' (cat 4.0:9 4.8 4.8 4.8)) + (output 'o5' (cat 5.0:9 3'd0)) + (output 'o6' (cat 6.0:9 3'd0)) + (output 'o7' (cat 7.0:10 7.9 7.9)) + (output 'o8' (cat 8.0:10 8.9 8.9)) + (output 'o9' (cat 9.0:9 9.8 9.8 9.8)) + (output 'o10' (cat 10.0:10 10.9 10.9)) + (output 'o11' (cat 11.0:8 11.7 11.7 11.7 11.7)) + (output 'o12' (cat 12.0:9 12.8 12.8 12.8)) + (output 'o13' (cat 13.0:9 13.8 13.8 13.8)) + (output 'o14' (cat 14.0:10 14.9 14.9)) + (output 'o15' (cat 15.0:9 15.8 15.8 15.8)) + (output 'o16' (cat 16.0:9 16.8 16.8 16.8)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i9u' 10:19) + (input 'i8s' 19:27) + (input 'i9s' 27:36) + (input 'i1' 36:37) + (output 'o1' (cat 1.0:8 4'd0)) + (output 'o2' (cat 2.0:9 3'd0)) + (output 'o3' (cat 3.0:9 3.8 3.8 3.8)) + (output 'o4' (cat 4.0:9 4.8 4.8 4.8)) + (output 'o5' (cat 5.0:9 3'd0)) + (output 'o6' (cat 6.0:9 3'd0)) + (output 'o7' (cat 7.0:10 7.9 7.9)) + (output 'o8' (cat 8.0:10 8.9 8.9)) + (output 'o9' (cat 9.0:9 9.8 9.8 9.8)) + (output 'o10' (cat 10.0:10 10.9 10.9)) + (output 'o11' (cat 11.0:8 11.7 11.7 11.7 11.7)) + (output 'o12' (cat 12.0:9 12.8 12.8 12.8)) + (output 'o13' (cat 13.0:9 13.8 13.8 13.8)) + (output 'o14' (cat 14.0:10 14.9 14.9)) + (output 'o15' (cat 15.0:9 15.8 15.8 15.8)) + (output 'o16' (cat 16.0:9 16.8 16.8 16.8)) + )) + (cell 1 0 (& 0.2:10 0.2:10)) + (cell 2 0 (& (cat 0.2:10 1'd0) 0.10:19)) + (cell 3 0 (& (cat 0.2:10 1'd0) (cat 0.19:27 0.26))) + (cell 4 0 (& (cat 0.2:10 1'd0) 0.27:36)) + (cell 5 0 (| 0.10:19 (cat 0.2:10 1'd0))) + (cell 6 0 (| 0.10:19 0.10:19)) + (cell 7 0 (| (cat 0.10:19 1'd0) (cat 0.19:27 0.26 0.26))) + (cell 8 0 (| (cat 0.10:19 1'd0) (cat 0.27:36 0.35))) + (cell 9 0 (^ (cat 0.19:27 0.26) (cat 0.2:10 1'd0))) + (cell 10 0 (^ (cat 0.19:27 0.26 0.26) (cat 0.10:19 1'd0))) + (cell 11 0 (^ 0.19:27 0.19:27)) + (cell 12 0 (^ (cat 0.19:27 0.26) 0.27:36)) + (cell 13 0 (m 0.36 0.27:36 (cat 0.2:10 1'd0))) + (cell 14 0 (m 0.36 (cat 0.27:36 0.35) (cat 0.10:19 1'd0))) + (cell 15 0 (m 0.36 0.27:36 (cat 0.19:27 0.26))) + (cell 16 0 (m 0.36 0.27:36 0.27:36)) + ) + """) + + def test_operator_binary_add(self): + i8u = Signal(8) + i9u = Signal(9) + i8s = Signal(signed(8)) + i9s = Signal(signed(9)) + o1 = Signal(12) + o2 = Signal(12) + o3 = Signal(12) + o4 = Signal(12) + o5 = Signal(12) + o6 = Signal(12) + o7 = Signal(12) + o8 = Signal(12) + o9 = Signal(12) + o10 = Signal(12) + o11 = Signal(12) + o12 = Signal(12) + o13 = Signal(12) + o14 = Signal(12) + o15 = Signal(12) + o16 = Signal(12) + m = Module() + m.d.comb += o1.eq(i8u + i8u) + m.d.comb += o2.eq(i8u + i9u) + m.d.comb += o3.eq(i8u + i8s) + m.d.comb += o4.eq(i8u + i9s) + m.d.comb += o5.eq(i9u + i8u) + m.d.comb += o6.eq(i9u + i9u) + m.d.comb += o7.eq(i9u + i8s) + m.d.comb += o8.eq(i9u + i9s) + m.d.comb += o9.eq(i8s + i8u) + m.d.comb += o10.eq(i8s + i9u) + m.d.comb += o11.eq(i8s + i8s) + m.d.comb += o12.eq(i8s + i9s) + m.d.comb += o13.eq(i9s + i8u) + m.d.comb += o14.eq(i9s + i9u) + m.d.comb += o15.eq(i9s + i8s) + m.d.comb += o16.eq(i9s + i9s) + nl = build_netlist(Fragment.get(m, None), [ + i8u, i9u, i8s, i9s, + o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i9u' 0.10:19) + (input 'i8s' 0.19:27) + (input 'i9s' 0.27:36) + (output 'o1' (cat 1.0:9 3'd0)) + (output 'o2' (cat 2.0:10 2'd0)) + (output 'o3' (cat 3.0:10 3.9 3.9)) + (output 'o4' (cat 4.0:10 4.9 4.9)) + (output 'o5' (cat 5.0:10 2'd0)) + (output 'o6' (cat 6.0:10 2'd0)) + (output 'o7' (cat 7.0:11 7.10)) + (output 'o8' (cat 8.0:11 8.10)) + (output 'o9' (cat 9.0:10 9.9 9.9)) + (output 'o10' (cat 10.0:11 10.10)) + (output 'o11' (cat 11.0:9 11.8 11.8 11.8)) + (output 'o12' (cat 12.0:10 12.9 12.9)) + (output 'o13' (cat 13.0:10 13.9 13.9)) + (output 'o14' (cat 14.0:11 14.10)) + (output 'o15' (cat 15.0:10 15.9 15.9)) + (output 'o16' (cat 16.0:10 16.9 16.9)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i9u' 10:19) + (input 'i8s' 19:27) + (input 'i9s' 27:36) + (output 'o1' (cat 1.0:9 3'd0)) + (output 'o2' (cat 2.0:10 2'd0)) + (output 'o3' (cat 3.0:10 3.9 3.9)) + (output 'o4' (cat 4.0:10 4.9 4.9)) + (output 'o5' (cat 5.0:10 2'd0)) + (output 'o6' (cat 6.0:10 2'd0)) + (output 'o7' (cat 7.0:11 7.10)) + (output 'o8' (cat 8.0:11 8.10)) + (output 'o9' (cat 9.0:10 9.9 9.9)) + (output 'o10' (cat 10.0:11 10.10)) + (output 'o11' (cat 11.0:9 11.8 11.8 11.8)) + (output 'o12' (cat 12.0:10 12.9 12.9)) + (output 'o13' (cat 13.0:10 13.9 13.9)) + (output 'o14' (cat 14.0:11 14.10)) + (output 'o15' (cat 15.0:10 15.9 15.9)) + (output 'o16' (cat 16.0:10 16.9 16.9)) + )) + (cell 1 0 (+ (cat 0.2:10 1'd0) (cat 0.2:10 1'd0))) + (cell 2 0 (+ (cat 0.2:10 2'd0) (cat 0.10:19 1'd0))) + (cell 3 0 (+ (cat 0.2:10 2'd0) (cat 0.19:27 0.26 0.26))) + (cell 4 0 (+ (cat 0.2:10 2'd0) (cat 0.27:36 0.35))) + (cell 5 0 (+ (cat 0.10:19 1'd0) (cat 0.2:10 2'd0))) + (cell 6 0 (+ (cat 0.10:19 1'd0) (cat 0.10:19 1'd0))) + (cell 7 0 (+ (cat 0.10:19 2'd0) (cat 0.19:27 0.26 0.26 0.26))) + (cell 8 0 (+ (cat 0.10:19 2'd0) (cat 0.27:36 0.35 0.35))) + (cell 9 0 (+ (cat 0.19:27 0.26 0.26) (cat 0.2:10 2'd0))) + (cell 10 0 (+ (cat 0.19:27 0.26 0.26 0.26) (cat 0.10:19 2'd0))) + (cell 11 0 (+ (cat 0.19:27 0.26) (cat 0.19:27 0.26))) + (cell 12 0 (+ (cat 0.19:27 0.26 0.26) (cat 0.27:36 0.35))) + (cell 13 0 (+ (cat 0.27:36 0.35) (cat 0.2:10 2'd0))) + (cell 14 0 (+ (cat 0.27:36 0.35 0.35) (cat 0.10:19 2'd0))) + (cell 15 0 (+ (cat 0.27:36 0.35) (cat 0.19:27 0.26 0.26))) + (cell 16 0 (+ (cat 0.27:36 0.35) (cat 0.27:36 0.35))) + ) + """) + + def test_operator_binary_sub(self): + i8u = Signal(8) + i9u = Signal(9) + i8s = Signal(signed(8)) + i9s = Signal(signed(9)) + o1 = Signal(12) + o2 = Signal(12) + o3 = Signal(12) + o4 = Signal(12) + o5 = Signal(12) + o6 = Signal(12) + o7 = Signal(12) + o8 = Signal(12) + o9 = Signal(12) + o10 = Signal(12) + o11 = Signal(12) + o12 = Signal(12) + o13 = Signal(12) + o14 = Signal(12) + o15 = Signal(12) + o16 = Signal(12) + m = Module() + m.d.comb += o1.eq(i8u - i8u) + m.d.comb += o2.eq(i8u - i9u) + m.d.comb += o3.eq(i8u - i8s) + m.d.comb += o4.eq(i8u - i9s) + m.d.comb += o5.eq(i9u - i8u) + m.d.comb += o6.eq(i9u - i9u) + m.d.comb += o7.eq(i9u - i8s) + m.d.comb += o8.eq(i9u - i9s) + m.d.comb += o9.eq(i8s - i8u) + m.d.comb += o10.eq(i8s - i9u) + m.d.comb += o11.eq(i8s - i8s) + m.d.comb += o12.eq(i8s - i9s) + m.d.comb += o13.eq(i9s - i8u) + m.d.comb += o14.eq(i9s - i9u) + m.d.comb += o15.eq(i9s - i8s) + m.d.comb += o16.eq(i9s - i9s) + nl = build_netlist(Fragment.get(m, None), [ + i8u, i9u, i8s, i9s, + o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i9u' 0.10:19) + (input 'i8s' 0.19:27) + (input 'i9s' 0.27:36) + (output 'o1' (cat 1.0:9 1.8 1.8 1.8)) + (output 'o2' (cat 2.0:10 2.9 2.9)) + (output 'o3' (cat 3.0:10 3.9 3.9)) + (output 'o4' (cat 4.0:10 4.9 4.9)) + (output 'o5' (cat 5.0:10 5.9 5.9)) + (output 'o6' (cat 6.0:10 6.9 6.9)) + (output 'o7' (cat 7.0:11 7.10)) + (output 'o8' (cat 8.0:11 8.10)) + (output 'o9' (cat 9.0:10 9.9 9.9)) + (output 'o10' (cat 10.0:11 10.10)) + (output 'o11' (cat 11.0:9 11.8 11.8 11.8)) + (output 'o12' (cat 12.0:10 12.9 12.9)) + (output 'o13' (cat 13.0:10 13.9 13.9)) + (output 'o14' (cat 14.0:11 14.10)) + (output 'o15' (cat 15.0:10 15.9 15.9)) + (output 'o16' (cat 16.0:10 16.9 16.9)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i9u' 10:19) + (input 'i8s' 19:27) + (input 'i9s' 27:36) + (output 'o1' (cat 1.0:9 1.8 1.8 1.8)) + (output 'o2' (cat 2.0:10 2.9 2.9)) + (output 'o3' (cat 3.0:10 3.9 3.9)) + (output 'o4' (cat 4.0:10 4.9 4.9)) + (output 'o5' (cat 5.0:10 5.9 5.9)) + (output 'o6' (cat 6.0:10 6.9 6.9)) + (output 'o7' (cat 7.0:11 7.10)) + (output 'o8' (cat 8.0:11 8.10)) + (output 'o9' (cat 9.0:10 9.9 9.9)) + (output 'o10' (cat 10.0:11 10.10)) + (output 'o11' (cat 11.0:9 11.8 11.8 11.8)) + (output 'o12' (cat 12.0:10 12.9 12.9)) + (output 'o13' (cat 13.0:10 13.9 13.9)) + (output 'o14' (cat 14.0:11 14.10)) + (output 'o15' (cat 15.0:10 15.9 15.9)) + (output 'o16' (cat 16.0:10 16.9 16.9)) + )) + (cell 1 0 (- (cat 0.2:10 1'd0) (cat 0.2:10 1'd0))) + (cell 2 0 (- (cat 0.2:10 2'd0) (cat 0.10:19 1'd0))) + (cell 3 0 (- (cat 0.2:10 2'd0) (cat 0.19:27 0.26 0.26))) + (cell 4 0 (- (cat 0.2:10 2'd0) (cat 0.27:36 0.35))) + (cell 5 0 (- (cat 0.10:19 1'd0) (cat 0.2:10 2'd0))) + (cell 6 0 (- (cat 0.10:19 1'd0) (cat 0.10:19 1'd0))) + (cell 7 0 (- (cat 0.10:19 2'd0) (cat 0.19:27 0.26 0.26 0.26))) + (cell 8 0 (- (cat 0.10:19 2'd0) (cat 0.27:36 0.35 0.35))) + (cell 9 0 (- (cat 0.19:27 0.26 0.26) (cat 0.2:10 2'd0))) + (cell 10 0 (- (cat 0.19:27 0.26 0.26 0.26) (cat 0.10:19 2'd0))) + (cell 11 0 (- (cat 0.19:27 0.26) (cat 0.19:27 0.26))) + (cell 12 0 (- (cat 0.19:27 0.26 0.26) (cat 0.27:36 0.35))) + (cell 13 0 (- (cat 0.27:36 0.35) (cat 0.2:10 2'd0))) + (cell 14 0 (- (cat 0.27:36 0.35 0.35) (cat 0.10:19 2'd0))) + (cell 15 0 (- (cat 0.27:36 0.35) (cat 0.19:27 0.26 0.26))) + (cell 16 0 (- (cat 0.27:36 0.35) (cat 0.27:36 0.35))) + ) + """) + + def test_operator_binary_mul(self): + i8u = Signal(8) + i8s = Signal(signed(8)) + i10u = Signal(10) + i10s = Signal(signed(10)) + o1 = Signal(24) + o2 = Signal(24) + o3 = Signal(24) + o4 = Signal(24) + m = Module() + m.d.comb += o1.eq(i8u * i10u) + m.d.comb += o2.eq(i8u * i10s) + m.d.comb += o3.eq(i8s * i10u) + m.d.comb += o4.eq(i8s * i10s) + nl = build_netlist(Fragment.get(m, None), [ + i8u, i8s, i10u, i10s, + o1, o2, o3, o4, + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i8s' 0.10:18) + (input 'i10u' 0.18:28) + (input 'i10s' 0.28:38) + (output 'o1' (cat 1.0:18 6'd0)) + (output 'o2' (cat 2.0:18 2.17 2.17 2.17 2.17 2.17 2.17)) + (output 'o3' (cat 3.0:18 3.17 3.17 3.17 3.17 3.17 3.17)) + (output 'o4' (cat 4.0:18 4.17 4.17 4.17 4.17 4.17 4.17)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i8s' 10:18) + (input 'i10u' 18:28) + (input 'i10s' 28:38) + (output 'o1' (cat 1.0:18 6'd0)) + (output 'o2' (cat 2.0:18 2.17 2.17 2.17 2.17 2.17 2.17)) + (output 'o3' (cat 3.0:18 3.17 3.17 3.17 3.17 3.17 3.17)) + (output 'o4' (cat 4.0:18 4.17 4.17 4.17 4.17 4.17 4.17)) + )) + (cell 1 0 (* (cat 0.2:10 10'd0) (cat 0.18:28 8'd0))) + (cell 2 0 (* (cat 0.2:10 10'd0) (cat 0.28:38 0.37 0.37 0.37 0.37 0.37 0.37 0.37 0.37))) + (cell 3 0 (* (cat 0.10:18 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17) (cat 0.18:28 8'd0))) + (cell 4 0 (* (cat 0.10:18 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17) (cat 0.28:38 0.37 0.37 0.37 0.37 0.37 0.37 0.37 0.37))) + ) + """) + + def test_operator_binary_divmod(self): + i8u = Signal(8) + i8s = Signal(signed(8)) + i6u = Signal(6) + i6s = Signal(signed(6)) + m = Module() + o1 = Signal(10) + o2 = Signal(10) + o3 = Signal(10) + o4 = Signal(10) + o5 = Signal(10) + o6 = Signal(10) + o7 = Signal(10) + o8 = Signal(10) + o9 = Signal(10) + o10 = Signal(10) + o11 = Signal(10) + o12 = Signal(10) + o13 = Signal(10) + o14 = Signal(10) + o15 = Signal(10) + o16 = Signal(10) + m.d.comb += o1.eq(i8u // i6u) + m.d.comb += o2.eq(i8u % i6u) + m.d.comb += o3.eq(i8u // i6s) + m.d.comb += o4.eq(i8u % i6s) + m.d.comb += o5.eq(i8s // i6u) + m.d.comb += o6.eq(i8s % i6u) + m.d.comb += o7.eq(i8s // i6s) + m.d.comb += o8.eq(i8s % i6s) + m.d.comb += o9.eq(i6u // i8u) + m.d.comb += o10.eq(i6u % i8u) + m.d.comb += o11.eq(i6u // i8s) + m.d.comb += o12.eq(i6u % i8s) + m.d.comb += o13.eq(i6s // i8u) + m.d.comb += o14.eq(i6s % i8u) + m.d.comb += o15.eq(i6s // i8s) + m.d.comb += o16.eq(i6s % i8s) + nl = build_netlist(Fragment.get(m, None), [ + i8u, i8s, i6u, i6s, + o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i8s' 0.10:18) + (input 'i6u' 0.18:24) + (input 'i6s' 0.24:30) + (output 'o1' (cat 1.0:8 2'd0)) + (output 'o2' (cat 2.0:6 4'd0)) + (output 'o3' (cat 3.0:9 3.8)) + (output 'o4' (cat 4.0:6 4.5 4.5 4.5 4.5)) + (output 'o5' (cat 5.0:8 5.7 5.7)) + (output 'o6' (cat 6.0:6 4'd0)) + (output 'o7' (cat 7.0:9 7.8)) + (output 'o8' (cat 8.0:6 8.5 8.5 8.5 8.5)) + (output 'o9' (cat 9.0:6 4'd0)) + (output 'o10' (cat 10.0:8 2'd0)) + (output 'o11' (cat 11.0:7 11.6 11.6 11.6)) + (output 'o12' (cat 12.0:8 12.7 12.7)) + (output 'o13' (cat 13.0:6 13.5 13.5 13.5 13.5)) + (output 'o14' (cat 14.0:8 2'd0)) + (output 'o15' (cat 15.0:7 15.6 15.6 15.6)) + (output 'o16' (cat 16.0:8 16.7 16.7)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i8s' 10:18) + (input 'i6u' 18:24) + (input 'i6s' 24:30) + (output 'o1' (cat 1.0:8 2'd0)) + (output 'o2' (cat 2.0:6 4'd0)) + (output 'o3' (cat 3.0:9 3.8)) + (output 'o4' (cat 4.0:6 4.5 4.5 4.5 4.5)) + (output 'o5' (cat 5.0:8 5.7 5.7)) + (output 'o6' (cat 6.0:6 4'd0)) + (output 'o7' (cat 7.0:9 7.8)) + (output 'o8' (cat 8.0:6 8.5 8.5 8.5 8.5)) + (output 'o9' (cat 9.0:6 4'd0)) + (output 'o10' (cat 10.0:8 2'd0)) + (output 'o11' (cat 11.0:7 11.6 11.6 11.6)) + (output 'o12' (cat 12.0:8 12.7 12.7)) + (output 'o13' (cat 13.0:6 13.5 13.5 13.5 13.5)) + (output 'o14' (cat 14.0:8 2'd0)) + (output 'o15' (cat 15.0:7 15.6 15.6 15.6)) + (output 'o16' (cat 16.0:8 16.7 16.7)) + )) + (cell 1 0 (u// 0.2:10 (cat 0.18:24 2'd0))) + (cell 2 0 (u% 0.2:10 (cat 0.18:24 2'd0))) + (cell 3 0 (s// (cat 0.2:10 1'd0) (cat 0.24:30 0.29 0.29 0.29))) + (cell 4 0 (s% (cat 0.2:10 1'd0) (cat 0.24:30 0.29 0.29 0.29))) + (cell 5 0 (s// 0.10:18 (cat 0.18:24 2'd0))) + (cell 6 0 (s% 0.10:18 (cat 0.18:24 2'd0))) + (cell 7 0 (s// (cat 0.10:18 0.17) (cat 0.24:30 0.29 0.29 0.29))) + (cell 8 0 (s% 0.10:18 (cat 0.24:30 0.29 0.29))) + (cell 9 0 (u// (cat 0.18:24 2'd0) 0.2:10)) + (cell 10 0 (u% (cat 0.18:24 2'd0) 0.2:10)) + (cell 11 0 (s// (cat 0.18:24 2'd0) 0.10:18)) + (cell 12 0 (s% (cat 0.18:24 2'd0) 0.10:18)) + (cell 13 0 (s// (cat 0.24:30 0.29 0.29 0.29) (cat 0.2:10 1'd0))) + (cell 14 0 (s% (cat 0.24:30 0.29 0.29 0.29) (cat 0.2:10 1'd0))) + (cell 15 0 (s// (cat 0.24:30 0.29 0.29) 0.10:18)) + (cell 16 0 (s% (cat 0.24:30 0.29 0.29) 0.10:18)) + ) + """) + + def test_operator_binary_shift(self): + i8u = Signal(8) + i8s = Signal(signed(8)) + i4 = Signal(4) + o1 = Signal(32) + o2 = Signal(32) + o3 = Signal(12) + o4 = Signal(12) + m = Module() + m.d.comb += o1.eq(i8u << i4) + m.d.comb += o2.eq(i8s << i4) + m.d.comb += o3.eq(i8u >> i4) + m.d.comb += o4.eq(i8s >> i4) + nl = build_netlist(Fragment.get(m, None), [ + i8u, i8s, i4, o1, o2, o3, o4, + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i8s' 0.10:18) + (input 'i4' 0.18:22) + (output 'o1' (cat 1.0:23 9'd0)) + (output 'o2' (cat 2.0:23 2.22 2.22 2.22 2.22 2.22 2.22 2.22 2.22 2.22)) + (output 'o3' (cat 3.0:8 4'd0)) + (output 'o4' (cat 4.0:8 4.7 4.7 4.7 4.7)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i8s' 10:18) + (input 'i4' 18:22) + (output 'o1' (cat 1.0:23 9'd0)) + (output 'o2' (cat 2.0:23 2.22 2.22 2.22 2.22 2.22 2.22 2.22 2.22 2.22)) + (output 'o3' (cat 3.0:8 4'd0)) + (output 'o4' (cat 4.0:8 4.7 4.7 4.7 4.7)) + )) + (cell 1 0 (<< (cat 0.2:10 15'd0) 0.18:22)) + (cell 2 0 (<< (cat 0.10:18 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17 0.17) 0.18:22)) + (cell 3 0 (u>> 0.2:10 0.18:22)) + (cell 4 0 (s>> 0.10:18 0.18:22)) + ) + """) + + def test_operator_binary_eq(self): + i8u = Signal(8) + i9u = Signal(9) + i8s = Signal(signed(8)) + i9s = Signal(signed(9)) + o1 = Signal(2) + o2 = Signal(2) + o3 = Signal(2) + o4 = Signal(2) + o5 = Signal(2) + o6 = Signal(2) + o7 = Signal(2) + o8 = Signal(2) + o9 = Signal(2) + o10 = Signal(2) + o11 = Signal(2) + o12 = Signal(2) + o13 = Signal(2) + o14 = Signal(2) + o15 = Signal(2) + o16 = Signal(2) + m = Module() + m.d.comb += o1.eq(i8u == i8u) + m.d.comb += o2.eq(i8u != i9u) + m.d.comb += o3.eq(i8u != i8s) + m.d.comb += o4.eq(i8u == i9s) + m.d.comb += o5.eq(i9u != i8u) + m.d.comb += o6.eq(i9u == i9u) + m.d.comb += o7.eq(i9u == i8s) + m.d.comb += o8.eq(i9u != i9s) + m.d.comb += o9.eq(i8s != i8u) + m.d.comb += o10.eq(i8s == i9u) + m.d.comb += o11.eq(i8s == i8s) + m.d.comb += o12.eq(i8s != i9s) + m.d.comb += o13.eq(i9s == i8u) + m.d.comb += o14.eq(i9s != i9u) + m.d.comb += o15.eq(i9s != i8s) + m.d.comb += o16.eq(i9s == i9s) + nl = build_netlist(Fragment.get(m, None), [ + i8u, i9u, i8s, i9s, + o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i9u' 0.10:19) + (input 'i8s' 0.19:27) + (input 'i9s' 0.27:36) + (output 'o1' (cat 1.0 1'd0)) + (output 'o2' (cat 2.0 1'd0)) + (output 'o3' (cat 3.0 1'd0)) + (output 'o4' (cat 4.0 1'd0)) + (output 'o5' (cat 5.0 1'd0)) + (output 'o6' (cat 6.0 1'd0)) + (output 'o7' (cat 7.0 1'd0)) + (output 'o8' (cat 8.0 1'd0)) + (output 'o9' (cat 9.0 1'd0)) + (output 'o10' (cat 10.0 1'd0)) + (output 'o11' (cat 11.0 1'd0)) + (output 'o12' (cat 12.0 1'd0)) + (output 'o13' (cat 13.0 1'd0)) + (output 'o14' (cat 14.0 1'd0)) + (output 'o15' (cat 15.0 1'd0)) + (output 'o16' (cat 16.0 1'd0)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i9u' 10:19) + (input 'i8s' 19:27) + (input 'i9s' 27:36) + (output 'o1' (cat 1.0 1'd0)) + (output 'o2' (cat 2.0 1'd0)) + (output 'o3' (cat 3.0 1'd0)) + (output 'o4' (cat 4.0 1'd0)) + (output 'o5' (cat 5.0 1'd0)) + (output 'o6' (cat 6.0 1'd0)) + (output 'o7' (cat 7.0 1'd0)) + (output 'o8' (cat 8.0 1'd0)) + (output 'o9' (cat 9.0 1'd0)) + (output 'o10' (cat 10.0 1'd0)) + (output 'o11' (cat 11.0 1'd0)) + (output 'o12' (cat 12.0 1'd0)) + (output 'o13' (cat 13.0 1'd0)) + (output 'o14' (cat 14.0 1'd0)) + (output 'o15' (cat 15.0 1'd0)) + (output 'o16' (cat 16.0 1'd0)) + )) + (cell 1 0 (== 0.2:10 0.2:10)) + (cell 2 0 (!= (cat 0.2:10 1'd0) 0.10:19)) + (cell 3 0 (!= (cat 0.2:10 1'd0) (cat 0.19:27 0.26))) + (cell 4 0 (== (cat 0.2:10 1'd0) 0.27:36)) + (cell 5 0 (!= 0.10:19 (cat 0.2:10 1'd0))) + (cell 6 0 (== 0.10:19 0.10:19)) + (cell 7 0 (== (cat 0.10:19 1'd0) (cat 0.19:27 0.26 0.26))) + (cell 8 0 (!= (cat 0.10:19 1'd0) (cat 0.27:36 0.35))) + (cell 9 0 (!= (cat 0.19:27 0.26) (cat 0.2:10 1'd0))) + (cell 10 0 (== (cat 0.19:27 0.26 0.26) (cat 0.10:19 1'd0))) + (cell 11 0 (== 0.19:27 0.19:27)) + (cell 12 0 (!= (cat 0.19:27 0.26) 0.27:36)) + (cell 13 0 (== 0.27:36 (cat 0.2:10 1'd0))) + (cell 14 0 (!= (cat 0.27:36 0.35) (cat 0.10:19 1'd0))) + (cell 15 0 (!= 0.27:36 (cat 0.19:27 0.26))) + (cell 16 0 (== 0.27:36 0.27:36)) + ) + """) + + def test_operator_binary_ord(self): + i8u = Signal(8) + i9u = Signal(9) + i8s = Signal(signed(8)) + i9s = Signal(signed(9)) + o1 = Signal(2) + o2 = Signal(2) + o3 = Signal(2) + o4 = Signal(2) + o5 = Signal(2) + o6 = Signal(2) + o7 = Signal(2) + o8 = Signal(2) + o9 = Signal(2) + o10 = Signal(2) + o11 = Signal(2) + o12 = Signal(2) + o13 = Signal(2) + o14 = Signal(2) + o15 = Signal(2) + o16 = Signal(2) + m = Module() + m.d.comb += o1.eq(i8u < i8u) + m.d.comb += o2.eq(i8u < i9u) + m.d.comb += o3.eq(i8u < i8s) + m.d.comb += o4.eq(i8u < i9s) + m.d.comb += o5.eq(i9u > i8u) + m.d.comb += o6.eq(i9u > i9u) + m.d.comb += o7.eq(i9u > i8s) + m.d.comb += o8.eq(i9u > i9s) + m.d.comb += o9.eq(i8s <= i8u) + m.d.comb += o10.eq(i8s <= i9u) + m.d.comb += o11.eq(i8s <= i8s) + m.d.comb += o12.eq(i8s <= i9s) + m.d.comb += o13.eq(i9s >= i8u) + m.d.comb += o14.eq(i9s >= i9u) + m.d.comb += o15.eq(i9s >= i8s) + m.d.comb += o16.eq(i9s >= i9s) + nl = build_netlist(Fragment.get(m, None), [ + i8u, i9u, i8s, i9s, + o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i9u' 0.10:19) + (input 'i8s' 0.19:27) + (input 'i9s' 0.27:36) + (output 'o1' (cat 1.0 1'd0)) + (output 'o2' (cat 2.0 1'd0)) + (output 'o3' (cat 3.0 1'd0)) + (output 'o4' (cat 4.0 1'd0)) + (output 'o5' (cat 5.0 1'd0)) + (output 'o6' (cat 6.0 1'd0)) + (output 'o7' (cat 7.0 1'd0)) + (output 'o8' (cat 8.0 1'd0)) + (output 'o9' (cat 9.0 1'd0)) + (output 'o10' (cat 10.0 1'd0)) + (output 'o11' (cat 11.0 1'd0)) + (output 'o12' (cat 12.0 1'd0)) + (output 'o13' (cat 13.0 1'd0)) + (output 'o14' (cat 14.0 1'd0)) + (output 'o15' (cat 15.0 1'd0)) + (output 'o16' (cat 16.0 1'd0)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i9u' 10:19) + (input 'i8s' 19:27) + (input 'i9s' 27:36) + (output 'o1' (cat 1.0 1'd0)) + (output 'o2' (cat 2.0 1'd0)) + (output 'o3' (cat 3.0 1'd0)) + (output 'o4' (cat 4.0 1'd0)) + (output 'o5' (cat 5.0 1'd0)) + (output 'o6' (cat 6.0 1'd0)) + (output 'o7' (cat 7.0 1'd0)) + (output 'o8' (cat 8.0 1'd0)) + (output 'o9' (cat 9.0 1'd0)) + (output 'o10' (cat 10.0 1'd0)) + (output 'o11' (cat 11.0 1'd0)) + (output 'o12' (cat 12.0 1'd0)) + (output 'o13' (cat 13.0 1'd0)) + (output 'o14' (cat 14.0 1'd0)) + (output 'o15' (cat 15.0 1'd0)) + (output 'o16' (cat 16.0 1'd0)) + )) + (cell 1 0 (u< 0.2:10 0.2:10)) + (cell 2 0 (u< (cat 0.2:10 1'd0) 0.10:19)) + (cell 3 0 (s< (cat 0.2:10 1'd0) (cat 0.19:27 0.26))) + (cell 4 0 (s< (cat 0.2:10 1'd0) 0.27:36)) + (cell 5 0 (u> 0.10:19 (cat 0.2:10 1'd0))) + (cell 6 0 (u> 0.10:19 0.10:19)) + (cell 7 0 (s> (cat 0.10:19 1'd0) (cat 0.19:27 0.26 0.26))) + (cell 8 0 (s> (cat 0.10:19 1'd0) (cat 0.27:36 0.35))) + (cell 9 0 (s<= (cat 0.19:27 0.26) (cat 0.2:10 1'd0))) + (cell 10 0 (s<= (cat 0.19:27 0.26 0.26) (cat 0.10:19 1'd0))) + (cell 11 0 (s<= 0.19:27 0.19:27)) + (cell 12 0 (s<= (cat 0.19:27 0.26) 0.27:36)) + (cell 13 0 (s>= 0.27:36 (cat 0.2:10 1'd0))) + (cell 14 0 (s>= (cat 0.27:36 0.35) (cat 0.10:19 1'd0))) + (cell 15 0 (s>= 0.27:36 (cat 0.19:27 0.26))) + (cell 16 0 (s>= 0.27:36 0.27:36)) + ) + """) + + def test_operator_mux(self): + i8a = Signal(8) + i8b = Signal(8) + i1 = Signal() + i4 = Signal(4) + o1 = Signal(8) + o2 = Signal(8) + m = Module() + m.d.comb += o1.eq(Mux(i1, i8a, i8b)) + m.d.comb += o2.eq(Mux(i4, i8a, i8b)) + nl = build_netlist(Fragment.get(m, None), [i8a, i8b, i1, i4, o1, o2]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8a' 0.2:10) + (input 'i8b' 0.10:18) + (input 'i1' 0.18) + (input 'i4' 0.19:23) + (output 'o1' 1.0:8) + (output 'o2' 3.0:8) + ) + (cell 0 0 (top + (input 'i8a' 2:10) + (input 'i8b' 10:18) + (input 'i1' 18:19) + (input 'i4' 19:23) + (output 'o1' 1.0:8) + (output 'o2' 3.0:8) + )) + (cell 1 0 (m 0.18 0.2:10 0.10:18)) + (cell 2 0 (b 0.19:23)) + (cell 3 0 (m 2.0 0.2:10 0.10:18)) + ) + """) + + def test_slice(self): + i = Signal(8) + o = Signal(8) + m = Module() + m.d.comb += o.eq(i[2:5]) + nl = build_netlist(Fragment.get(m, None), [i, o]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i' 0.2:10) + (output 'o' (cat 0.4:7 5'd0)) + ) + (cell 0 0 (top + (input 'i' 2:10) + (output 'o' (cat 0.4:7 5'd0)) + )) + ) + """) + + def test_part(self): + i8u = Signal(8) + i8s = Signal(signed(8)) + i4 = Signal(4) + o1 = Signal(4) + o2 = Signal(4) + o3 = Signal(4) + o4 = Signal(4) + m = Module() + m.d.comb += o1.eq(i8u.bit_select(i4, 3)) + m.d.comb += o2.eq(i8s.bit_select(i4, 3)) + m.d.comb += o3.eq(i8u.word_select(i4, 3)) + m.d.comb += o4.eq(i8s.word_select(i4, 3)) + nl = build_netlist(Fragment.get(m, None), [i8u, i8s, i4, o1, o2, o3, o4]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8u' 0.2:10) + (input 'i8s' 0.10:18) + (input 'i4' 0.18:22) + (output 'o1' (cat 1.0:3 1'd0)) + (output 'o2' (cat 2.0:3 1'd0)) + (output 'o3' (cat 3.0:3 1'd0)) + (output 'o4' (cat 4.0:3 1'd0)) + ) + (cell 0 0 (top + (input 'i8u' 2:10) + (input 'i8s' 10:18) + (input 'i4' 18:22) + (output 'o1' (cat 1.0:3 1'd0)) + (output 'o2' (cat 2.0:3 1'd0)) + (output 'o3' (cat 3.0:3 1'd0)) + (output 'o4' (cat 4.0:3 1'd0)) + )) + (cell 1 0 (part 0.2:10 unsigned 0.18:22 3 1)) + (cell 2 0 (part 0.10:18 signed 0.18:22 3 1)) + (cell 3 0 (part 0.2:10 unsigned 0.18:22 3 3)) + (cell 4 0 (part 0.10:18 signed 0.18:22 3 3)) + ) + """) + + def test_cat(self): + i1 = Signal() + i2 = Signal(8) + i3 = Signal(3) + o = Signal(16) + m = Module() + m.d.comb += o.eq(Cat(i1, i2, i3)) + nl = build_netlist(Fragment.get(m, None), [i1, i2, i3, o]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i1' 0.2) + (input 'i2' 0.3:11) + (input 'i3' 0.11:14) + (output 'o' (cat 0.2:14 4'd0)) + ) + (cell 0 0 (top + (input 'i1' 2:3) + (input 'i2' 3:11) + (input 'i3' 11:14) + (output 'o' (cat 0.2:14 4'd0)) + )) + ) + """) + + def test_arrayproxy(self): + i8ua = Signal(8) + i8ub = Signal(8) + i8uc = Signal(8) + i8sa = Signal(signed(8)) + i8sb = Signal(signed(8)) + i8sc = Signal(signed(8)) + i4 = Signal(4) + o1 = Signal(10) + o2 = Signal(10) + o3 = Signal(10) + o4 = Signal(10) + m = Module() + m.d.comb += o1.eq(Array([i8ua, i8ub, i8uc])[i4]) + m.d.comb += o2.eq(Array([i8ua, i8ub, i8sc])[i4]) + m.d.comb += o3.eq(Array([i8sa, i8sb, i8sc])[i4]) + m.d.comb += o4.eq(Array([i8sa, i8sb, i4])[i4]) + nl = build_netlist(Fragment.get(m, None), [i8ua, i8ub, i8uc, i8sa, i8sb, i8sc, i4, o1, o2, o3, o4]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i8ua' 0.2:10) + (input 'i8ub' 0.10:18) + (input 'i8uc' 0.18:26) + (input 'i8sa' 0.26:34) + (input 'i8sb' 0.34:42) + (input 'i8sc' 0.42:50) + (input 'i4' 0.50:54) + (output 'o1' (cat 1.0:8 2'd0)) + (output 'o2' (cat 2.0:9 2.8)) + (output 'o3' (cat 3.0:8 3.7 3.7)) + (output 'o4' (cat 4.0:8 4.7 4.7)) + ) + (cell 0 0 (top + (input 'i8ua' 2:10) + (input 'i8ub' 10:18) + (input 'i8uc' 18:26) + (input 'i8sa' 26:34) + (input 'i8sb' 34:42) + (input 'i8sc' 42:50) + (input 'i4' 50:54) + (output 'o1' (cat 1.0:8 2'd0)) + (output 'o2' (cat 2.0:9 2.8)) + (output 'o3' (cat 3.0:8 3.7 3.7)) + (output 'o4' (cat 4.0:8 4.7 4.7)) + )) + (cell 1 0 (array_mux 8 0.50:54 (0.2:10 0.10:18 0.18:26))) + (cell 2 0 (array_mux 9 0.50:54 ((cat 0.2:10 1'd0) (cat 0.10:18 1'd0) (cat 0.42:50 0.49)))) + (cell 3 0 (array_mux 8 0.50:54 (0.26:34 0.34:42 0.42:50))) + (cell 4 0 (array_mux 8 0.50:54 (0.26:34 0.34:42 (cat 0.50:54 4'd0)))) + ) + """) + + def test_anyvalue(self): + o1 = Signal(12) + o2 = Signal(12) + o3 = Signal(12) + o4 = Signal(12) + m = Module() + m.d.comb += o1.eq(AnyConst(8)) + m.d.comb += o2.eq(AnyConst(signed(8))) + m.d.comb += o3.eq(AnySeq(8)) + m.d.comb += o4.eq(AnySeq(signed(8))) + nl = build_netlist(Fragment.get(m, None), [o1, o2, o3, o4]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (output 'o1' (cat 1.0:8 4'd0)) + (output 'o2' (cat 2.0:8 2.7 2.7 2.7 2.7)) + (output 'o3' (cat 3.0:8 4'd0)) + (output 'o4' (cat 4.0:8 4.7 4.7 4.7 4.7)) + ) + (cell 0 0 (top + (output 'o1' (cat 1.0:8 4'd0)) + (output 'o2' (cat 2.0:8 2.7 2.7 2.7 2.7)) + (output 'o3' (cat 3.0:8 4'd0)) + (output 'o4' (cat 4.0:8 4.7 4.7 4.7 4.7)) + )) + (cell 1 0 (anyconst 8)) + (cell 2 0 (anyconst 8)) + (cell 3 0 (anyseq 8)) + (cell 4 0 (anyseq 8)) + ) + """) + + def test_initial(self): + o1 = Signal(12) + m = Module() + m.d.comb += o1.eq(Initial()) + nl = build_netlist(Fragment.get(m, None), [o1]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (output 'o1' (cat 1.0 11'd0)) + ) + (cell 0 0 (top + (output 'o1' (cat 1.0 11'd0)) + )) + (cell 1 0 (initial)) + ) + """) + +class SwitchTestCase(FHDLTestCase): + def test_comb(self): + o1 = Signal(8) + o2 = Signal(8, init=123) + i = Signal(4) + i2 = Signal(4) + m = Module() + with m.If(i[0]): + m.d.comb += o1.eq(1) + with m.Elif(i[1]): + m.d.comb += o1[2:4].eq(2) + m.d.comb += o2.eq(3) + with m.If(i[2]): + with m.Switch(i2): + with m.Case(1): + m.d.comb += o2.eq(4) + with m.Case(2, 4): + m.d.comb += o2.eq(5) + with m.Case('11--'): + m.d.comb += o2.eq(6) + with m.If(i[3]): + m.d.comb += o1.eq(7) + nl = build_netlist(Fragment.get(m, None), [i, i2, o1, o2]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i' 0.2:6) + (input 'i2' 0.6:10) + (output 'o1' 12.0:8) + (output 'o2' 13.0:8) + ) + (cell 0 0 (top + (input 'i' 2:6) + (input 'i2' 6:10) + (output 'o1' 12.0:8) + (output 'o2' 13.0:8) + )) + (cell 1 0 (matches 0.2:4 -1)) + (cell 2 0 (matches 0.2:4 1-)) + (cell 3 0 (priority_match 1 (cat 1.0 2.0))) + (cell 4 0 (matches 0.4 1)) + (cell 5 0 (priority_match 1 4.0)) + (cell 6 0 (matches 0.6:10 0001)) + (cell 7 0 (matches 0.6:10 0010 0100)) + (cell 8 0 (matches 0.6:10 11--)) + (cell 9 0 (priority_match 5.0 (cat 6.0 7.0 8.0))) + (cell 10 0 (matches 0.5 1)) + (cell 11 0 (priority_match 9.2 10.0)) + (cell 12 0 (assignment_list 8'd0 + (3.0 0:8 8'd1) + (3.1 2:4 2'd2) + (11.0 0:8 8'd7) + )) + (cell 13 0 (assignment_list 8'd123 + (3.1 0:8 8'd3) + (9.0 0:8 8'd4) + (9.1 0:8 8'd5) + (9.2 0:8 8'd6) + )) + ) + """) + + def test_sync(self): + o1 = Signal(8, reset_less=True) + o2 = Signal(8, init=123) + o3 = Signal(8, init=45, reset_less=True) + o4 = Signal(8, init=67) + o5 = Signal(8, init=89) + i1 = Signal(8) + i2 = Signal() + m = Module() + m.domains.a = ClockDomain() + m.domains.b = ClockDomain(async_reset=True) + m.domains.c = ClockDomain(reset_less=True, clk_edge="neg") + with m.If(i2): + m.d.a += o1.eq(i1) + m.d.a += o2.eq(i1) + m.d.b += o3.eq(i1) + m.d.b += o4.eq(i1) + m.d.c += o5.eq(i1) + nl = build_netlist(Fragment.get(m, None), [ + i1, i2, o1, o2, o3, o4, o5, + ClockSignal("a"), ResetSignal("a"), + ClockSignal("b"), ResetSignal("b"), + ClockSignal("c"), + ]) + # TODO: two inefficiencies in NIR emitter: + # - _ignore_resets inserts useless redundant Switch for async reset + # - matches and priority_match duplicated between clock domains — add cache? + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i1' 0.2:10) + (input 'i2' 0.10) + (input 'a_clk' 0.11) + (input 'a_rst' 0.12) + (input 'b_clk' 0.13) + (input 'b_rst' 0.14) + (input 'c_clk' 0.15) + (output 'o1' 12.0:8) + (output 'o2' 14.0:8) + (output 'o3' 16.0:8) + (output 'o4' 18.0:8) + (output 'o5' 20.0:8) + ) + (cell 0 0 (top + (input 'i1' 2:10) + (input 'i2' 10:11) + (input 'a_clk' 11:12) + (input 'a_rst' 12:13) + (input 'b_clk' 13:14) + (input 'b_rst' 14:15) + (input 'c_clk' 15:16) + (output 'o1' 12.0:8) + (output 'o2' 14.0:8) + (output 'o3' 16.0:8) + (output 'o4' 18.0:8) + (output 'o5' 20.0:8) + )) + (cell 1 0 (matches 0.10 1)) + (cell 2 0 (priority_match 1 1.0)) + (cell 3 0 (matches 0.12 1)) + (cell 4 0 (priority_match 1 3.0)) + (cell 5 0 (matches 0.10 1)) + (cell 6 0 (priority_match 1 5.0)) + (cell 7 0 (matches 0.14 1)) + (cell 8 0 (priority_match 1 7.0)) + (cell 9 0 (matches 0.10 1)) + (cell 10 0 (priority_match 1 9.0)) + (cell 11 0 (assignment_list 12.0:8 (2.0 0:8 0.2:10))) + (cell 12 0 (flipflop 11.0:8 0 pos 0.11 0)) + (cell 13 0 (assignment_list 14.0:8 (2.0 0:8 0.2:10) (4.0 0:8 8'd123))) + (cell 14 0 (flipflop 13.0:8 123 pos 0.11 0)) + (cell 15 0 (assignment_list 16.0:8 (6.0 0:8 0.2:10))) + (cell 16 0 (flipflop 15.0:8 45 pos 0.13 0)) + (cell 17 0 (assignment_list 18.0:8 (6.0 0:8 0.2:10) (8.0 0:8 8'd67))) + (cell 18 0 (flipflop 17.0:8 67 pos 0.13 0.14)) + (cell 19 0 (assignment_list 20.0:8 (10.0 0:8 0.2:10))) + (cell 20 0 (flipflop 19.0:8 89 neg 0.15 0)) + ) + """) + + def test_assert(self): + m = Module() + i = Signal(6) + m.domains.a = ClockDomain() + m.domains.b = ClockDomain(async_reset=True) + m.domains.c = ClockDomain(reset_less=True, clk_edge="neg") + with m.If(i[5]): + m.d.comb += Assert(i[0]) + m.d.comb += Assume(i[1], name="a") + m.d.a += Assert(i[2]) + m.d.b += Assume(i[3], name="b") + m.d.c += Cover(i[4], name="c") + m.d.comb += Cover(i, name="d") + nl = build_netlist(Fragment.get(m, None), [ + i, + ClockSignal("a"), ResetSignal("a"), + ClockSignal("b"), ResetSignal("b"), + ClockSignal("c"), + ]) + self.assertRepr(nl, """ + ( + (module 0 None ('top') + (input 'i' 0.2:8) + (input 'a_clk' 0.8) + (input 'a_rst' 0.9) + (input 'b_clk' 0.10) + (input 'b_rst' 0.11) + (input 'c_clk' 0.12) + ) + (cell 0 0 (top + (input 'i' 2:8) + (input 'a_clk' 8:9) + (input 'a_rst' 9:10) + (input 'b_clk' 10:11) + (input 'b_rst' 11:12) + (input 'c_clk' 12:13) + )) + (cell 1 0 (matches 0.7 1)) + (cell 2 0 (priority_match 1 1.0)) + (cell 3 0 (assignment_list 1'd0 (2.0 0:1 1'd1))) + (cell 4 0 (assert None 0.2 3.0)) + (cell 5 0 (assignment_list 1'd0 (2.0 0:1 1'd1))) + (cell 6 0 (assume 'a' 0.3 5.0)) + (cell 7 0 (b 0.2:8)) + (cell 8 0 (assignment_list 1'd0 (2.0 0:1 1'd1))) + (cell 9 0 (cover 'd' 7.0 8.0)) + (cell 10 0 (matches 0.7 1)) + (cell 11 0 (priority_match 1 10.0)) + (cell 12 0 (assignment_list 1'd0 (11.0 0:1 1'd1))) + (cell 13 0 (assert None 0.4 12.0 pos 0.8)) + (cell 14 0 (matches 0.7 1)) + (cell 15 0 (priority_match 1 14.0)) + (cell 16 0 (assignment_list 1'd0 (15.0 0:1 1'd1))) + (cell 17 0 (assume 'b' 0.5 16.0 pos 0.10)) + (cell 18 0 (matches 0.7 1)) + (cell 19 0 (priority_match 1 18.0)) + (cell 20 0 (assignment_list 1'd0 (19.0 0:1 1'd1))) + (cell 21 0 (cover 'c' 0.6 20.0 neg 0.12)) + + + ) + """)