Skip to content

Commit

Permalink
[CompileGuard] Fix compile guard select key parsing
Browse files Browse the repository at this point in the history
See #1291. Fixes two-key case (previously unsupported), and adds and refactors
tests.
  • Loading branch information
rsetaluri committed Jul 26, 2023
1 parent 8393f22 commit dc5c244
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 10 deletions.
6 changes: 3 additions & 3 deletions magma/compile_guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ def compile_guard_select(**kwargs):
try:
default = kwargs.pop("default")
except KeyError:
raise ValueError("Expected default argument") from None
if not (len(kwargs) > 1):
raise ValueError("Expected at least one key besides default")
raise KeyError("Expected default argument") from None
if not kwargs: # kwargs is empty
raise KeyError("Expected at least one key besides default")
# We rely on insertion order to make the default the last element for the
# generated if/elif/else code.
kwargs["default"] = default
Expand Down
68 changes: 68 additions & 0 deletions tests/gold/test_compile_guard_select_two_keys.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module coreir_reg #(
parameter width = 1,
parameter clk_posedge = 1,
parameter init = 1
) (
input clk,
input [width-1:0] in,
output [width-1:0] out
);
reg [width-1:0] outReg=init;
wire real_clk;
assign real_clk = clk_posedge ? clk : ~clk;
always @(posedge real_clk) begin
outReg <= in;
end
assign out = outReg;
endmodule

module Register (
input I,
output O,
input CLK
);
wire [0:0] reg_P1_inst0_out;
coreir_reg #(
.clk_posedge(1'b1),
.init(1'h0),
.width(1)
) reg_P1_inst0 (
.clk(CLK),
.in(I),
.out(reg_P1_inst0_out)
);
assign O = reg_P1_inst0_out[0];
endmodule

module CompileGuardSelect_Bit_COND1_default (
input I0,
input I1,
output O
);
`ifdef COND1
assign O = I0;
`else
assign O = I1;
`endif
endmodule

module _Top (
input I,
output O,
input CLK
);
wire Register_inst0_O;
wire magma_Bit_xor_inst0_out;
CompileGuardSelect_Bit_COND1_default CompileGuardSelect_Bit_COND1_default_inst0 (
.I0(Register_inst0_O),
.I1(I),
.O(O)
);
Register Register_inst0 (
.I(magma_Bit_xor_inst0_out),
.O(Register_inst0_O),
.CLK(CLK)
);
assign magma_Bit_xor_inst0_out = I ^ 1'b1;
endmodule

45 changes: 38 additions & 7 deletions tests/test_compile_guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,20 +253,50 @@ class _Top(m.Circuit):


def test_compile_guard_select_basic():

class _Top(m.Circuit):
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()

x = m.Register(m.Bit)()(io.I ^ 1)
y = m.Register(m.Bit)()(io.I)

io.O @= m.compile_guard_select(
COND1=x, COND2=y, default=io.I
)
io.O @= m.compile_guard_select(COND1=x, COND2=y, default=io.I)

basename = "test_compile_guard_select_basic"
m.compile(f"build/{basename}", _Top, inline=True)
assert m.testing.check_files_equal(
__file__, f"build/{basename}.v", f"gold/{basename}.v")
__file__, f"build/{basename}.v", f"gold/{basename}.v"
)


def test_compile_guard_select_two_keys():

class _Top(m.Circuit):
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
x = m.Register(m.Bit)()(io.I ^ 1)
io.O @= m.compile_guard_select(COND1=x, default=io.I)

basename = "test_compile_guard_select_two_keys"
m.compile(f"build/{basename}", _Top, inline=True)
assert m.testing.check_files_equal(
__file__, f"build/{basename}.v", f"gold/{basename}.v"
)


def test_compile_guard_select_no_default():
with pytest.raises(KeyError):

class _Top(m.Circuit):
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
x = m.Register(m.Bit)()(io.I ^ 1)
io.O @= m.compile_guard_select(COND1=x)


def test_compile_guard_select_only_default():
with pytest.raises(KeyError):

class _Top(m.Circuit):
io = m.IO(I=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
x = m.Register(m.Bit)()(io.I ^ 1)
io.O @= m.compile_guard_select(default=x)


def test_compile_guard_select_complex_type():
Expand All @@ -277,7 +307,8 @@ def make_top():
class _Top(m.Circuit):
io = m.IO(I0=m.In(T), I1=m.In(T), O=m.Out(T))
io.O @= m.compile_guard_select(
COND1=io.I0, COND2=io.I1, default=io.I0)
COND1=io.I0, COND2=io.I1, default=io.I0
)

with pytest.raises(TypeError):
make_top()
Expand Down

0 comments on commit dc5c244

Please sign in to comment.