Skip to content
Draft
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
66 changes: 65 additions & 1 deletion lib/Conversion/ImportVerilog/Expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,71 @@ Value Context::convertToSimpleBitVector(Value value) {
value);
}
}

if (llvm::isa<moore::StringType>(value.getType())) { // extract or readop
moore::ReadOp ReadOp;
if (auto ExtractOp =
llvm::dyn_cast<moore::ExtractOp>(value.getDefiningOp())) {
// if the value is index of a string array, the DefiningOp is ExtractOp
ReadOp = llvm::dyn_cast<moore::ReadOp>(
ExtractOp->getOperand(0).getDefiningOp());
} else {
ReadOp = llvm::dyn_cast<moore::ReadOp>(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<moore::BlockingAssignOp>(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<moore::ConversionOp>(
AssignOp->getOperand(1).getDefiningOp());
auto initValue = ConvertOp->getOperand(0);
if (llvm::isa<moore::RefType>(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<moore::ConversionOp>(
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<moore::ConversionOp>(
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<moore::ConversionOp>(
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<moore::ConversionOp>(value.getLoc(),
initValue.getType(), value);
}
}
mlir::emitError(value.getLoc()) << "expression of type " << value.getType()
<< " cannot be cast to a simple bit vector";
return {};
Expand Down
27 changes: 27 additions & 0 deletions lib/Conversion/ImportVerilog/FormatStrings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<slang::ast::NamedValueExpression>()) {
auto ops = builder.create<moore::ConversionOp>(
loc, moore::FormatStringType::get(context.builder.getContext()),
context.convertLvalueExpression(arg));
fragments.push_back(ops);
return success();
} else if (auto *concat =
arg.as_if<slang::ast::ConcatenationExpression>()) {
// concatenation may contain string literal or named value
moore::ConversionOp ops = nullptr;
for (auto &op : concat->operands()) {
if (auto *lit = op->as_if<slang::ast::StringLiteral>()) {
if (options.width)
return mlir::emitError(loc)
<< "string format specifier with width not supported";
emitLiteral(lit->getValue());
} else if (auto nvexp =
op->as_if<slang::ast::NamedValueExpression>()) {
ops = builder.create<moore::ConversionOp>(
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";

Expand Down
16 changes: 16 additions & 0 deletions test/Conversion/ImportVerilog/basic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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