Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SystemVerilog functions: LRM query

73 views
Skip to first unread message

Chris Higgs

unread,
Feb 6, 2012, 12:39:56 PM2/6/12
to
Greetings,

I'm want to call a function from another function. Both functions are
void and have inout arguments. VCS doesn't seem to complain, however
Quartus balks saying that "functions can't enable tasks" (the code is
synthesisable).

Referring back to the LRM doesn't leave me wiser as to whether Quartus
is legitimately throwing a wobbly. From section 10.3:

"It shall be illegal to call a function with output, inout or ref
arguments in an event expression, in an expression
within a procedural continuous assignment, or in an expression that is
not within a procedural statement."

Does this mean that if I call function "foo" from within a procedural
statement that "foo" cannot subsequently call function "bar"?

Thanks,

Chris

Jonathan Bromley

unread,
Feb 9, 2012, 4:02:14 PM2/9/12
to
On Mon, 6 Feb 2012 09:39:56 -0800 (PST), Chris Higgs wrote:

>I'm want to call a function from another function. Both functions are
>void and have inout arguments. VCS doesn't seem to complain, however
>Quartus balks saying that "functions can't enable tasks" (the code is
>synthesisable).
>
>Referring back to the LRM doesn't leave me wiser as to whether Quartus
>is legitimately throwing a wobbly.

Whatever you've done, Quartus's message is silly. If your inner
subprogram really is "function void" then it isn't a task, and the
error message is ridiculous.

>"It shall be illegal to call a function with output, inout or ref
>arguments in an event expression, in an expression
>within a procedural continuous assignment, or in an expression that is
>not within a procedural statement."
>
>Does this mean that if I call function "foo" from within a procedural
>statement that "foo" cannot subsequently call function "bar"?

No, it just says that you can't have a function writing to its
actual arguments in a situation where you don't know exactly
when the function is going to get called. That would lead to
fairly mad nondeterminism.

Any chance of a code snippet? Did you try it in any other
tool than Quartus?
--
Jonathan Bromley

Chris Higgs

unread,
Feb 10, 2012, 1:11:58 PM2/10/12
to
On Feb 9, 9:02 pm, Jonathan Bromley <s...@oxfordbromley.plus.com>
wrote:
> Whatever you've done, Quartus's message is silly.  If your inner
> subprogram really is "function void" then it isn't a task, and the
> error message is ridiculous.

Indeed, the error message is completely erroneous.

> No, it just says that you can't have a function writing to its
> actual arguments in a situation where you don't know exactly
> when the function is going to get called.  That would lead to
> fairly mad nondeterminism.

Yup, I suspected that was the case but wasn't completely convinced
after reading the LRM carefully that it was entirely unambiguous. It
would be a pretty severe limitation otherwise!

> Any chance of a code snippet?  Did you try it in any other
> tool than Quartus?

Code below, which VCS is happy compiling. I've raised an SR with
Altera who are yet to confirm that it's a Quartus bug.

Thanks for response,

Chris

<code>
module function_example(
input clk,
input [15:0] data,
output [15:0] result);

typedef enum {
STATE1,
STATE2
} state_enum_e;

typedef struct {
state_enum_e state;
logic [15:0] scratch;
} state_t;

state_t state, next_state;

function void handle_state1(input logic [15:0] somedata, inout state_t
self);
self.scratch = somedata;
self.state = STATE2;
endfunction

function void handle_state2(input logic [15:0] somedata, inout state_t
self);
self.scratch &= somedata;
self.state = STATE1;
endfunction

function void dispatcher(input logic [15:0] somedata, inout state_t
self);
case (self.state)
STATE1: handle_state1(somedata, self);
STATE2: handle_state2(somedata, self);
default: self.state = STATE1;
endcase
endfunction

always_comb begin
next_state = state;
dispatcher(data, next_state);
end

always_ff @(posedge clk)
begin
state <= next_state;
end

assign result = state.scratch;

endmodule

</code>

Chris Higgs

unread,
Feb 28, 2012, 7:32:24 AM2/28/12
to
An update for reference: Quartus interprets a void function as a task
and therefore (erroneously) applies the LRM restrictions on calling
tasks to the function.

A workaround is to make the function non-void by returning a value
(even if the value is subsequently discarded).
0 new messages