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

[ImportVerilog] Add case inside #7928

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
29 changes: 26 additions & 3 deletions lib/Conversion/ImportVerilog/Statements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,32 @@ struct StmtVisitor {
case CaseStatementCondition::WildcardJustZ:
cond = builder.create<moore::CaseZEqOp>(itemLoc, caseExpr, value);
break;
case CaseStatementCondition::Inside:
mlir::emitError(loc, "unsupported set membership case statement");
return failure();
std::vector<Value> values;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SmallVector per MLIR coding guidelines.

values.reserve(item.expressions.size());
for (const auto *expr : item.expressions) {
auto value = context.convertRvalueExpression(*expr);
if (!value)
return failure();
values.push_back(value);
}

if (values.empty()) {
mlir::emitError(loc, "empty set in inside case statement");
return failure();
}

if (values.size() == 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This conditional could be completely eliminated.

cond = builder.create<moore::WildcardEqOp>(loc, caseExpr,
values.front());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why use front here and [0] two lines later?

} else {
cond =
builder.create<moore::WildcardEqOp>(loc, caseExpr, values[0]);
for (size_t i = 1; i < values.size(); ++i) {
auto nextCond =
builder.create<moore::WildcardEqOp>(loc, caseExpr, values[i]);
cond = builder.create<moore::OrOp>(loc, cond, nextCond);
}
}
}
cond = builder.create<moore::ConversionOp>(itemLoc, builder.getI1Type(),
cond);
Expand Down
69 changes: 69 additions & 0 deletions test/Conversion/ImportVerilog/basic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2232,3 +2232,72 @@ function int AssignFuncArgs2(int x, int y);
// CHECK: [[ADD:%.+]] = moore.add [[READ_X]], [[READ_Y]] : i32
return x+y;
endfunction

module priority_case_test;
// CHECK: logic clock
logic clock;
// CHECK: logic [2:0] status
logic [2:0] status;

task task1;
// CHECK: task1 executed
$display("task1 executed at time %0t", $time);
endtask

task task2;
// CHECK: task2 executed
$display("task2 executed at time %0t", $time);
endtask

initial begin
// CHECK: clock initialized to 0
clock = 0;
// CHECK: clock toggles every 5 ns
forever #5 clock = ~clock;
end

initial begin
// CHECK: Test Case 1: status = 3'b001
status = 3'b001;
@(posedge clock);

// CHECK: Test Case 2: status = 3'b011
status = 3'b011;
@(posedge clock);

// CHECK: Test Case 3: status = 3'b010 (matches task2)
status = 3'b010;
@(posedge clock);

// CHECK: Test Case 4: status = 3'b100 (matches task2)
status = 3'b100;
@(posedge clock);

// CHECK: Test Case 5: status = 3'b00x (no match)
status = 3'b00x;
@(posedge clock);

// CHECK: Test Case 6: status = 3'b111 (matches task2)
status = 3'b111;
@(posedge clock);

// CHECK: Test Case 7: status = 3'bxxx (no match)
status = 3'bxxx;
@(posedge clock);

// CHECK: End simulation
$finish;
end

always @(posedge clock) begin
// CHECK: Entering priority case
priority case (status)
// CHECK: Matches 3'b001 or 3'b011, executes task1
3'b001, 3'b011: task1;
// CHECK: Matches 3'b0?0 or [3'b100:3'b111], executes task2
3'b0?0, [3'b100:3'b111]: task2;
// CHECK: No match, default case
default: $display("No match for status = %b at time %0t", status, $time);
endcase
end
Comment on lines +2236 to +2302
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @ankolesn, thanks a lot for working on this! One comment regarding your unit test: we don't simulate the design as part of the unit test, so things like $display(...) will not show up as prints in the output. Instead, the unit tests check that the expected IR operations get generated. For your PR, I'd add different examples that exercise interesting corner cases of your implementation. If you look through basic.sv, you should find existing tests for case statements that can give you some inspiration on how to do that. Then you can check if your code generates the correct IR ops for inside case statements.

endmodule
Loading