-
Notifications
You must be signed in to change notification settings - Fork 299
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
[ExportVerilog] Support sv.func.* op emission #7015
Conversation
ba2358e
to
3dbbeb7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really an expert on this, but apart from a few nits, the fact that you should update this wrt. the llvm bump fixes and llvm itself to make sure that it won't break on merge, and clang-tidy, LGTM.
if (dyn_cast_or_null<HWInstanceLike>(op.getSrc().getDefiningOp())) | ||
// prepare assigns wires to instance outputs and function results, but these | ||
// are logically handled in the port binding list when outputing an instance. | ||
if (isa_and_nonnull<HWInstanceLike, FuncCallOp>(op.getSrc().getDefiningOp())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Is the second type argument really necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's necessary. FuncCall op emissions follows a similar emission implementation to HWInstanceOp. The assignments are emitted in FuncCallOp emission so we need to skip here.
auto printArg = [&](Value value) { | ||
if (needsComma) | ||
ps << "," << PP::space; | ||
emitExpression(value, ops); | ||
needsComma = true; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
won't this lead to a trailing comma? Could you maybe do something using the argument index instead to figure out if you need a comma or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question! I think it will not produce training comma since a comma is always emitted before an operand.
ps << *linkageName << PP::nbsp << "=" << PP::nbsp; | ||
auto op = | ||
cast<FuncOp>(state.symbolCache.getDefinition(importOp.getCalleeAttr())); | ||
assert(op.isDeclaration() && "function must be a declaration"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think I've seen this way of adding assert messages before lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is per LLVM coding style: https://llvm.org/docs/CodingStandards.html#assert-liberally
startStatement(); | ||
ps.addCallback({func, true}); | ||
// A function is moduled as an automatic function. | ||
emitFunctionSignature(*this, ps, func, /*isAutomatic=*/true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: commented code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding an argument name as a comment is encouraged for boolean parameter: https://llvm.org/docs/CodingStandards.html#comment-formatting
3390da4
to
75cdb7d
Compare
…eForEmission accordingly
b5bfc8c
to
0724cf4
Compare
ef06699
to
3767a5b
Compare
Co-authored-by: Will Dietz <will.dietz@sifive.com>
I'd like to merge. Post-merge review is also appreciated! |
This PR (separated from #6977) implements ExportVerilog support of sv.func, sv.func.dpi.import, sv.func.call and sv.func.call.procedural.
sv.func emission is similar to hw.module but one difference is a return value. Surprisingly in SV a function name is used as a placeholder for a return value so name legalization properly sets
hw.verilogName
of a returned value to a function name.Result names of sv.func.call.procedural are attached to temporary registers created in PrepareForEmission. This is similar implementation approach as hw.instance.
A part of PrepareForEmission and ExportVerilog is ported from #4856