diff --git a/lib/Conversion/ImportVerilog/Statements.cpp b/lib/Conversion/ImportVerilog/Statements.cpp index fe1bc80f5d2c..03d99d98914d 100644 --- a/lib/Conversion/ImportVerilog/Statements.cpp +++ b/lib/Conversion/ImportVerilog/Statements.cpp @@ -207,9 +207,32 @@ struct StmtVisitor { case CaseStatementCondition::WildcardJustZ: cond = builder.create(itemLoc, caseExpr, value); break; - case CaseStatementCondition::Inside: - mlir::emitError(loc, "unsupported set membership case statement"); - return failure(); + std::vector 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(loc, caseExpr, + values.front()); + } else { + cond = + builder.create(loc, caseExpr, values[0]); + for (size_t i = 1; i < values.size(); ++i) { + auto nextCond = + builder.create(loc, caseExpr, values[i]); + cond = builder.create(loc, cond, nextCond); + } + } } cond = builder.create(itemLoc, builder.getI1Type(), cond); diff --git a/test/Conversion/ImportVerilog/basic.sv b/test/Conversion/ImportVerilog/basic.sv index 7959351f000c..6aa1ef056069 100644 --- a/test/Conversion/ImportVerilog/basic.sv +++ b/test/Conversion/ImportVerilog/basic.sv @@ -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 +endmodule