Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MLIR] Add support for Tuples with integer keys #1260

Merged
merged 2 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions magma/backend/mlir/hardware_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
from magma.primitives.xmr import XMRSink, XMRSource
from magma.protocol_type import magma_value as get_magma_value
from magma.t import Kind, Type
from magma.tuple import TupleMeta, Tuple as m_Tuple
from magma.tuple import TupleMeta, Tuple as m_Tuple, Product
from magma.value_utils import make_selector, TupleSelector, ArraySelector
from magma.view import PortView

Expand Down Expand Up @@ -138,9 +138,21 @@ def magma_type_to_mlir_type(type: Kind) -> MlirType:
if issubclass(type.T, Bit):
return magma_type_to_mlir_type(Bits[type.N])
return hw.ArrayType((type.N,), magma_type_to_mlir_type(type.T))
# NOTE(rsetaluri): If the type is Tuple (i.e. has integer keys), then the
# struct type we emit should prefix the field key with an underscore
# (e.g. "_0") to make it a valid keyword. Note that this *must* be in sync
# with the translation of magma_tuple_get_op's which does the same.
if issubclass(type, Product):
fields = {
str(k): magma_type_to_mlir_type(t)
for k, t in type.field_dict.items()
}
return hw.StructType(tuple(fields.items()))
if issubclass(type, m_Tuple):
fields = {str(k): magma_type_to_mlir_type(t)
for k, t in type.field_dict.items()}
fields = {
f"_{i}": magma_type_to_mlir_type(t)
for i, t in enumerate(type.field_dict.values())
}
rsetaluri marked this conversation as resolved.
Show resolved Hide resolved
return hw.StructType(tuple(fields.items()))


Expand Down Expand Up @@ -970,6 +982,14 @@ def visit_instance_wrapper(self, module: ModuleWrapper) -> bool:
return True
if inst_wrapper.name.startswith("magma_tuple_get_op"):
index = inst_wrapper.attrs["index"]
# NOTE(rsetaluri): If the underlying type is *not* a Product (i.e. a
# Tuple with integer keys), then the StructExtractOp we emit should
# prefix the field key with an underscore (e.g. "_0") to make it a
# valid keyword. Note that this *must* be in sync with the
# translation function magma_type_to_mlir_type() which does the
# same.
if not issubclass(inst_wrapper.attrs["T"], Product):
index = f"_{index}"
hw.StructExtractOp(
field=index,
operands=module.operands,
Expand Down
10 changes: 5 additions & 5 deletions tests/test_backend/test_mlir/golds/simple_aggregates_tuple.mlir
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module attributes {circt.loweringOptions = "locationInfoStyle=none"} {
hw.module @simple_aggregates_tuple(%a: !hw.struct<0: i8, 1: i8>) -> (y: !hw.struct<0: i8, 1: i8>) {
%0 = hw.struct_extract %a["0"] : !hw.struct<0: i8, 1: i8>
hw.module @simple_aggregates_tuple(%a: !hw.struct<_0: i8, _1: i8>) -> (y: !hw.struct<_0: i8, _1: i8>) {
%0 = hw.struct_extract %a["_0"] : !hw.struct<_0: i8, _1: i8>
%2 = hw.constant -1 : i8
%1 = comb.xor %2, %0 : i8
%3 = hw.struct_extract %a["1"] : !hw.struct<0: i8, 1: i8>
%3 = hw.struct_extract %a["_1"] : !hw.struct<_0: i8, _1: i8>
%4 = comb.xor %2, %3 : i8
%5 = hw.struct_create (%1, %4) : !hw.struct<0: i8, 1: i8>
hw.output %5 : !hw.struct<0: i8, 1: i8>
%5 = hw.struct_create (%1, %4) : !hw.struct<_0: i8, _1: i8>
hw.output %5 : !hw.struct<_0: i8, _1: i8>
}
}
9 changes: 9 additions & 0 deletions tests/test_backend/test_mlir/golds/simple_aggregates_tuple.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Generated by CIRCT circtorg-0.0.0-1773-g7abbc4313
module simple_aggregates_tuple(
input struct packed {logic [7:0] _0; logic [7:0] _1; } a,
output struct packed {logic [7:0] _0; logic [7:0] _1; } y
);

assign y = '{_0: (~a._0), _1: (~a._1)};
endmodule

Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@ def test_compile_to_mlir(ckt):
"use_native_bind_processor": True,
"basename": ckt.name,
}
# NOTE(rsetaluri): This is a hack to skip the Tuple[] to verilog test since
# MLIR does not allow leading integers in names (e.g. `!hw.struct<0:
# ...>`). We should ultimately fix this by changing the IR code generation.
if ckt.name == "simple_aggregates_tuple":
kwargs["check_verilog"] = False
run_test_compile_to_mlir(ckt, **kwargs)


Expand Down