-
Notifications
You must be signed in to change notification settings - Fork 298
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
[Sim] Replace sim.func.dpi.call with sim.func.call and improve a verifier, NFC #7452
base: main
Are you sure you want to change the base?
Conversation
…fier Just drop `.dpi` Since sim.func.dpi.call now accepts func.func as well.
25f72a1
to
4b62e79
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.
From a more general perspective I'm wondering if the motivation to let this call operation call func.func
operations was only to get it lowered through Arc or whether there are other use-cases that will require this? Because there we could also lower it to func.call
directly with a bit more work and thus simplifying the sim.func.call
operation again (e.g., by placing a func.call
inside an arc.clock_domain
once it's fully supported). There'd probably be some value in keeping DPI functions and calls, and regular functions and calls separate (e.g., to keep the IR simple and elegant, and to not mix abstraction levels). But I'm also interested in what other people think about this.
The improved verifier is great regardless 🎉
let description = [{ | ||
`sim.func.dpi.call` represents SystemVerilog DPI function call. There are two | ||
optional operands `clock` and `enable`. | ||
`sim.func.call` represents a function call. Unlike a call operation in Func dialect, |
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.
`sim.func.call` represents a function call. Unlike a call operation in Func dialect, | |
`sim.func.call` represents a function call. Unlike a call operation in the Func dialect, |
`sim.func.dpi.call` represents SystemVerilog DPI function call. There are two | ||
optional operands `clock` and `enable`. | ||
`sim.func.call` represents a function call. Unlike a call operation in Func dialect, | ||
there are two optional operands `clock` and `enable`. | ||
|
||
If `clock` is not provided, the callee is invoked when input values are changed. |
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.
If `clock` is not provided, the callee is invoked when input values are changed. | |
If `clock` is not provided, the callee is invoked when any call argument value changes. |
`sim.func.dpi.call` represents SystemVerilog DPI function call. There are two | ||
optional operands `clock` and `enable`. | ||
`sim.func.call` represents a function call. Unlike a call operation in Func dialect, | ||
there are two optional operands `clock` and `enable`. | ||
|
||
If `clock` is not provided, the callee is invoked when input values are changed. | ||
If provided, the DPI function is called at clock's posedge. The result values behave |
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.
If provided, the DPI function is called at clock's posedge. The result values behave | |
If provided, the DPI function is called at the clock's posedge. The result values behave |
`enable` operand is used to conditionally call the DPI since DPI call could be quite | ||
more expensive than native constructs. When `enable` is low, results of unclocked | ||
calls are undefined and in SV results they are lowered into `X`. Users are expected | ||
`enable` operand is used to conditionally call the function since function call |
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.
`enable` operand is used to conditionally call the function since function call | |
The `enable` operand is used to conditionally call the function since the call |
calls are undefined and in SV results they are lowered into `X`. Users are expected | ||
`enable` operand is used to conditionally call the function since function call | ||
could be quite more expensive than native constructs. When `enable` is low, results | ||
of unclocked calls are undefined and in SV they are lowered into `X`. Users are expected |
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 assume the same kind of 'undefined' as division by zero and out-of-bounds array accesses?
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 belong to the same kind to div-by-zero. I intended undefined values definition in comb https://circt.llvm.org/docs/Dialects/Comb/RationaleComb/#undefined-values. I'll mention it in here.
calls are undefined and in SV results they are lowered into `X`. Users are expected | ||
`enable` operand is used to conditionally call the function since function call | ||
could be quite more expensive than native constructs. When `enable` is low, results | ||
of unclocked calls are undefined and in SV they are lowered into `X`. Users are expected |
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'm not really convinced that specifying how something is lowered to SV is a good way to specify an operation's semantics. Is it possible to define the semantics independent of SV in a way that allows this as a potential lowering?
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.
That's great point, thank you for suggestion!
hw.module @dpi_call(in %clock : !seq.clock, in %in: i1) { | ||
// expected-error @below {{'sim.func.call' op result type mismatch at index 1}} | ||
// expected-note @below {{op result types: 'i1', 'i1'}} | ||
%0, %1 = sim.func.call @mismatch(%in) : (i1) -> (i1, i1) |
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.
The "incorrect number of ..." error messages are not tested here.
Drop
.dpi
ofsim.func.dpi.call
since it now acceptsfunc.func
as well. This PR also adds nicer verifier for sim.func.call to check function types.