diff --git a/lib/Conversion/ImportVerilog/Expressions.cpp b/lib/Conversion/ImportVerilog/Expressions.cpp index ed3f0076860e..b0a93eb66722 100644 --- a/lib/Conversion/ImportVerilog/Expressions.cpp +++ b/lib/Conversion/ImportVerilog/Expressions.cpp @@ -1272,7 +1272,71 @@ Value Context::convertToSimpleBitVector(Value value) { value); } } - + if (llvm::isa(value.getType())) { // extract or readop + moore::ReadOp ReadOp; + if (auto ExtractOp = + llvm::dyn_cast(value.getDefiningOp())) { + // if the value is index of a string array, the DefiningOp is ExtractOp + ReadOp = llvm::dyn_cast( + ExtractOp->getOperand(0).getDefiningOp()); + } else { + ReadOp = llvm::dyn_cast(value.getDefiningOp()); + } + if (auto VarOp = ReadOp->getOperand(0).getDefiningOp()) { + Operation *AssignOp = nullptr; + for (auto user : VarOp->getResults().getUsers()) { + // find the assign op + if (llvm::isa(user)) { + AssignOp = user; + } + } + if (VarOp->use_empty()) { + // if the string is not initialized, the VarOp->getOperands().size() == + // 0 so we need to find assign op to get the value + if (AssignOp == nullptr) { + mlir::emitError(value.getLoc()) << "nullValue\n"; + return {}; + } else { + auto ConvertOp = llvm::dyn_cast( + AssignOp->getOperand(1).getDefiningOp()); + auto initValue = ConvertOp->getOperand(0); + if (llvm::isa(initValue.getType())) { + // if the initValue is a ref type, we need to get the actual value + auto ActualOp = initValue.getDefiningOp(); + auto RefVarOp = ActualOp->getOperand(0).getDefiningOp(); + initValue = RefVarOp->getOperand(0); + } + return builder.create( + value.getLoc(), initValue.getType(), value); + } + } + mlir::Value initValue; + if (AssignOp == nullptr) { + // if the string no assign op ,use initial value + if (auto ConvertOp = llvm::dyn_cast( + VarOp->getOperand(0).getDefiningOp())) { + initValue = ConvertOp->getOperand(0); + } else { + mlir::emitError(value.getLoc()) + << "not support " << VarOp->getOperand(0).getType() + << " as a string\n"; + return {}; + } + } else { + if (auto ConvertOp = llvm::dyn_cast( + AssignOp->getOperand(1).getDefiningOp())) { + initValue = ConvertOp->getOperand(0); + } else { + mlir::emitError(value.getLoc()) + << "not support " << AssignOp->getOperand(1).getType() + << " as a string\n"; + return {}; + } + } + return builder.create(value.getLoc(), + initValue.getType(), value); + } + } mlir::emitError(value.getLoc()) << "expression of type " << value.getType() << " cannot be cast to a simple bit vector"; return {}; diff --git a/lib/Conversion/ImportVerilog/FormatStrings.cpp b/lib/Conversion/ImportVerilog/FormatStrings.cpp index 7698ad142b71..a675f0a519c0 100644 --- a/lib/Conversion/ImportVerilog/FormatStrings.cpp +++ b/lib/Conversion/ImportVerilog/FormatStrings.cpp @@ -137,7 +137,34 @@ struct FormatStringParser { << "string format specifier with width not supported"; emitLiteral(lit->getValue()); return success(); + } else if (auto nvexp = arg.as_if()) { + auto ops = builder.create( + loc, moore::FormatStringType::get(context.builder.getContext()), + context.convertLvalueExpression(arg)); + fragments.push_back(ops); + return success(); + } else if (auto *concat = + arg.as_if()) { + // concatenation may contain string literal or named value + moore::ConversionOp ops = nullptr; + for (auto &op : concat->operands()) { + if (auto *lit = op->as_if()) { + if (options.width) + return mlir::emitError(loc) + << "string format specifier with width not supported"; + emitLiteral(lit->getValue()); + } else if (auto nvexp = + op->as_if()) { + ops = builder.create( + loc, moore::FormatStringType::get(context.builder.getContext()), + context.convertLvalueExpression(arg)); + } + } + if (ops != nullptr) // if there is {str,str1},only need to push one + fragments.push_back(ops); // ops,another will be remove after + return success(); } + return mlir::emitError(argLoc) << "expression cannot be formatted as string"; diff --git a/test/Conversion/ImportVerilog/basic.sv b/test/Conversion/ImportVerilog/basic.sv index 36dde1665f9b..80461148e977 100644 --- a/test/Conversion/ImportVerilog/basic.sv +++ b/test/Conversion/ImportVerilog/basic.sv @@ -2338,3 +2338,19 @@ module RangeElementSelection( b[3:0] = b[c[0]-:2]; end endmodule + +module displayfunction(); + +bit [8*14:1] a; +bit [8*14:1] b; +string c; +initial begin + a = "Test"; + b = "TEST"; + c = {"Hello", "_", "World", "!"}; + $display(":assert: ('TEST' in '%s')", {"a", "b"}); + $display(":assert: ('Test' in '%s')", {a, b}); + $display(":assert:('%s' == 'Hello_World!')", c); +end + +endmodule \ No newline at end of file