From 79ba91be79de25fadbb1b999fc3e4ecdbbc219ab Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Thu, 1 Nov 2018 16:36:37 -0700 Subject: [PATCH 01/13] Add initial support for assignment operator --- magma/__init__.py | 1 + magma/circuit.py | 27 ++++++++++++++++++++++++ tests/test_operators.py | 46 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/magma/__init__.py b/magma/__init__.py index c0276817b7..de26926927 100644 --- a/magma/__init__.py +++ b/magma/__init__.py @@ -58,3 +58,4 @@ def set_mantle_target(t): from .backend.util import set_codegen_debug_info from .enum import Enum +import magma.util diff --git a/magma/circuit.py b/magma/circuit.py index 7add110875..76b7a1ca41 100644 --- a/magma/circuit.py +++ b/magma/circuit.py @@ -93,6 +93,19 @@ def __new__(metacls, name, bases, dct): return cls + def __setattr__(cls, key, value): + # First check if interface has been set, since early in the metaclass + # pipeline we set attributes on the class, so we just use default + # semantics for those statements + if not getattr(cls, "ports_set", False) or key not in cls.interface: + super().__setattr__(key, value) + else: + port = cls.interface[key] + if port.isoutput(): + raise TypeError(f"Cannot assign to input port of definition: {port.debug_name}") + # Error handling deferred to wiring logic + port.wire(value) + def __call__(cls, *largs, **kwargs): #print('CircuitKind call:', largs, kwargs) debug_info = get_callee_frame_info() @@ -207,6 +220,19 @@ def _repr_html_(self): def __getitem__(self, key): return self.interface[key] + def __setattr__(self, key, value): + # First check if interface has been set, since early in the metaclass + # pipeline we set attributes on the class, so we just use default + # semantics for those statements + if self.interface is None or key not in self.interface: + object.__setattr__(self, key, value) + else: + port = self.interface[key] + if port.isoutput(): + raise TypeError(f"Cannot assign to output port of instance: {port.debug_name}") + # Error handling deferred to wiring logic + port.wire(value) + # wire a list of outputs to the circuit's inputs def wireoutputs(self, outputs, debug_info): inputs = self.interface.inputs() @@ -452,6 +478,7 @@ def __new__(metacls, name, bases, dct): # instantiate interface self.interface = self.IO(defn=self, renamed_ports=dct["renamed_ports"]) setports(self, self.interface.ports) + self.ports_set = True # create circuit definition if hasattr(self, 'definition'): diff --git a/tests/test_operators.py b/tests/test_operators.py index 583966382c..22457b1cde 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -1,5 +1,7 @@ import magma as m from magma.operators import MantleImportError +from common import DeclareAnd +import pytest def test_error(): @@ -10,3 +12,47 @@ def test_error(): "Operator should throw an error since mantle is not imported" except MantleImportError: pass + + +@pytest.mark.parametrize("width", [None, 3]) +@pytest.mark.parametrize("output", ["verilog", "coreir"]) +def test_assign(width, output): + T = m.util.BitOrBits(width) + name = f"test_assign_operator_{width}_{output}" + circ = m.DefineCircuit(name, "a", m.In(T), "b", m.In(T), + "c", m.Out(T)) + and2 = DeclareAnd(width)() + and2.I0 = circ.a + and2.I1 = circ.b + circ.c = and2.O + m.EndDefine() + + m.compile(f"build/{name}", circ, output) + + +@pytest.mark.parametrize("width", [None, 3]) +def test_assign_error_0(width): + T = m.util.BitOrBits(width) + name = f"test_assign_operator_{width}" + circ = m.DefineCircuit(name, "a", m.In(T), "b", m.In(T), + "c", m.Out(T)) + and2 = DeclareAnd(width)() + try: + and2.O = circ.a + assert False, "Should raise type error" + except TypeError as e: + assert str(e) == f"Cannot assign to output port of instance: test_assign_operator_{width}.And{width}_inst0.O" + + +@pytest.mark.parametrize("width", [None, 3]) +def test_assign_error_1(width): + T = m.util.BitOrBits(width) + name = f"test_assign_operator_{width}" + circ = m.DefineCircuit(name, "a", m.In(T), "b", m.In(T), + "c", m.Out(T)) + and2 = DeclareAnd(width)() + try: + circ.a = and2.O + assert False, "Should raise type error" + except TypeError as e: + assert str(e) == f"Cannot assign to input port of definition: test_assign_operator_{width}.a" From 6d8634e445f2cf7995ab44271a9fdec5eb8fd0fd Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Thu, 1 Nov 2018 16:44:33 -0700 Subject: [PATCH 02/13] Update docs for assignment --- docs/operators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operators.md b/docs/operators.md index d06c0bab3e..6aaab23227 100644 --- a/docs/operators.md +++ b/docs/operators.md @@ -46,7 +46,7 @@ Language](https://ieeexplore.ieee.org/document/8299595) (page 256, Table 11-1 #### Assignment | Verilog Operator | Magma Operator | Types | Context | Comments | |------------------|----------------| ----- | ------- | -------- | -| `=` | `m.wire`, **TODO (=)** | Any | All | Assignment cannot be overloaded for arbitrary Python variables, so in general we must use `m.wire`. There are plans to add support for assignment to attributes of magma types, such as `reg.I = io.I`. | +| `=` | `m.wire`, `=` (only when setting attributes on circuit definitions or circuit instances) | Any | All | Assignment cannot be overloaded for arbitrary Python variables, so in general we must use `m.wire`. We have added preliminary for assignment to attributes of magma circuit definitions and instances, e.g. `reg.I = io.I`, but remember that assigning to Python variables, e.g. `I = io.I` does not correspond to wiring. | | `+=`, `-=`, `/=`, `*=` | `None` | None | All | Again, unsupported due to the lack of support for overloading assignment. May be added in the future for attributes of magma types | | `%=` | `None` | None | All | See above | | `&=`, `|=`, `^=` | `None` | None | All | See above | From ef1f3ff7ed314bbb6693e9f5a77c3f299d38eb06 Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Thu, 1 Nov 2018 16:45:28 -0700 Subject: [PATCH 03/13] Remove old comments --- magma/circuit.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/magma/circuit.py b/magma/circuit.py index 76b7a1ca41..db18b6503e 100644 --- a/magma/circuit.py +++ b/magma/circuit.py @@ -103,7 +103,6 @@ def __setattr__(cls, key, value): port = cls.interface[key] if port.isoutput(): raise TypeError(f"Cannot assign to input port of definition: {port.debug_name}") - # Error handling deferred to wiring logic port.wire(value) def __call__(cls, *largs, **kwargs): @@ -230,7 +229,6 @@ def __setattr__(self, key, value): port = self.interface[key] if port.isoutput(): raise TypeError(f"Cannot assign to output port of instance: {port.debug_name}") - # Error handling deferred to wiring logic port.wire(value) # wire a list of outputs to the circuit's inputs From 036ed3bfd28d13ef6bded3cc9583117b05245f38 Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Thu, 1 Nov 2018 16:50:01 -0700 Subject: [PATCH 04/13] Add note about aug assignments --- docs/operators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operators.md b/docs/operators.md index 6aaab23227..41ce8c168f 100644 --- a/docs/operators.md +++ b/docs/operators.md @@ -47,7 +47,7 @@ Language](https://ieeexplore.ieee.org/document/8299595) (page 256, Table 11-1 | Verilog Operator | Magma Operator | Types | Context | Comments | |------------------|----------------| ----- | ------- | -------- | | `=` | `m.wire`, `=` (only when setting attributes on circuit definitions or circuit instances) | Any | All | Assignment cannot be overloaded for arbitrary Python variables, so in general we must use `m.wire`. We have added preliminary for assignment to attributes of magma circuit definitions and instances, e.g. `reg.I = io.I`, but remember that assigning to Python variables, e.g. `I = io.I` does not correspond to wiring. | -| `+=`, `-=`, `/=`, `*=` | `None` | None | All | Again, unsupported due to the lack of support for overloading assignment. May be added in the future for attributes of magma types | +| `+=`, `-=`, `/=`, `*=` | `None` | None | All | Support is not planned for these operators because magma cannot provide a clean semantics for them. Assignment only works for inputs to circuit instances and outputs of circuit definitions. AugAssign operators imply a value that is used both as an input an output. For example, `inst.a +=1` would imply a is an output that feeds into binary add with 1, while also an input which consumes the result of the binary add. | | `%=` | `None` | None | All | See above | | `&=`, `|=`, `^=` | `None` | None | All | See above | | `>>=`, `<<=` | `None` | None | All | See above | From 48e118231a2f14ac669572147d37e786b33950a5 Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Sat, 3 Nov 2018 08:33:31 -0700 Subject: [PATCH 05/13] Add missing file --- magma/util.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 magma/util.py diff --git a/magma/util.py b/magma/util.py new file mode 100644 index 0000000000..35de69414f --- /dev/null +++ b/magma/util.py @@ -0,0 +1,9 @@ +import magma as m + + +def BitOrBits(width): + if width is None: + return m.Bit + if not isinstance(width, int): + raise ValueError(f"Expected width to be None or int, got {width}") + return m.Bits(width) From a6939315eaf2fda0b68a349ad4c77643c45bc850 Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Sat, 3 Nov 2018 08:38:24 -0700 Subject: [PATCH 06/13] Add missing common.py --- tests/common.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/common.py diff --git a/tests/common.py b/tests/common.py new file mode 100644 index 0000000000..559c478591 --- /dev/null +++ b/tests/common.py @@ -0,0 +1,7 @@ +import magma as m + + +def DeclareAnd(width): + T = m.util.BitOrBits(width) + return m.DeclareCircuit(f'And{width}', "I0", m.In(T), "I1", m.In(T), + "O", m.Out(T)) From 0cf86f87c3e777bbba4e05f5c4d2273e4ca61deb Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Sat, 3 Nov 2018 08:56:20 -0700 Subject: [PATCH 07/13] Improve ports_set logic --- magma/circuit.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/magma/circuit.py b/magma/circuit.py index db18b6503e..0512f81054 100644 --- a/magma/circuit.py +++ b/magma/circuit.py @@ -46,11 +46,13 @@ def circuit_to_html(cls): # create an attribute for each port def setports(self, ports): + self.ports_set = False #print('setports', ports) for name, port in ports.items(): #print(self, port, type(port)) if isinstance(name, str): setattr(self, name, port) + self.ports_set = True # # Metaclass for creating circuits @@ -223,7 +225,9 @@ def __setattr__(self, key, value): # First check if interface has been set, since early in the metaclass # pipeline we set attributes on the class, so we just use default # semantics for those statements - if self.interface is None or key not in self.interface: + if not getattr(self, "ports_set", False) or \ + getattr(self, "interface", None) is None or \ + key not in self.interface: object.__setattr__(self, key, value) else: port = self.interface[key] @@ -476,7 +480,6 @@ def __new__(metacls, name, bases, dct): # instantiate interface self.interface = self.IO(defn=self, renamed_ports=dct["renamed_ports"]) setports(self, self.interface.ports) - self.ports_set = True # create circuit definition if hasattr(self, 'definition'): From 8c0a1fbbe1b73b538325a5658c70829615eefba0 Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Sat, 3 Nov 2018 08:56:33 -0700 Subject: [PATCH 08/13] Fixup trailing lines in gold files for upstream coreir changes --- tests/gold/basic_function_call.json | 2 +- tests/gold/if_statement_basic.json | 2 +- tests/gold/if_statement_nested.json | 2 +- tests/gold/return_magma_named_tuple.json | 2 +- tests/gold/return_magma_tuple.json | 2 +- tests/gold/return_py_tuple.json | 2 +- tests/gold/simple_circuit_1.json | 2 +- tests/gold/ternary.json | 2 +- tests/gold/ternary_nested.json | 2 +- tests/gold/ternary_nested2.json | 2 +- tests/gold/test_map_circuit.json | 2 +- tests/test_circuit/gold/test_add8cin.json | 2 +- .../gold/test_anon_value_Array(2,Bit).json | 2 +- tests/test_circuit/gold/test_anon_value_Bit.json | 2 +- .../gold/test_anon_value_Bits(2).json | 2 +- .../gold/test_anon_value_Tuple(x=Bit,y=Bit).json | 2 +- tests/test_circuit/gold/test_simple_def.json | 2 +- .../test_circuit/gold/test_simple_def_class.json | 2 +- tests/test_coreir/gold/linker_test0.json | 2 +- tests/test_coreir/gold/test_array_nesting.json | 2 +- .../gold/test_multi_direction_tuple.json | 2 +- .../test_multi_direction_tuple_instance.json | 2 +- tests/test_coreir/gold/test_nesting.json | 2 +- tests/test_coreir/mapParallel_test.json | 2 +- tests/test_coreir/mapParallel_test_gold.json | 2 +- tests/test_type/gold/test_enum.v | 6 +++--- tests/test_type/gold/test_enum_max_value.v | 6 +++--- tests/test_type/gold/test_new_types.json | 2 +- tests/test_type/gold/test_new_types.v | 16 ++++++++-------- tests/test_type/test_const_wire_golden.json | 2 +- .../test_coreir_wrap_golden_AsyncReset.json | 2 +- .../test_type/test_coreir_wrap_golden_Clock.json | 2 +- 32 files changed, 43 insertions(+), 43 deletions(-) diff --git a/tests/gold/basic_function_call.json b/tests/gold/basic_function_call.json index d3a20dd914..a923036806 100644 --- a/tests/gold/basic_function_call.json +++ b/tests/gold/basic_function_call.json @@ -48,4 +48,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/if_statement_basic.json b/tests/gold/if_statement_basic.json index b7af946737..f6123f4106 100644 --- a/tests/gold/if_statement_basic.json +++ b/tests/gold/if_statement_basic.json @@ -31,4 +31,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/if_statement_nested.json b/tests/gold/if_statement_nested.json index 1b1e74de62..d8639d87a6 100644 --- a/tests/gold/if_statement_nested.json +++ b/tests/gold/if_statement_nested.json @@ -43,4 +43,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/return_magma_named_tuple.json b/tests/gold/return_magma_named_tuple.json index b1419f121b..05bfb3c872 100644 --- a/tests/gold/return_magma_named_tuple.json +++ b/tests/gold/return_magma_named_tuple.json @@ -15,4 +15,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/return_magma_tuple.json b/tests/gold/return_magma_tuple.json index d1b655b9cd..595a787c68 100644 --- a/tests/gold/return_magma_tuple.json +++ b/tests/gold/return_magma_tuple.json @@ -15,4 +15,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/return_py_tuple.json b/tests/gold/return_py_tuple.json index 62ebf20d62..99895667dc 100644 --- a/tests/gold/return_py_tuple.json +++ b/tests/gold/return_py_tuple.json @@ -16,4 +16,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/simple_circuit_1.json b/tests/gold/simple_circuit_1.json index 463c6bb0a8..340dafb231 100644 --- a/tests/gold/simple_circuit_1.json +++ b/tests/gold/simple_circuit_1.json @@ -74,4 +74,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/ternary.json b/tests/gold/ternary.json index c338a78ee3..209da6ef7d 100644 --- a/tests/gold/ternary.json +++ b/tests/gold/ternary.json @@ -31,4 +31,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/ternary_nested.json b/tests/gold/ternary_nested.json index 551ab91e27..28dbfa9c96 100644 --- a/tests/gold/ternary_nested.json +++ b/tests/gold/ternary_nested.json @@ -37,4 +37,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/ternary_nested2.json b/tests/gold/ternary_nested2.json index 363798e5b5..6f6705e4fe 100644 --- a/tests/gold/ternary_nested2.json +++ b/tests/gold/ternary_nested2.json @@ -37,4 +37,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/gold/test_map_circuit.json b/tests/gold/test_map_circuit.json index 1e13d6dbe4..89a5f48b19 100644 --- a/tests/gold/test_map_circuit.json +++ b/tests/gold/test_map_circuit.json @@ -95,4 +95,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_circuit/gold/test_add8cin.json b/tests/test_circuit/gold/test_add8cin.json index 3c5c941ff2..e6f90da810 100644 --- a/tests/test_circuit/gold/test_add8cin.json +++ b/tests/test_circuit/gold/test_add8cin.json @@ -60,4 +60,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_circuit/gold/test_anon_value_Array(2,Bit).json b/tests/test_circuit/gold/test_anon_value_Array(2,Bit).json index aa5d82efba..430357bdda 100644 --- a/tests/test_circuit/gold/test_anon_value_Array(2,Bit).json +++ b/tests/test_circuit/gold/test_anon_value_Array(2,Bit).json @@ -29,4 +29,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_circuit/gold/test_anon_value_Bit.json b/tests/test_circuit/gold/test_anon_value_Bit.json index dab48b1aec..d08f37d5be 100644 --- a/tests/test_circuit/gold/test_anon_value_Bit.json +++ b/tests/test_circuit/gold/test_anon_value_Bit.json @@ -29,4 +29,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_circuit/gold/test_anon_value_Bits(2).json b/tests/test_circuit/gold/test_anon_value_Bits(2).json index aa5d82efba..430357bdda 100644 --- a/tests/test_circuit/gold/test_anon_value_Bits(2).json +++ b/tests/test_circuit/gold/test_anon_value_Bits(2).json @@ -29,4 +29,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_circuit/gold/test_anon_value_Tuple(x=Bit,y=Bit).json b/tests/test_circuit/gold/test_anon_value_Tuple(x=Bit,y=Bit).json index 5f07b93d51..a98bdada87 100644 --- a/tests/test_circuit/gold/test_anon_value_Tuple(x=Bit,y=Bit).json +++ b/tests/test_circuit/gold/test_anon_value_Tuple(x=Bit,y=Bit).json @@ -29,4 +29,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_circuit/gold/test_simple_def.json b/tests/test_circuit/gold/test_simple_def.json index eede176d41..ee50cf9e45 100644 --- a/tests/test_circuit/gold/test_simple_def.json +++ b/tests/test_circuit/gold/test_simple_def.json @@ -29,4 +29,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_circuit/gold/test_simple_def_class.json b/tests/test_circuit/gold/test_simple_def_class.json index 93e12a98b5..66116731f3 100644 --- a/tests/test_circuit/gold/test_simple_def_class.json +++ b/tests/test_circuit/gold/test_simple_def_class.json @@ -29,4 +29,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_coreir/gold/linker_test0.json b/tests/test_coreir/gold/linker_test0.json index 113c32b2bd..6adaf5cf1d 100644 --- a/tests/test_coreir/gold/linker_test0.json +++ b/tests/test_coreir/gold/linker_test0.json @@ -23,4 +23,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_coreir/gold/test_array_nesting.json b/tests/test_coreir/gold/test_array_nesting.json index 0b589d74eb..70609f58a7 100644 --- a/tests/test_coreir/gold/test_array_nesting.json +++ b/tests/test_coreir/gold/test_array_nesting.json @@ -22,4 +22,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_coreir/gold/test_multi_direction_tuple.json b/tests/test_coreir/gold/test_multi_direction_tuple.json index f1ec8990f0..2246403de5 100644 --- a/tests/test_coreir/gold/test_multi_direction_tuple.json +++ b/tests/test_coreir/gold/test_multi_direction_tuple.json @@ -13,4 +13,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_coreir/gold/test_multi_direction_tuple_instance.json b/tests/test_coreir/gold/test_multi_direction_tuple_instance.json index f20bf9a42a..7fdd054e02 100644 --- a/tests/test_coreir/gold/test_multi_direction_tuple_instance.json +++ b/tests/test_coreir/gold/test_multi_direction_tuple_instance.json @@ -27,4 +27,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_coreir/gold/test_nesting.json b/tests/test_coreir/gold/test_nesting.json index 80de254c4a..b6a21bb381 100644 --- a/tests/test_coreir/gold/test_nesting.json +++ b/tests/test_coreir/gold/test_nesting.json @@ -37,4 +37,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_coreir/mapParallel_test.json b/tests/test_coreir/mapParallel_test.json index bad9ab00f3..94a1bdd489 100644 --- a/tests/test_coreir/mapParallel_test.json +++ b/tests/test_coreir/mapParallel_test.json @@ -51,4 +51,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_coreir/mapParallel_test_gold.json b/tests/test_coreir/mapParallel_test_gold.json index bad9ab00f3..94a1bdd489 100644 --- a/tests/test_coreir/mapParallel_test_gold.json +++ b/tests/test_coreir/mapParallel_test_gold.json @@ -51,4 +51,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_type/gold/test_enum.v b/tests/test_type/gold/test_enum.v index b681b756f1..b064c484da 100644 --- a/tests/test_type/gold/test_enum.v +++ b/tests/test_type/gold/test_enum.v @@ -1,7 +1,7 @@ module coreir_const #(parameter value=1, parameter width=1) ( output [width-1:0] out ); - assign out = value; + assign out = width'value; endmodule // coreir_const @@ -18,10 +18,10 @@ module enum_test ( .out(const_0_2__out) ); - assign O_1[1:0] = const_0_2__out[1:0]; - assign O_0[1:0] = I[1:0]; + assign O_1[1:0] = const_0_2__out[1:0]; + endmodule // enum_test diff --git a/tests/test_type/gold/test_enum_max_value.v b/tests/test_type/gold/test_enum_max_value.v index 9d984949bb..234ddee7d5 100644 --- a/tests/test_type/gold/test_enum_max_value.v +++ b/tests/test_type/gold/test_enum_max_value.v @@ -1,7 +1,7 @@ module coreir_const #(parameter value=1, parameter width=1) ( output [width-1:0] out ); - assign out = value; + assign out = width'value; endmodule // coreir_const @@ -18,10 +18,10 @@ module enum_test_max_value ( .out(const_4_3__out) ); - assign O_1[2:0] = const_4_3__out[2:0]; - assign O_0[2:0] = I[2:0]; + assign O_1[2:0] = const_4_3__out[2:0]; + endmodule // enum_test_max_value diff --git a/tests/test_type/gold/test_new_types.json b/tests/test_type/gold/test_new_types.json index 6401bbf79c..bc8e352084 100644 --- a/tests/test_type/gold/test_new_types.json +++ b/tests/test_type/gold/test_new_types.json @@ -14,4 +14,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_type/gold/test_new_types.v b/tests/test_type/gold/test_new_types.v index 170ad697ec..318bde5ec6 100644 --- a/tests/test_type/gold/test_new_types.v +++ b/tests/test_type/gold/test_new_types.v @@ -54,14 +54,6 @@ module TestCircuit ( assign O_0_y[2:0] = I_0_y[2:0]; - assign O_10_x[2:0] = I_10_x[2:0]; - - assign O_10_y[2:0] = I_10_y[2:0]; - - assign O_11_x[2:0] = I_11_x[2:0]; - - assign O_11_y[2:0] = I_11_y[2:0]; - assign O_1_x[2:0] = I_1_x[2:0]; assign O_1_y[2:0] = I_1_y[2:0]; @@ -98,6 +90,14 @@ module TestCircuit ( assign O_9_y[2:0] = I_9_y[2:0]; + assign O_10_x[2:0] = I_10_x[2:0]; + + assign O_10_y[2:0] = I_10_y[2:0]; + + assign O_11_x[2:0] = I_11_x[2:0]; + + assign O_11_y[2:0] = I_11_y[2:0]; + endmodule // TestCircuit diff --git a/tests/test_type/test_const_wire_golden.json b/tests/test_type/test_const_wire_golden.json index 737284d49d..87833a54e1 100644 --- a/tests/test_type/test_const_wire_golden.json +++ b/tests/test_type/test_const_wire_golden.json @@ -28,4 +28,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_type/test_coreir_wrap_golden_AsyncReset.json b/tests/test_type/test_coreir_wrap_golden_AsyncReset.json index 72143afc7b..9725656fc0 100644 --- a/tests/test_type/test_coreir_wrap_golden_AsyncReset.json +++ b/tests/test_type/test_coreir_wrap_golden_AsyncReset.json @@ -33,4 +33,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test_type/test_coreir_wrap_golden_Clock.json b/tests/test_type/test_coreir_wrap_golden_Clock.json index 71234f4eb4..d90d799d63 100644 --- a/tests/test_type/test_coreir_wrap_golden_Clock.json +++ b/tests/test_type/test_coreir_wrap_golden_Clock.json @@ -33,4 +33,4 @@ } } } -} \ No newline at end of file +} From 0afee9721eb2888173ea9ac60d97ef9159a8a1bd Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Sat, 3 Nov 2018 08:59:04 -0700 Subject: [PATCH 09/13] Revert "Fixup trailing lines in gold files for upstream coreir changes" This reverts commit 8c0a1fbbe1b73b538325a5658c70829615eefba0. --- tests/gold/basic_function_call.json | 2 +- tests/gold/if_statement_basic.json | 2 +- tests/gold/if_statement_nested.json | 2 +- tests/gold/return_magma_named_tuple.json | 2 +- tests/gold/return_magma_tuple.json | 2 +- tests/gold/return_py_tuple.json | 2 +- tests/gold/simple_circuit_1.json | 2 +- tests/gold/ternary.json | 2 +- tests/gold/ternary_nested.json | 2 +- tests/gold/ternary_nested2.json | 2 +- tests/gold/test_map_circuit.json | 2 +- tests/test_circuit/gold/test_add8cin.json | 2 +- .../gold/test_anon_value_Array(2,Bit).json | 2 +- tests/test_circuit/gold/test_anon_value_Bit.json | 2 +- .../gold/test_anon_value_Bits(2).json | 2 +- .../gold/test_anon_value_Tuple(x=Bit,y=Bit).json | 2 +- tests/test_circuit/gold/test_simple_def.json | 2 +- .../test_circuit/gold/test_simple_def_class.json | 2 +- tests/test_coreir/gold/linker_test0.json | 2 +- tests/test_coreir/gold/test_array_nesting.json | 2 +- .../gold/test_multi_direction_tuple.json | 2 +- .../test_multi_direction_tuple_instance.json | 2 +- tests/test_coreir/gold/test_nesting.json | 2 +- tests/test_coreir/mapParallel_test.json | 2 +- tests/test_coreir/mapParallel_test_gold.json | 2 +- tests/test_type/gold/test_enum.v | 6 +++--- tests/test_type/gold/test_enum_max_value.v | 6 +++--- tests/test_type/gold/test_new_types.json | 2 +- tests/test_type/gold/test_new_types.v | 16 ++++++++-------- tests/test_type/test_const_wire_golden.json | 2 +- .../test_coreir_wrap_golden_AsyncReset.json | 2 +- .../test_type/test_coreir_wrap_golden_Clock.json | 2 +- 32 files changed, 43 insertions(+), 43 deletions(-) diff --git a/tests/gold/basic_function_call.json b/tests/gold/basic_function_call.json index a923036806..d3a20dd914 100644 --- a/tests/gold/basic_function_call.json +++ b/tests/gold/basic_function_call.json @@ -48,4 +48,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/if_statement_basic.json b/tests/gold/if_statement_basic.json index f6123f4106..b7af946737 100644 --- a/tests/gold/if_statement_basic.json +++ b/tests/gold/if_statement_basic.json @@ -31,4 +31,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/if_statement_nested.json b/tests/gold/if_statement_nested.json index d8639d87a6..1b1e74de62 100644 --- a/tests/gold/if_statement_nested.json +++ b/tests/gold/if_statement_nested.json @@ -43,4 +43,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/return_magma_named_tuple.json b/tests/gold/return_magma_named_tuple.json index 05bfb3c872..b1419f121b 100644 --- a/tests/gold/return_magma_named_tuple.json +++ b/tests/gold/return_magma_named_tuple.json @@ -15,4 +15,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/return_magma_tuple.json b/tests/gold/return_magma_tuple.json index 595a787c68..d1b655b9cd 100644 --- a/tests/gold/return_magma_tuple.json +++ b/tests/gold/return_magma_tuple.json @@ -15,4 +15,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/return_py_tuple.json b/tests/gold/return_py_tuple.json index 99895667dc..62ebf20d62 100644 --- a/tests/gold/return_py_tuple.json +++ b/tests/gold/return_py_tuple.json @@ -16,4 +16,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/simple_circuit_1.json b/tests/gold/simple_circuit_1.json index 340dafb231..463c6bb0a8 100644 --- a/tests/gold/simple_circuit_1.json +++ b/tests/gold/simple_circuit_1.json @@ -74,4 +74,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/ternary.json b/tests/gold/ternary.json index 209da6ef7d..c338a78ee3 100644 --- a/tests/gold/ternary.json +++ b/tests/gold/ternary.json @@ -31,4 +31,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/ternary_nested.json b/tests/gold/ternary_nested.json index 28dbfa9c96..551ab91e27 100644 --- a/tests/gold/ternary_nested.json +++ b/tests/gold/ternary_nested.json @@ -37,4 +37,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/ternary_nested2.json b/tests/gold/ternary_nested2.json index 6f6705e4fe..363798e5b5 100644 --- a/tests/gold/ternary_nested2.json +++ b/tests/gold/ternary_nested2.json @@ -37,4 +37,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/gold/test_map_circuit.json b/tests/gold/test_map_circuit.json index 89a5f48b19..1e13d6dbe4 100644 --- a/tests/gold/test_map_circuit.json +++ b/tests/gold/test_map_circuit.json @@ -95,4 +95,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_circuit/gold/test_add8cin.json b/tests/test_circuit/gold/test_add8cin.json index e6f90da810..3c5c941ff2 100644 --- a/tests/test_circuit/gold/test_add8cin.json +++ b/tests/test_circuit/gold/test_add8cin.json @@ -60,4 +60,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_circuit/gold/test_anon_value_Array(2,Bit).json b/tests/test_circuit/gold/test_anon_value_Array(2,Bit).json index 430357bdda..aa5d82efba 100644 --- a/tests/test_circuit/gold/test_anon_value_Array(2,Bit).json +++ b/tests/test_circuit/gold/test_anon_value_Array(2,Bit).json @@ -29,4 +29,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_circuit/gold/test_anon_value_Bit.json b/tests/test_circuit/gold/test_anon_value_Bit.json index d08f37d5be..dab48b1aec 100644 --- a/tests/test_circuit/gold/test_anon_value_Bit.json +++ b/tests/test_circuit/gold/test_anon_value_Bit.json @@ -29,4 +29,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_circuit/gold/test_anon_value_Bits(2).json b/tests/test_circuit/gold/test_anon_value_Bits(2).json index 430357bdda..aa5d82efba 100644 --- a/tests/test_circuit/gold/test_anon_value_Bits(2).json +++ b/tests/test_circuit/gold/test_anon_value_Bits(2).json @@ -29,4 +29,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_circuit/gold/test_anon_value_Tuple(x=Bit,y=Bit).json b/tests/test_circuit/gold/test_anon_value_Tuple(x=Bit,y=Bit).json index a98bdada87..5f07b93d51 100644 --- a/tests/test_circuit/gold/test_anon_value_Tuple(x=Bit,y=Bit).json +++ b/tests/test_circuit/gold/test_anon_value_Tuple(x=Bit,y=Bit).json @@ -29,4 +29,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_circuit/gold/test_simple_def.json b/tests/test_circuit/gold/test_simple_def.json index ee50cf9e45..eede176d41 100644 --- a/tests/test_circuit/gold/test_simple_def.json +++ b/tests/test_circuit/gold/test_simple_def.json @@ -29,4 +29,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_circuit/gold/test_simple_def_class.json b/tests/test_circuit/gold/test_simple_def_class.json index 66116731f3..93e12a98b5 100644 --- a/tests/test_circuit/gold/test_simple_def_class.json +++ b/tests/test_circuit/gold/test_simple_def_class.json @@ -29,4 +29,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_coreir/gold/linker_test0.json b/tests/test_coreir/gold/linker_test0.json index 6adaf5cf1d..113c32b2bd 100644 --- a/tests/test_coreir/gold/linker_test0.json +++ b/tests/test_coreir/gold/linker_test0.json @@ -23,4 +23,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_coreir/gold/test_array_nesting.json b/tests/test_coreir/gold/test_array_nesting.json index 70609f58a7..0b589d74eb 100644 --- a/tests/test_coreir/gold/test_array_nesting.json +++ b/tests/test_coreir/gold/test_array_nesting.json @@ -22,4 +22,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_coreir/gold/test_multi_direction_tuple.json b/tests/test_coreir/gold/test_multi_direction_tuple.json index 2246403de5..f1ec8990f0 100644 --- a/tests/test_coreir/gold/test_multi_direction_tuple.json +++ b/tests/test_coreir/gold/test_multi_direction_tuple.json @@ -13,4 +13,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_coreir/gold/test_multi_direction_tuple_instance.json b/tests/test_coreir/gold/test_multi_direction_tuple_instance.json index 7fdd054e02..f20bf9a42a 100644 --- a/tests/test_coreir/gold/test_multi_direction_tuple_instance.json +++ b/tests/test_coreir/gold/test_multi_direction_tuple_instance.json @@ -27,4 +27,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_coreir/gold/test_nesting.json b/tests/test_coreir/gold/test_nesting.json index b6a21bb381..80de254c4a 100644 --- a/tests/test_coreir/gold/test_nesting.json +++ b/tests/test_coreir/gold/test_nesting.json @@ -37,4 +37,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_coreir/mapParallel_test.json b/tests/test_coreir/mapParallel_test.json index 94a1bdd489..bad9ab00f3 100644 --- a/tests/test_coreir/mapParallel_test.json +++ b/tests/test_coreir/mapParallel_test.json @@ -51,4 +51,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_coreir/mapParallel_test_gold.json b/tests/test_coreir/mapParallel_test_gold.json index 94a1bdd489..bad9ab00f3 100644 --- a/tests/test_coreir/mapParallel_test_gold.json +++ b/tests/test_coreir/mapParallel_test_gold.json @@ -51,4 +51,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_type/gold/test_enum.v b/tests/test_type/gold/test_enum.v index b064c484da..b681b756f1 100644 --- a/tests/test_type/gold/test_enum.v +++ b/tests/test_type/gold/test_enum.v @@ -1,7 +1,7 @@ module coreir_const #(parameter value=1, parameter width=1) ( output [width-1:0] out ); - assign out = width'value; + assign out = value; endmodule // coreir_const @@ -18,10 +18,10 @@ module enum_test ( .out(const_0_2__out) ); - assign O_0[1:0] = I[1:0]; - assign O_1[1:0] = const_0_2__out[1:0]; + assign O_0[1:0] = I[1:0]; + endmodule // enum_test diff --git a/tests/test_type/gold/test_enum_max_value.v b/tests/test_type/gold/test_enum_max_value.v index 234ddee7d5..9d984949bb 100644 --- a/tests/test_type/gold/test_enum_max_value.v +++ b/tests/test_type/gold/test_enum_max_value.v @@ -1,7 +1,7 @@ module coreir_const #(parameter value=1, parameter width=1) ( output [width-1:0] out ); - assign out = width'value; + assign out = value; endmodule // coreir_const @@ -18,10 +18,10 @@ module enum_test_max_value ( .out(const_4_3__out) ); - assign O_0[2:0] = I[2:0]; - assign O_1[2:0] = const_4_3__out[2:0]; + assign O_0[2:0] = I[2:0]; + endmodule // enum_test_max_value diff --git a/tests/test_type/gold/test_new_types.json b/tests/test_type/gold/test_new_types.json index bc8e352084..6401bbf79c 100644 --- a/tests/test_type/gold/test_new_types.json +++ b/tests/test_type/gold/test_new_types.json @@ -14,4 +14,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_type/gold/test_new_types.v b/tests/test_type/gold/test_new_types.v index 318bde5ec6..170ad697ec 100644 --- a/tests/test_type/gold/test_new_types.v +++ b/tests/test_type/gold/test_new_types.v @@ -54,6 +54,14 @@ module TestCircuit ( assign O_0_y[2:0] = I_0_y[2:0]; + assign O_10_x[2:0] = I_10_x[2:0]; + + assign O_10_y[2:0] = I_10_y[2:0]; + + assign O_11_x[2:0] = I_11_x[2:0]; + + assign O_11_y[2:0] = I_11_y[2:0]; + assign O_1_x[2:0] = I_1_x[2:0]; assign O_1_y[2:0] = I_1_y[2:0]; @@ -90,14 +98,6 @@ module TestCircuit ( assign O_9_y[2:0] = I_9_y[2:0]; - assign O_10_x[2:0] = I_10_x[2:0]; - - assign O_10_y[2:0] = I_10_y[2:0]; - - assign O_11_x[2:0] = I_11_x[2:0]; - - assign O_11_y[2:0] = I_11_y[2:0]; - endmodule // TestCircuit diff --git a/tests/test_type/test_const_wire_golden.json b/tests/test_type/test_const_wire_golden.json index 87833a54e1..737284d49d 100644 --- a/tests/test_type/test_const_wire_golden.json +++ b/tests/test_type/test_const_wire_golden.json @@ -28,4 +28,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_type/test_coreir_wrap_golden_AsyncReset.json b/tests/test_type/test_coreir_wrap_golden_AsyncReset.json index 9725656fc0..72143afc7b 100644 --- a/tests/test_type/test_coreir_wrap_golden_AsyncReset.json +++ b/tests/test_type/test_coreir_wrap_golden_AsyncReset.json @@ -33,4 +33,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/test_type/test_coreir_wrap_golden_Clock.json b/tests/test_type/test_coreir_wrap_golden_Clock.json index d90d799d63..71234f4eb4 100644 --- a/tests/test_type/test_coreir_wrap_golden_Clock.json +++ b/tests/test_type/test_coreir_wrap_golden_Clock.json @@ -33,4 +33,4 @@ } } } -} +} \ No newline at end of file From 61ce935864bb80d7d3e201278d33c4056809bf77 Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Thu, 8 Nov 2018 11:24:27 -0800 Subject: [PATCH 10/13] Change wiring operator to use <= --- docs/operators.md | 2 +- magma/operators.py | 9 ++++++--- magma/t.py | 6 ++++++ tests/test_operators.py | 31 ++++++++++++++++++++++++++++--- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/docs/operators.md b/docs/operators.md index 41ce8c168f..a60aa921da 100644 --- a/docs/operators.md +++ b/docs/operators.md @@ -46,7 +46,7 @@ Language](https://ieeexplore.ieee.org/document/8299595) (page 256, Table 11-1 #### Assignment | Verilog Operator | Magma Operator | Types | Context | Comments | |------------------|----------------| ----- | ------- | -------- | -| `=` | `m.wire`, `=` (only when setting attributes on circuit definitions or circuit instances) | Any | All | Assignment cannot be overloaded for arbitrary Python variables, so in general we must use `m.wire`. We have added preliminary for assignment to attributes of magma circuit definitions and instances, e.g. `reg.I = io.I`, but remember that assigning to Python variables, e.g. `I = io.I` does not correspond to wiring. | +| `=` | `m.wire`, `<=` (can only be used on magma input values) | Any | All | Assignment cannot be overloaded for arbitrary Python variables, so in general we must use `m.wire`. We have added preliminary for assignment to attributes of magma values using the `<=` operator, which may be familiar for Verilog programmers using non-blocking assignments. Example: `reg.I <= io.I`. `<=` is purely syntactic sugar defiend on output values and calls `m.wire` under the hood. | | `+=`, `-=`, `/=`, `*=` | `None` | None | All | Support is not planned for these operators because magma cannot provide a clean semantics for them. Assignment only works for inputs to circuit instances and outputs of circuit definitions. AugAssign operators imply a value that is used both as an input an output. For example, `inst.a +=1` would imply a is an output that feeds into binary add with 1, while also an input which consumes the result of the binary add. | | `%=` | `None` | None | All | See above | | `&=`, `|=`, `^=` | `None` | None | All | See above | diff --git a/magma/operators.py b/magma/operators.py index 7334f76d7d..0754a45f51 100644 --- a/magma/operators.py +++ b/magma/operators.py @@ -46,7 +46,8 @@ def wrapped(self, other): "__mul__", "__div__", "__lt__", - "__le__", + # __le__ skipped because it's used for assignment on inputs + # "__le__", "__gt__", "__ge__" ): @@ -87,7 +88,8 @@ def wrapped(self, other): "__mul__", "__div__", "__lt__", - "__le__", + # __le__ skipped because it's used for assignment on inputs + # "__le__", "__gt__", "__ge__" ): @@ -99,7 +101,8 @@ def wrapped(self, other): "__mul__", "__div__", "__lt__", - "__le__", + # __le__ skipped because it's used for assignment on inputs + # "__le__", "__gt__", "__ge__" ): diff --git a/magma/t.py b/magma/t.py index 7f1d94b140..4f24241f4e 100644 --- a/magma/t.py +++ b/magma/t.py @@ -67,6 +67,12 @@ def debug_name(self): defn_str = str(self.name.inst.defn.name) + "." return f"{defn_str}{inst_str}{str(self)}" + def __le__(self, other): + if self.isinput(): + self.wire(other) + else: + raise TypeError("Cannot use <= to assign to an output") + class Kind(type): def __init__(cls, name, bases, dct): diff --git a/tests/test_operators.py b/tests/test_operators.py index 22457b1cde..a0a540ff21 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -2,6 +2,7 @@ from magma.operators import MantleImportError from common import DeclareAnd import pytest +from magma.testing import check_files_equal def test_error(): @@ -22,12 +23,36 @@ def test_assign(width, output): circ = m.DefineCircuit(name, "a", m.In(T), "b", m.In(T), "c", m.Out(T)) and2 = DeclareAnd(width)() - and2.I0 = circ.a - and2.I1 = circ.b - circ.c = and2.O + and2.I0 <= circ.a + and2.I1 <= circ.b + circ.c <= and2.O m.EndDefine() m.compile(f"build/{name}", circ, output) + suffix = "v" if output == "verilog" else "json" + assert check_files_equal(__file__, f"build/{name}.{suffix}", + f"gold/{name}.{suffix}") + + + +@pytest.mark.parametrize("width", [None, 3]) +@pytest.mark.parametrize("output", ["verilog", "coreir"]) +def test_assign_to_var(width, output): + T = m.util.BitOrBits(width) + name = f"test_assign_operator2_{width}_{output}" + circ = m.DefineCircuit(name, "a", m.In(T), "b", m.In(T), + "c", m.Out(T)) + and2 = DeclareAnd(width)() + c, I0, I1 = and2.I0, and2.I1, circ.c + I0 <= circ.a + I1 <= circ.b + c <= and2.O + m.EndDefine() + + m.compile(f"build/{name}", circ, output) + suffix = "v" if output == "verilog" else "json" + assert check_files_equal(__file__, f"build/{name}.{suffix}", + f"gold/{name}.{suffix}") @pytest.mark.parametrize("width", [None, 3]) From e4f9bfba5aa4bf8b3ea1c0edc69ff4f04ed6af86 Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Thu, 8 Nov 2018 11:35:04 -0800 Subject: [PATCH 11/13] Add missing gold files --- .../gold/test_assign_operator2_3_coreir.json | 32 +++++++++++++++++++ tests/gold/test_assign_operator2_3_verilog.v | 6 ++++ .../test_assign_operator2_None_coreir.json | 32 +++++++++++++++++++ .../gold/test_assign_operator2_None_verilog.v | 6 ++++ tests/gold/test_assign_operator_3_coreir.json | 32 +++++++++++++++++++ tests/gold/test_assign_operator_3_verilog.v | 6 ++++ .../test_assign_operator_None_coreir.json | 32 +++++++++++++++++++ .../gold/test_assign_operator_None_verilog.v | 6 ++++ 8 files changed, 152 insertions(+) create mode 100644 tests/gold/test_assign_operator2_3_coreir.json create mode 100644 tests/gold/test_assign_operator2_3_verilog.v create mode 100644 tests/gold/test_assign_operator2_None_coreir.json create mode 100644 tests/gold/test_assign_operator2_None_verilog.v create mode 100644 tests/gold/test_assign_operator_3_coreir.json create mode 100644 tests/gold/test_assign_operator_3_verilog.v create mode 100644 tests/gold/test_assign_operator_None_coreir.json create mode 100644 tests/gold/test_assign_operator_None_verilog.v diff --git a/tests/gold/test_assign_operator2_3_coreir.json b/tests/gold/test_assign_operator2_3_coreir.json new file mode 100644 index 0000000000..3b5085f30c --- /dev/null +++ b/tests/gold/test_assign_operator2_3_coreir.json @@ -0,0 +1,32 @@ +{"top":"global.test_assign_operator2_3_coreir", +"namespaces":{ + "global":{ + "modules":{ + "And3":{ + "type":["Record",[ + ["I0",["Array",3,"BitIn"]], + ["I1",["Array",3,"BitIn"]], + ["O",["Array",3,"Bit"]] + ]] + }, + "test_assign_operator2_3_coreir":{ + "type":["Record",[ + ["a",["Array",3,"BitIn"]], + ["b",["Array",3,"BitIn"]], + ["c",["Array",3,"Bit"]] + ]], + "instances":{ + "inst0":{ + "modref":"global.And3" + } + }, + "connections":[ + ["inst0.O","inst0.I0"], + ["self.a","inst0.I1"], + ["self.c","self.b"] + ] + } + } + } +} +} \ No newline at end of file diff --git a/tests/gold/test_assign_operator2_3_verilog.v b/tests/gold/test_assign_operator2_3_verilog.v new file mode 100644 index 0000000000..5d4e3c26ca --- /dev/null +++ b/tests/gold/test_assign_operator2_3_verilog.v @@ -0,0 +1,6 @@ +module test_assign_operator2_3_verilog (input [2:0] a, input [2:0] b, output [2:0] c); +wire [2:0] inst0_O; +And3 inst0 (.I0(inst0_O), .I1(a), .O(inst0_O)); +assign c = b; +endmodule + diff --git a/tests/gold/test_assign_operator2_None_coreir.json b/tests/gold/test_assign_operator2_None_coreir.json new file mode 100644 index 0000000000..4194488a13 --- /dev/null +++ b/tests/gold/test_assign_operator2_None_coreir.json @@ -0,0 +1,32 @@ +{"top":"global.test_assign_operator2_None_coreir", +"namespaces":{ + "global":{ + "modules":{ + "AndNone":{ + "type":["Record",[ + ["I0","BitIn"], + ["I1","BitIn"], + ["O","Bit"] + ]] + }, + "test_assign_operator2_None_coreir":{ + "type":["Record",[ + ["a","BitIn"], + ["b","BitIn"], + ["c","Bit"] + ]], + "instances":{ + "inst0":{ + "modref":"global.AndNone" + } + }, + "connections":[ + ["inst0.O","inst0.I0"], + ["self.a","inst0.I1"], + ["self.c","self.b"] + ] + } + } + } +} +} \ No newline at end of file diff --git a/tests/gold/test_assign_operator2_None_verilog.v b/tests/gold/test_assign_operator2_None_verilog.v new file mode 100644 index 0000000000..1e1e0067ba --- /dev/null +++ b/tests/gold/test_assign_operator2_None_verilog.v @@ -0,0 +1,6 @@ +module test_assign_operator2_None_verilog (input a, input b, output c); +wire inst0_O; +AndNone inst0 (.I0(inst0_O), .I1(a), .O(inst0_O)); +assign c = b; +endmodule + diff --git a/tests/gold/test_assign_operator_3_coreir.json b/tests/gold/test_assign_operator_3_coreir.json new file mode 100644 index 0000000000..7f3b07beec --- /dev/null +++ b/tests/gold/test_assign_operator_3_coreir.json @@ -0,0 +1,32 @@ +{"top":"global.test_assign_operator_3_coreir", +"namespaces":{ + "global":{ + "modules":{ + "And3":{ + "type":["Record",[ + ["I0",["Array",3,"BitIn"]], + ["I1",["Array",3,"BitIn"]], + ["O",["Array",3,"Bit"]] + ]] + }, + "test_assign_operator_3_coreir":{ + "type":["Record",[ + ["a",["Array",3,"BitIn"]], + ["b",["Array",3,"BitIn"]], + ["c",["Array",3,"Bit"]] + ]], + "instances":{ + "inst0":{ + "modref":"global.And3" + } + }, + "connections":[ + ["self.a","inst0.I0"], + ["self.b","inst0.I1"], + ["self.c","inst0.O"] + ] + } + } + } +} +} \ No newline at end of file diff --git a/tests/gold/test_assign_operator_3_verilog.v b/tests/gold/test_assign_operator_3_verilog.v new file mode 100644 index 0000000000..35a1794797 --- /dev/null +++ b/tests/gold/test_assign_operator_3_verilog.v @@ -0,0 +1,6 @@ +module test_assign_operator_3_verilog (input [2:0] a, input [2:0] b, output [2:0] c); +wire [2:0] inst0_O; +And3 inst0 (.I0(a), .I1(b), .O(inst0_O)); +assign c = inst0_O; +endmodule + diff --git a/tests/gold/test_assign_operator_None_coreir.json b/tests/gold/test_assign_operator_None_coreir.json new file mode 100644 index 0000000000..bc55485ebc --- /dev/null +++ b/tests/gold/test_assign_operator_None_coreir.json @@ -0,0 +1,32 @@ +{"top":"global.test_assign_operator_None_coreir", +"namespaces":{ + "global":{ + "modules":{ + "AndNone":{ + "type":["Record",[ + ["I0","BitIn"], + ["I1","BitIn"], + ["O","Bit"] + ]] + }, + "test_assign_operator_None_coreir":{ + "type":["Record",[ + ["a","BitIn"], + ["b","BitIn"], + ["c","Bit"] + ]], + "instances":{ + "inst0":{ + "modref":"global.AndNone" + } + }, + "connections":[ + ["self.a","inst0.I0"], + ["self.b","inst0.I1"], + ["self.c","inst0.O"] + ] + } + } + } +} +} \ No newline at end of file diff --git a/tests/gold/test_assign_operator_None_verilog.v b/tests/gold/test_assign_operator_None_verilog.v new file mode 100644 index 0000000000..25e1e332f6 --- /dev/null +++ b/tests/gold/test_assign_operator_None_verilog.v @@ -0,0 +1,6 @@ +module test_assign_operator_None_verilog (input a, input b, output c); +wire inst0_O; +AndNone inst0 (.I0(a), .I1(b), .O(inst0_O)); +assign c = inst0_O; +endmodule + From 5308df727ead0cbfbf00ec926b620d7aba552360 Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Thu, 8 Nov 2018 11:38:37 -0800 Subject: [PATCH 12/13] Remove old __setattr__ implementation --- magma/circuit.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/magma/circuit.py b/magma/circuit.py index 0512f81054..7add110875 100644 --- a/magma/circuit.py +++ b/magma/circuit.py @@ -46,13 +46,11 @@ def circuit_to_html(cls): # create an attribute for each port def setports(self, ports): - self.ports_set = False #print('setports', ports) for name, port in ports.items(): #print(self, port, type(port)) if isinstance(name, str): setattr(self, name, port) - self.ports_set = True # # Metaclass for creating circuits @@ -95,18 +93,6 @@ def __new__(metacls, name, bases, dct): return cls - def __setattr__(cls, key, value): - # First check if interface has been set, since early in the metaclass - # pipeline we set attributes on the class, so we just use default - # semantics for those statements - if not getattr(cls, "ports_set", False) or key not in cls.interface: - super().__setattr__(key, value) - else: - port = cls.interface[key] - if port.isoutput(): - raise TypeError(f"Cannot assign to input port of definition: {port.debug_name}") - port.wire(value) - def __call__(cls, *largs, **kwargs): #print('CircuitKind call:', largs, kwargs) debug_info = get_callee_frame_info() @@ -221,20 +207,6 @@ def _repr_html_(self): def __getitem__(self, key): return self.interface[key] - def __setattr__(self, key, value): - # First check if interface has been set, since early in the metaclass - # pipeline we set attributes on the class, so we just use default - # semantics for those statements - if not getattr(self, "ports_set", False) or \ - getattr(self, "interface", None) is None or \ - key not in self.interface: - object.__setattr__(self, key, value) - else: - port = self.interface[key] - if port.isoutput(): - raise TypeError(f"Cannot assign to output port of instance: {port.debug_name}") - port.wire(value) - # wire a list of outputs to the circuit's inputs def wireoutputs(self, outputs, debug_info): inputs = self.interface.inputs() From 0b999952aab3f060ac3b1c4366f234afd5a3d74d Mon Sep 17 00:00:00 2001 From: Leonard Truong Date: Thu, 8 Nov 2018 11:45:12 -0800 Subject: [PATCH 13/13] Update error tests --- magma/t.py | 2 +- tests/test_operators.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/magma/t.py b/magma/t.py index 4f24241f4e..49fe4fdb02 100644 --- a/magma/t.py +++ b/magma/t.py @@ -71,7 +71,7 @@ def __le__(self, other): if self.isinput(): self.wire(other) else: - raise TypeError("Cannot use <= to assign to an output") + raise TypeError(f"Cannot use <= to assign to output: {self.debug_name} (trying to assign {other.debug_name})") class Kind(type): diff --git a/tests/test_operators.py b/tests/test_operators.py index a0a540ff21..54a898b29a 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -63,10 +63,10 @@ def test_assign_error_0(width): "c", m.Out(T)) and2 = DeclareAnd(width)() try: - and2.O = circ.a + and2.O <= circ.a assert False, "Should raise type error" except TypeError as e: - assert str(e) == f"Cannot assign to output port of instance: test_assign_operator_{width}.And{width}_inst0.O" + assert str(e) == f"Cannot use <= to assign to output: {and2.O.debug_name} (trying to assign {circ.a.debug_name})" @pytest.mark.parametrize("width", [None, 3]) @@ -77,7 +77,7 @@ def test_assign_error_1(width): "c", m.Out(T)) and2 = DeclareAnd(width)() try: - circ.a = and2.O + circ.a <= and2.O assert False, "Should raise type error" except TypeError as e: - assert str(e) == f"Cannot assign to input port of definition: test_assign_operator_{width}.a" + assert str(e) == f"Cannot use <= to assign to output: {circ.a.debug_name} (trying to assign {and2.O.debug_name})"