Skip to content

Commit

Permalink
Add support CaseStatementCondition::Inside
Browse files Browse the repository at this point in the history
  • Loading branch information
ankolesn committed Dec 12, 2024
1 parent 515ce89 commit 83e9720
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 20 deletions.
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;
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) {
cond = builder.create<moore::WildcardEqOp>(loc, caseExpr,
values.front());
} 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
85 changes: 68 additions & 17 deletions test/Conversion/ImportVerilog/basic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2233,20 +2233,71 @@ function int AssignFuncArgs2(int x, int y);
return x+y;
endfunction

// CHECK-LABEL: moore.module @CaseStatementTest()
module CaseStatementTest;
bit [31:0] caseExpr, result;
// CHECK: [[CASE_EXPR:%.+]] = moore.read %caseExpr : <i32>
// CHECK: [[COND1:%.+]] = moore.caseeq [[CASE_EXPR]], {{.*}} : !moore.i32
// CHECK: [[COND2:%.+]] = moore.caseeq [[CASE_EXPR]], {{.*}} : !moore.i32
// CHECK: [[COND3:%.+]] = moore.caseeq [[CASE_EXPR]], {{.*}} : !moore.i32
// CHECK: [[OR1:%.+]] = arith.or [[COND1]], [[COND2]] : i1
// CHECK: [[FINAL_COND:%.+]] = arith.or [[OR1]], [[COND3]] : i1
// CHECK: moore.assign %result, [[FINAL_COND]] : i1
always_comb begin
case (caseExpr)
32'h1, 32'h2, 32'h3: result = 1;
default: result = 0;
endcase
end
endmodule
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
endmodule

0 comments on commit 83e9720

Please sign in to comment.