Merge pull request #831 from larsclausen/void-func-always-comb
Let void functions in always_comb block contribute to sensitivity list
This commit is contained in:
commit
4ce8fa255a
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Check that variables referenced in a void function contribute to the
|
||||||
|
// sensitivity list of a always_comb block.
|
||||||
|
|
||||||
|
module top;
|
||||||
|
logic passed;
|
||||||
|
logic [7:0] value;
|
||||||
|
integer counter;
|
||||||
|
|
||||||
|
function automatic void count(bit what);
|
||||||
|
counter = 0;
|
||||||
|
for (integer i = 0; i < $bits(value); i++) begin
|
||||||
|
if (value[i] == what)
|
||||||
|
counter += 1;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
count(1'b1);
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
passed = 1'b1;
|
||||||
|
|
||||||
|
value = 8'b0000_0000;
|
||||||
|
#1;
|
||||||
|
if (counter !== 0) begin
|
||||||
|
$display("Expected 0, got %d", counter);
|
||||||
|
passed = 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
value = 8'b0011_1100;
|
||||||
|
#1;
|
||||||
|
if (counter !== 4) begin
|
||||||
|
$display("Expected 4, got %d", counter);
|
||||||
|
passed = 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
value = 8'b1011_1101;
|
||||||
|
#1;
|
||||||
|
if (counter !== 6) begin
|
||||||
|
$display("Expected 6, got %d", counter);
|
||||||
|
passed = 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (passed) begin
|
||||||
|
$display("PASSED");
|
||||||
|
end else begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -76,6 +76,7 @@ always_comb_fail4 CE,-g2005-sv ivltests
|
||||||
always_comb_no_sens nornal,-g2005-sv ivltests gold=always_comb_no_sens.gold
|
always_comb_no_sens nornal,-g2005-sv ivltests gold=always_comb_no_sens.gold
|
||||||
always_comb_rfunc nornal,-g2005-sv ivltests
|
always_comb_rfunc nornal,-g2005-sv ivltests
|
||||||
always_comb_trig normal,-g2005-sv ivltests
|
always_comb_trig normal,-g2005-sv ivltests
|
||||||
|
always_comb_void_func normal,-g2005-sv ivltests
|
||||||
always_comb_warn normal,-g2005-sv ivltests gold=always_comb_warn.gold
|
always_comb_warn normal,-g2005-sv ivltests gold=always_comb_warn.gold
|
||||||
always_ff normal,-g2005-sv ivltests
|
always_ff normal,-g2005-sv ivltests
|
||||||
always_ff_fail CE,-g2005-sv ivltests
|
always_ff_fail CE,-g2005-sv ivltests
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
|
|
||||||
# Verilog 95 does not support automatic tasks or functions.
|
# Verilog 95 does not support automatic tasks or functions.
|
||||||
always_comb_rfunc CE ivltests
|
always_comb_rfunc CE ivltests
|
||||||
|
always_comb_void_func CE ivltests
|
||||||
automatic_error11 CE ivltests
|
automatic_error11 CE ivltests
|
||||||
automatic_error12 CE ivltests
|
automatic_error12 CE ivltests
|
||||||
automatic_error13 CE ivltests
|
automatic_error13 CE ivltests
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,30 @@ NexusSet* NetETernary::nex_input(bool rem_out, bool always_sens, bool nested_fun
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the contribution of a function call in a always_comb block
|
||||||
|
static void func_always_sens(NetFuncDef *func, NexusSet *result,
|
||||||
|
bool rem_out, bool nested_func)
|
||||||
|
{
|
||||||
|
// Avoid recursive function calls.
|
||||||
|
static set<NetFuncDef*> func_set;
|
||||||
|
if (!nested_func)
|
||||||
|
func_set.clear();
|
||||||
|
|
||||||
|
if (!func_set.insert(func).second)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::unique_ptr<NexusSet> tmp(func->proc()->nex_input(rem_out, true, true));
|
||||||
|
// Remove the function inputs
|
||||||
|
std::unique_ptr<NexusSet> in(new NexusSet);
|
||||||
|
for (unsigned idx = 0; idx < func->port_count(); idx++) {
|
||||||
|
NetNet *net = func->port(idx);
|
||||||
|
assert(net->pin_count() == 1);
|
||||||
|
in->add(net->pin(0).nexus(), 0, net->vector_width());
|
||||||
|
}
|
||||||
|
tmp->rem(*in);
|
||||||
|
result->add(*tmp);
|
||||||
|
}
|
||||||
|
|
||||||
NexusSet* NetEUFunc::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
NexusSet* NetEUFunc::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||||
{
|
{
|
||||||
NexusSet*result = new NexusSet;
|
NexusSet*result = new NexusSet;
|
||||||
|
|
@ -265,31 +289,8 @@ NexusSet* NetEUFunc::nex_input(bool rem_out, bool always_sens, bool nested_func)
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (always_sens) {
|
if (always_sens)
|
||||||
NetFuncDef*func = func_->func_def();
|
func_always_sens(func_->func_def(), result, rem_out, nested_func);
|
||||||
|
|
||||||
// Avoid recursive function calls.
|
|
||||||
static set<NetFuncDef*> func_set;
|
|
||||||
if (!nested_func)
|
|
||||||
func_set.clear();
|
|
||||||
|
|
||||||
if (!func_set.insert(func).second)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
NexusSet*tmp = func->proc()->nex_input(rem_out, always_sens, true);
|
|
||||||
// Remove the function inputs
|
|
||||||
NexusSet*in = new NexusSet;
|
|
||||||
for (unsigned idx = 0 ; idx < func->port_count() ; idx += 1) {
|
|
||||||
NetNet*net = func->port(idx);
|
|
||||||
assert(net->pin_count() == 1);
|
|
||||||
in->add(net->pin(0).nexus(), 0, net->vector_width());
|
|
||||||
}
|
|
||||||
tmp->rem(*in);
|
|
||||||
delete in;
|
|
||||||
|
|
||||||
result->add(*tmp);
|
|
||||||
delete tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -613,9 +614,18 @@ NexusSet* NetSTask::nex_input(bool rem_out, bool always_sens, bool nested_func)
|
||||||
* parameters to consider, because the compiler already removed them
|
* parameters to consider, because the compiler already removed them
|
||||||
* and converted them to blocking assignments.
|
* and converted them to blocking assignments.
|
||||||
*/
|
*/
|
||||||
NexusSet* NetUTask::nex_input(bool, bool, bool) const
|
NexusSet* NetUTask::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||||
{
|
{
|
||||||
return new NexusSet;
|
NexusSet *result = new NexusSet;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let the contents of void functions contribute to the sensitivity list
|
||||||
|
* of always_comb blocks
|
||||||
|
*/
|
||||||
|
if (always_sens && task_->type() == NetScope::FUNC)
|
||||||
|
func_always_sens(task_->func_def(), result, rem_out, nested_func);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusSet* NetWhile::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
NexusSet* NetWhile::nex_input(bool rem_out, bool always_sens, bool nested_func) const
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue