mirror of https://github.com/llvm/circt.git
[ImportVerilog] Add case statement.
This commit is contained in:
parent
80c6602d37
commit
e2b0f3230b
|
@ -110,6 +110,59 @@ struct StmtVisitor {
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle case statements.
|
||||||
|
LogicalResult visit(const slang::ast::CaseStatement &caseStmt) {
|
||||||
|
auto caseExpr = context.convertExpression(caseStmt.expr);
|
||||||
|
auto items = caseStmt.items;
|
||||||
|
// Used to generate the condition of the default case statement.
|
||||||
|
SmallVector<Value> defaultConds;
|
||||||
|
// Traverse the case items.
|
||||||
|
for (auto item : items) {
|
||||||
|
// One statement will be matched with multi-conditions.
|
||||||
|
// Like case(cond) 0, 1 : y = x; endcase.
|
||||||
|
SmallVector<Value> allConds;
|
||||||
|
for (const auto *expr : item.expressions) {
|
||||||
|
auto itemExpr = context.convertExpression(*expr);
|
||||||
|
auto newEqOp = builder.create<moore::EqOp>(loc, caseExpr, itemExpr);
|
||||||
|
allConds.push_back(newEqOp);
|
||||||
|
}
|
||||||
|
// Bound all conditions of an item into one.
|
||||||
|
auto cond = allConds.back();
|
||||||
|
allConds.pop_back();
|
||||||
|
while (!allConds.empty()) {
|
||||||
|
cond = builder.create<moore::OrOp>(loc, allConds.back(), cond);
|
||||||
|
allConds.pop_back();
|
||||||
|
}
|
||||||
|
// Gather all items' conditions.
|
||||||
|
defaultConds.push_back(cond);
|
||||||
|
cond =
|
||||||
|
builder.create<moore::ConversionOp>(loc, builder.getI1Type(), cond);
|
||||||
|
auto ifOp = builder.create<mlir::scf::IfOp>(loc, cond);
|
||||||
|
OpBuilder::InsertionGuard guard(builder);
|
||||||
|
builder.setInsertionPoint(ifOp.thenYield());
|
||||||
|
if (failed(context.convertStatement(*item.stmt)))
|
||||||
|
return failure();
|
||||||
|
}
|
||||||
|
// Handle the 'default case' statement if it exists.
|
||||||
|
if (caseStmt.defaultCase) {
|
||||||
|
auto cond = defaultConds.back();
|
||||||
|
defaultConds.pop_back();
|
||||||
|
while (!defaultConds.empty()) {
|
||||||
|
cond = builder.create<moore::OrOp>(loc, defaultConds.back(), cond);
|
||||||
|
defaultConds.pop_back();
|
||||||
|
}
|
||||||
|
cond = builder.create<moore::NotOp>(loc, cond);
|
||||||
|
cond =
|
||||||
|
builder.create<moore::ConversionOp>(loc, builder.getI1Type(), cond);
|
||||||
|
auto ifOp = builder.create<mlir::scf::IfOp>(loc, cond);
|
||||||
|
OpBuilder::InsertionGuard guard(builder);
|
||||||
|
builder.setInsertionPoint(ifOp.thenYield());
|
||||||
|
if (failed(context.convertStatement(*caseStmt.defaultCase)))
|
||||||
|
return failure();
|
||||||
|
}
|
||||||
|
return success();
|
||||||
|
}
|
||||||
|
|
||||||
// Handle `for` loops.
|
// Handle `for` loops.
|
||||||
LogicalResult visit(const slang::ast::ForLoopStatement &stmt) {
|
LogicalResult visit(const slang::ast::ForLoopStatement &stmt) {
|
||||||
if (!stmt.loopVars.empty())
|
if (!stmt.loopVars.empty())
|
||||||
|
|
|
@ -129,6 +129,57 @@ module Statements;
|
||||||
x = z;
|
x = z;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
//===------------------------------------------------------------------===//
|
||||||
|
// Case statements
|
||||||
|
|
||||||
|
// CHECK: [[TMP1:%.+]] = moore.eq %x, %x : !moore.bit -> !moore.bit
|
||||||
|
// CHECK: [[TMP2:%.+]] = moore.conversion [[TMP1]] : !moore.bit -> i1
|
||||||
|
// CHECK: scf.if [[TMP2]] {
|
||||||
|
// CHECK: moore.blocking_assign %x, %x : !moore.bit
|
||||||
|
// CHECK: }
|
||||||
|
// CHECK: [[TMP3:%.+]] = moore.eq %x, %x : !moore.bit -> !moore.bit
|
||||||
|
// CHECK: [[TMP4:%.+]] = moore.eq %x, %y : !moore.bit -> !moore.bit
|
||||||
|
// CHECK: [[TMP5:%.+]] = moore.or [[TMP3]], [[TMP4]] : !moore.bit
|
||||||
|
// CHECK: [[TMP6:%.+]] = moore.conversion [[TMP5]] : !moore.bit -> i1
|
||||||
|
// CHECK: scf.if [[TMP6]] {
|
||||||
|
// CHECK: moore.blocking_assign %x, %y : !moore.bit
|
||||||
|
// CHECK: }
|
||||||
|
case (x)
|
||||||
|
x: x = x;
|
||||||
|
x, y: x = y;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
// CHECK: [[TMP1:%.+]] = moore.eq %x, %x : !moore.bit -> !moore.bit
|
||||||
|
// CHECK: [[TMP2:%.+]] = moore.conversion [[TMP1]] : !moore.bit -> i1
|
||||||
|
// CHECK: scf.if [[TMP2]] {
|
||||||
|
// CHECK: moore.blocking_assign %x, %x : !moore.bit
|
||||||
|
// CHECK: }
|
||||||
|
// CHECK: [[TMP3:%.+]] = moore.eq %x, %x : !moore.bit -> !moore.bit
|
||||||
|
// CHECK: [[TMP4:%.+]] = moore.eq %x, %y : !moore.bit -> !moore.bit
|
||||||
|
// CHECK: [[TMP5:%.+]] = moore.or [[TMP3]], [[TMP4]] : !moore.bit
|
||||||
|
// CHECK: [[TMP6:%.+]] = moore.conversion [[TMP5]] : !moore.bit -> i1
|
||||||
|
// CHECK: scf.if [[TMP6]] {
|
||||||
|
// CHECK: moore.blocking_assign %x, %y : !moore.bit
|
||||||
|
// CHECK: }
|
||||||
|
// CHECK: [[TMP7:%.+]] = moore.eq %x, %z : !moore.bit -> !moore.bit
|
||||||
|
// CHECK: [[TMP8:%.+]] = moore.conversion [[TMP7]] : !moore.bit -> i1
|
||||||
|
// CHECK: scf.if [[TMP8]] {
|
||||||
|
// CHECK: moore.blocking_assign %x, %z : !moore.bit
|
||||||
|
// CHECK: }
|
||||||
|
// CHECK: [[TMP9:%.+]] = moore.or [[TMP5]], [[TMP7]] : !moore.bit
|
||||||
|
// CHECK: [[TMP10:%.+]] = moore.or [[TMP1]], [[TMP9]] : !moore.bit
|
||||||
|
// CHECK: [[TMP11:%.+]] = moore.not [[TMP10]] : !moore.bit
|
||||||
|
// CHECK: [[TMP12:%.+]] = moore.conversion [[TMP11]] : !moore.bit -> i1
|
||||||
|
// CHECK: scf.if [[TMP12]] {
|
||||||
|
// CHECK: moore.blocking_assign %x, %x : !moore.bit
|
||||||
|
// CHECK: }
|
||||||
|
case (x)
|
||||||
|
x: x = x;
|
||||||
|
x, y: x = y;
|
||||||
|
z: x = z;
|
||||||
|
default x = x;
|
||||||
|
endcase
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// Loop statements
|
// Loop statements
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue