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 all commits
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
14 changes: 10 additions & 4 deletions magma/backend/mlir/hardware_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
value_or_type_to_string as magma_value_or_type_to_string,
visit_value_or_value_wrapper_by_direction as
visit_magma_value_or_value_wrapper_by_direction,
tuple_key_to_str as magma_tuple_key_to_str,
)
from magma.backend.mlir.mem_utils import (
make_mem_reg,
Expand Down Expand Up @@ -139,9 +140,11 @@ def magma_type_to_mlir_type(type: Kind) -> MlirType:
return magma_type_to_mlir_type(Bits[type.N])
return hw.ArrayType((type.N,), magma_type_to_mlir_type(type.T))
if issubclass(type, m_Tuple):
fields = {str(k): magma_type_to_mlir_type(t)
for k, t in type.field_dict.items()}
return hw.StructType(tuple(fields.items()))
fields = (
(magma_tuple_key_to_str(k, type), magma_type_to_mlir_type(t))
for k, t in type.field_dict.items()
)
return hw.StructType(tuple(fields))


@wrap_with_not_implemented_error
Expand Down Expand Up @@ -969,7 +972,10 @@ def visit_instance_wrapper(self, module: ModuleWrapper) -> bool:
)
return True
if inst_wrapper.name.startswith("magma_tuple_get_op"):
index = inst_wrapper.attrs["index"]
index = magma_tuple_key_to_str(
inst_wrapper.attrs["index"],
inst_wrapper.attrs["T"]
)
hw.StructExtractOp(
field=index,
operands=module.operands,
Expand Down
11 changes: 10 additions & 1 deletion magma/backend/mlir/magma_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from magma.common import replace_all, Stack, SimpleCounter
from magma.ref import Ref, ArrayRef, TupleRef
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


ModuleLike = Union[DefineCircuitKind, Circuit]
Expand Down Expand Up @@ -42,6 +42,15 @@ def value_or_type_to_string(value_or_type: Union[Type, Kind]):
return replace_all(s, _VALUE_OR_TYPE_TO_STRING_REPLACEMENTS)


def tuple_key_to_str(key: Union[str, int], T: TupleMeta) -> str:
# 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.
if issubclass(T, Product):
return str(key)
return f"_{key}"


@dataclasses.dataclass(frozen=True)
class ValueWrapper:
id: str = dataclasses.field(default_factory=make_unique_name, init=False)
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