Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Moore] Support the display system task. #7600

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
36 changes: 36 additions & 0 deletions include/circt/Dialect/Moore/MooreOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1329,4 +1329,40 @@ def YieldOp : MooreOp<"yield", [
let hasVerifier = 1;
}

//===----------------------------------------------------------------------===//
// Input/Output system tasks
//===----------------------------------------------------------------------===//

class PrintOpBase<string mnemonic, list<Trait> traits = []> :
MooreOp<mnemonic, traits # [
HasParent<"ProcedureOp">
]> {
let arguments = (ins
OptionalAttr<StrAttr>:$information,
Variadic<UnpackedType>:$data
);

let assemblyFormat = [{
($information^)? (`(` $data^ `)` `:`)? attr-dict type($data)
}];
}

def DisplayOp : PrintOpBase<"display"> {
let description = [{
The $disply system task displays information with an implicit line feed.
It has four forms, such as $display, $displayb(binary), $displayo(octal),
and $displayh(hexadecimal).
See IEEE 1800-2017 § 21.2.1 "The display and write tasks".
}];
}

def WriteOp : PrintOpBase<"write"> {
let description = [{
The $write system task also displays information, but it doesn't have an
implicit line feed. It has $write, $writeb, $writeo, and $writeh forms.
See IEEE 1800-2017 § 21.2.1 "The display and write tasks".
}];
}


#endif // CIRCT_DIALECT_MOORE_MOOREOPS
34 changes: 33 additions & 1 deletion lib/Conversion/ImportVerilog/Expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,31 @@ struct RvalueExprVisitor {
if (subroutine.name == "$signed" || subroutine.name == "$unsigned")
return context.convertRvalueExpression(*expr.arguments()[0]);

if (subroutine.name == "$display" || subroutine.name == "$displayb" ||
subroutine.name == "$displayo" || subroutine.name == "$displayh") {
StringAttr information;
SmallVector<Value> datas;
for (auto *arg : expr.arguments()) {
if (auto *strNode = arg->as_if<slang::ast::StringLiteral>()) {
information = builder.getStringAttr(strNode->getValue());
continue;
}
auto rvalue = context.convertRvalueExpression(*arg);
if (rvalue)
datas.push_back(rvalue);
}
if (!datas.empty() || information)
builder.create<moore::DisplayOp>(loc, information, datas);

// Return a variable with the void type to "expression statements", which
// will be removed later. This ensures we can look at the correct IR.
slang::ast::VoidType vt;
Type voidType = context.convertType(vt);
return builder.create<moore::VariableOp>(
loc, moore::RefType::get(cast<moore::UnpackedType>(voidType)),
StringAttr{}, Value{});
}

mlir::emitError(loc) << "unsupported system call `" << subroutine.name
<< "`";
return {};
Expand All @@ -769,7 +794,7 @@ struct RvalueExprVisitor {
auto elementCount = expr.elements().size();
SmallVector<Value> elements;
elements.reserve(replCount * elementCount);
for (auto elementExpr : expr.elements()) {
for (auto *elementExpr : expr.elements()) {
auto value = context.convertRvalueExpression(*elementExpr);
if (!value)
return {};
Expand Down Expand Up @@ -823,6 +848,13 @@ struct RvalueExprVisitor {
return visitAssignmentPattern(expr, *count);
}

// FIXME: It occurs in something like display tasks.
// Maybe have other situations? So I left a warning.
Value visit(const slang::ast::EmptyArgumentExpression &) {
mlir::emitWarning(loc, "Encounter an empty expression crash");
return {};
}

/// Emit an error for all other expressions.
template <typename T>
Value visit(T &&node) {
Expand Down
38 changes: 38 additions & 0 deletions test/Conversion/ImportVerilog/basic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1904,3 +1904,41 @@ task automatic ImplicitEventControlExamples();
x[a] = !b;
end
endtask

// CHECK-LABEL: moore.module @Display() {
module Display();
int a;
// CHECK: [[L:%.+]] = moore.variable : <uarray<8 x l1>>
logic l [7:0];
initial begin
// CHECK: [[READ_A1:%.+]] = moore.read %a : <i32>
// CHECK: [[READ_A2:%.+]] = moore.read %a : <i32>
// CHECK: [[READ_A3:%.+]] = moore.read %a : <i32>
// CHECK: moore.display "The values of a, a, a are: %d%d%d"([[READ_A1]], [[READ_A2]], [[READ_A3]]) : !moore.i32, !moore.i32, !moore.i32
$display("The values of a, a, a are: %d%d%d", a, a, a);

// CHECK: [[C100:%.+]] = moore.constant 100 : i32
// CHECK: moore.display([[C100]]) : !moore.i32
$displayb(100);

// CHECK: [[READ_A4:%.+]] = moore.read %a : <i32>
// CHECK: moore.display "The value of a is: %b"([[READ_A4]]) : !moore.i32
$displayo("The value of a is: %b", a);

// CHECK: moore.display "Wellcome to Moore!!!"
$displayh("Wellcome to Moore!!!");

// CHECK: [[READ_L:%.+]] = moore.read [[L]] : <uarray<8 x l1>>
// CHECK: moore.display "l = %p"([[READ_L]]) : !moore.uarray<8 x l1>
$display("l = %p", l);

// CHECK-NOT: moore.display
$display();
// CHECK-NOT: moore.display
$display(,,);

// CHECK: [[C520:%.+]] = moore.constant 520 : i32
// CHECK: moore.display([[C520]])
$display(,520,);
end
endmodule
Loading