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

[Sim] Replace sim.func.dpi.call with sim.func.call and improve a verifier, NFC #7452

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

uenoku
Copy link
Member

@uenoku uenoku commented Aug 7, 2024

Drop .dpi of sim.func.dpi.call since it now accepts func.func as well. This PR also adds nicer verifier for sim.func.call to check function types.

…fier

Just drop `.dpi` Since sim.func.dpi.call now accepts func.func as well.
Copy link
Member

@maerhart maerhart left a 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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`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
Copy link
Member

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?

Copy link
Member Author

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
Copy link
Member

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?

Copy link
Member Author

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)
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants