Skip to content

Commit 40684b9

Browse files
committed
[CompileGuard] Fix compile guard select key parsing
See #1291. Fixes two-key case (previously unsupported), and adds and refactors tests.
1 parent df4a8af commit 40684b9

File tree

3 files changed

+109
-10
lines changed

3 files changed

+109
-10
lines changed

magma/compile_guard.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,9 @@ def compile_guard_select(**kwargs):
172172
try:
173173
default = kwargs.pop("default")
174174
except KeyError:
175-
raise ValueError("Expected default argument") from None
176-
if not (len(kwargs) > 1):
177-
raise ValueError("Expected at least one key besides default")
175+
raise KeyError("Expected default argument") from None
176+
if not kwargs: # kwargs is empty
177+
raise KeyError("Expected at least one key besides default")
178178
# We rely on insertion order to make the default the last element for the
179179
# generated if/elif/else code.
180180
kwargs["default"] = default
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
module coreir_reg #(
2+
parameter width = 1,
3+
parameter clk_posedge = 1,
4+
parameter init = 1
5+
) (
6+
input clk,
7+
input [width-1:0] in,
8+
output [width-1:0] out
9+
);
10+
reg [width-1:0] outReg=init;
11+
wire real_clk;
12+
assign real_clk = clk_posedge ? clk : ~clk;
13+
always @(posedge real_clk) begin
14+
outReg <= in;
15+
end
16+
assign out = outReg;
17+
endmodule
18+
19+
module Register (
20+
input I,
21+
output O,
22+
input CLK
23+
);
24+
wire [0:0] reg_P1_inst0_out;
25+
coreir_reg #(
26+
.clk_posedge(1'b1),
27+
.init(1'h0),
28+
.width(1)
29+
) reg_P1_inst0 (
30+
.clk(CLK),
31+
.in(I),
32+
.out(reg_P1_inst0_out)
33+
);
34+
assign O = reg_P1_inst0_out[0];
35+
endmodule
36+
37+
module CompileGuardSelect_Bit_COND1_default (
38+
input I0,
39+
input I1,
40+
output O
41+
);
42+
`ifdef COND1
43+
assign O = I0;
44+
`else
45+
assign O = I1;
46+
`endif
47+
endmodule
48+
49+
module _Top (
50+
input I,
51+
output O,
52+
input CLK
53+
);
54+
wire Register_inst0_O;
55+
wire magma_Bit_xor_inst0_out;
56+
CompileGuardSelect_Bit_COND1_default CompileGuardSelect_Bit_COND1_default_inst0 (
57+
.I0(Register_inst0_O),
58+
.I1(I),
59+
.O(O)
60+
);
61+
Register Register_inst0 (
62+
.I(magma_Bit_xor_inst0_out),
63+
.O(Register_inst0_O),
64+
.CLK(CLK)
65+
);
66+
assign magma_Bit_xor_inst0_out = I ^ 1'b1;
67+
endmodule
68+

tests/test_compile_guard.py

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -253,20 +253,50 @@ class _Top(m.Circuit):
253253

254254

255255
def test_compile_guard_select_basic():
256+
256257
class _Top(m.Circuit):
257258
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
258-
259259
x = m.Register(m.Bit)()(io.I ^ 1)
260260
y = m.Register(m.Bit)()(io.I)
261-
262-
io.O @= m.compile_guard_select(
263-
COND1=x, COND2=y, default=io.I
264-
)
261+
io.O @= m.compile_guard_select(COND1=x, COND2=y, default=io.I)
265262

266263
basename = "test_compile_guard_select_basic"
267264
m.compile(f"build/{basename}", _Top, inline=True)
268265
assert m.testing.check_files_equal(
269-
__file__, f"build/{basename}.v", f"gold/{basename}.v")
266+
__file__, f"build/{basename}.v", f"gold/{basename}.v"
267+
)
268+
269+
270+
def test_compile_guard_select_two_keys():
271+
272+
class _Top(m.Circuit):
273+
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
274+
x = m.Register(m.Bit)()(io.I ^ 1)
275+
io.O @= m.compile_guard_select(COND1=x, default=io.I)
276+
277+
basename = "test_compile_guard_select_two_keys"
278+
m.compile(f"build/{basename}", _Top, inline=True)
279+
assert m.testing.check_files_equal(
280+
__file__, f"build/{basename}.v", f"gold/{basename}.v"
281+
)
282+
283+
284+
def test_compile_guard_select_no_default():
285+
with pytest.raises(KeyError):
286+
287+
class _Top(m.Circuit):
288+
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
289+
x = m.Register(m.Bit)()(io.I ^ 1)
290+
io.O @= m.compile_guard_select(COND1=x)
291+
292+
293+
def test_compile_guard_select_only_default():
294+
with pytest.raises(KeyError):
295+
296+
class _Top(m.Circuit):
297+
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
298+
x = m.Register(m.Bit)()(io.I ^ 1)
299+
io.O @= m.compile_guard_select(default=x)
270300

271301

272302
def test_compile_guard_select_complex_type():
@@ -277,7 +307,8 @@ def make_top():
277307
class _Top(m.Circuit):
278308
io = m.IO(I0=m.In(T), I1=m.In(T), O=m.Out(T))
279309
io.O @= m.compile_guard_select(
280-
COND1=io.I0, COND2=io.I1, default=io.I0)
310+
COND1=io.I0, COND2=io.I1, default=io.I0
311+
)
281312

282313
with pytest.raises(TypeError):
283314
make_top()

0 commit comments

Comments
 (0)