Skip to content

Commit 2e5e2a9

Browse files
committed
[MLIR] Add support for compile guard select
1 parent 172da52 commit 2e5e2a9

File tree

4 files changed

+56
-8
lines changed

4 files changed

+56
-8
lines changed

magma/backend/mlir/hardware_module.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
from magma.circuit import AnonymousCircuitType, CircuitKind, DefineCircuitKind
5353
from magma.clock import Reset, ResetN, AsyncReset, AsyncResetN
5454
from magma.common import filter_by_key, assert_false
55-
from magma.compile_guard import get_compile_guard_data
55+
from magma.compile_guard import get_compile_guard_data, CompileGuardSelect
5656
from magma.digital import Digital, DigitalMeta
5757
from magma.inline_verilog_expression import InlineVerilogExpression
5858
from magma.inline_verilog2 import InlineVerilog2
@@ -880,6 +880,27 @@ def visit_magma_xmr_source(self, module: ModuleWrapper) -> bool:
880880
sv.ReadInOutOp(operands=[in_out], results=[result])
881881
return True
882882

883+
@wrap_with_not_implemented_error
884+
def visit_magma_compile_guard_select(self, module: ModuleWrapper) -> bool:
885+
inst = module.module
886+
defn = type(inst)
887+
assert isinstance(defn, CompileGuardSelect)
888+
assert len(defn.keys) + 1 == len(module.operands)
889+
assert len(module.results) == 1
890+
result = module.results[0]
891+
mlir_type = magma_type_to_mlir_type(defn.T)
892+
reg = self.ctx.new_value(hw.InOutType(mlir_type))
893+
sv.RegOp(results=[reg])
894+
with contextlib.ExitStack() as stack:
895+
for i, key in enumerate(defn.keys):
896+
if_def = sv.IfDefOp(key)
897+
stack.enter_context(push_block(if_def.then_block))
898+
sv.AssignOp(operands=[reg, module.operands[i]])
899+
stack.enter_context(push_block(if_def.else_block))
900+
sv.AssignOp(operands=[reg, module.operands[-1]])
901+
sv.ReadInOutOp(operands=[reg], results=[result])
902+
return True
903+
883904
@wrap_with_not_implemented_error
884905
def visit_inline_verilog(self, module: ModuleWrapper) -> bool:
885906
inst = module.module
@@ -921,6 +942,8 @@ def visit_instance(self, module: ModuleWrapper) -> bool:
921942
return self.visit_magma_xmr_sink(module)
922943
if isinstance(defn, XMRSource):
923944
return self.visit_magma_xmr_source(module)
945+
if isinstance(defn, CompileGuardSelect):
946+
return self.visit_magma_compile_guard_select(module)
924947
if getattr(defn, "inline_verilog_strs", []):
925948
return self.visit_inline_verilog(module)
926949
if isprimitive(defn):

tests/test_backend/test_mlir/examples.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,15 @@ class xmr_bind_asserts(m.Circuit):
488488
class simple_compile_guard(m.Circuit):
489489
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
490490
with m.compile_guard(
491-
"COND1", defn_name="COND1_compile_guard", type="defined"):
492-
out = m.Register(m.Bit)()(io.I)
491+
"COND1", defn_name="COND1_compile_guard", type="defined"
492+
):
493+
m.Register(m.Bit)()(io.I)
493494
with m.compile_guard(
494-
"COND2", defn_name="COND2_compile_guard", type="undefined"):
495-
out = m.Register(m.Bit)()(io.I)
496-
io.O @= io.I
495+
"COND2", defn_name="COND2_compile_guard", type="undefined"
496+
):
497+
m.Register(m.Bit)()(io.I)
498+
out = m.compile_guard_select(COND1=io.I, COND2=~io.I, default=0)
499+
io.O @= out
497500

498501

499502
m.passes.clock.WireClockPass(simple_compile_guard).run()

tests/test_backend/test_mlir/golds/simple_compile_guard.mlir

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,27 @@ module attributes {circt.loweringOptions = "locationInfoStyle=none"} {
2222
%0 = sv.read_inout %1 : !hw.inout<i1>
2323
}
2424
hw.module @simple_compile_guard(%I: i1, %CLK: i1) -> (O: i1) {
25+
%1 = hw.constant -1 : i1
26+
%0 = comb.xor %1, %I : i1
27+
%2 = hw.constant 0 : i1
28+
%4 = sv.reg : !hw.inout<i1>
29+
sv.ifdef "COND1" {
30+
sv.assign %4, %I : i1
31+
} else {
32+
sv.ifdef "COND2" {
33+
sv.assign %4, %0 : i1
34+
} else {
35+
sv.assign %4, %2 : i1
36+
}
37+
}
38+
%3 = sv.read_inout %4 : !hw.inout<i1>
2539
sv.ifdef "COND1" {
2640
hw.instance "COND1_compile_guard" @COND1_compile_guard(port_0: %I: i1, port_1: %CLK: i1) -> ()
2741
}
2842
sv.ifdef "COND2" {
2943
} else {
3044
hw.instance "COND2_compile_guard" @COND2_compile_guard(port_0: %I: i1, port_1: %CLK: i1) -> ()
3145
}
32-
hw.output %I : i1
46+
hw.output %3 : i1
3347
}
3448
}

tests/test_backend/test_mlir/golds/simple_compile_guard.v

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,26 @@ module simple_compile_guard(
2929
output O
3030
);
3131

32+
reg _GEN;
3233
`ifdef COND1
34+
assign _GEN = I;
3335
COND1_compile_guard COND1_compile_guard (
3436
.port_0 (I),
3537
.port_1 (CLK)
3638
);
39+
`else // COND1
40+
`ifdef COND2
41+
assign _GEN = ~I;
42+
`else // COND2
43+
assign _GEN = 1'h0;
44+
`endif // COND2
3745
`endif // COND1
3846
`ifndef COND2
3947
COND2_compile_guard COND2_compile_guard (
4048
.port_0 (I),
4149
.port_1 (CLK)
4250
);
4351
`endif // not def COND2
44-
assign O = I;
52+
assign O = _GEN;
4553
endmodule
4654

0 commit comments

Comments
 (0)