(#6194) Add automatic task unrolled test. Disable unrolling on fork.
This commit is contained in:
parent
a50ea2a1a6
commit
0818b0ad8b
|
@ -37,6 +37,7 @@ Chuxuan Wang
|
|||
Chykon
|
||||
Conor McCullough
|
||||
Dan Petrisko
|
||||
Danny Oler
|
||||
Daniel Bates
|
||||
Dave Sargeant
|
||||
David Horton
|
||||
|
|
|
@ -46,6 +46,7 @@ class UnrollVisitor final : public VNVisitor {
|
|||
bool m_varModeCheck; // Just checking RHS assignments
|
||||
bool m_varModeReplace; // Replacing varrefs
|
||||
bool m_varAssignHit; // Assign var hit
|
||||
bool m_forkHit; // Fork hit
|
||||
bool m_generate; // Expand single generate For loop
|
||||
string m_beginName; // What name to give begin iterations
|
||||
VDouble0 m_statLoops; // Statistic tracking
|
||||
|
@ -133,6 +134,7 @@ class UnrollVisitor final : public VNVisitor {
|
|||
// Now, make sure there's no assignment to this variable in the loop
|
||||
m_varModeCheck = true;
|
||||
m_varAssignHit = false;
|
||||
m_forkHit = false;
|
||||
m_ignoreIncp = incp;
|
||||
iterateAndNextNull(precondsp);
|
||||
iterateAndNextNull(bodysp);
|
||||
|
@ -141,6 +143,8 @@ class UnrollVisitor final : public VNVisitor {
|
|||
m_ignoreIncp = nullptr;
|
||||
if (m_varAssignHit) return cantUnroll(nodep, "genvar assigned *inside* loop");
|
||||
|
||||
if (m_forkHit) return cantUnroll(nodep, "fork inside loop");
|
||||
|
||||
//
|
||||
if (m_forVscp) {
|
||||
UINFO(8, " Loop Variable: " << m_forVscp);
|
||||
|
@ -463,6 +467,17 @@ class UnrollVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
void visit(AstFork* nodep) override {
|
||||
if (m_varModeCheck) {
|
||||
if (nodep->joinType().joinNone() || nodep->joinType().joinAny()) {
|
||||
// Forks are not allowed to unroll for loops, so we just set a flag
|
||||
m_forkHit = true;
|
||||
}
|
||||
} else {
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
void visit(AstNode* nodep) override {
|
||||
|
@ -489,6 +504,7 @@ public:
|
|||
m_varModeCheck = false;
|
||||
m_varModeReplace = false;
|
||||
m_varAssignHit = false;
|
||||
m_forkHit = false;
|
||||
m_generate = generate;
|
||||
m_beginName = beginName;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
task_example start: module 0, channel 0
|
||||
task_example end: module 0, channel 0
|
||||
task_example start: module 0, channel 1
|
||||
task_example end: module 0, channel 1
|
||||
task_example start: module 1, channel 0
|
||||
task_example end: module 1, channel 0
|
||||
task_example start: module 1, channel 1
|
||||
task_example end: module 1, channel 1
|
||||
*-* Test 1 Finished *-*
|
||||
task_example start: module 0, channel 0
|
||||
task_example end: module 0, channel 0
|
||||
task_example start: module 0, channel 1
|
||||
task_example end: module 0, channel 1
|
||||
task_example start: module 1, channel 0
|
||||
task_example end: module 1, channel 0
|
||||
task_example start: module 1, channel 1
|
||||
task_example end: module 1, channel 1
|
||||
*-* Test 2 Finished *-*
|
||||
task_example start: module 0, channel 0
|
||||
extra statement
|
||||
task_example start: module 0, channel 1
|
||||
extra statement
|
||||
task_example start: module 1, channel 0
|
||||
extra statement
|
||||
task_example start: module 1, channel 1
|
||||
extra statement
|
||||
task_example end: module 0, channel 0
|
||||
task_example end: module 0, channel 1
|
||||
task_example end: module 1, channel 0
|
||||
task_example end: module 1, channel 1
|
||||
*-* Test 3 Finished *-*
|
||||
task_example start: module 0, channel 0
|
||||
task_example start: module 0, channel 1
|
||||
task_example start: module 1, channel 0
|
||||
task_example start: module 1, channel 1
|
||||
task_example end: module 0, channel 0
|
||||
task_example end: module 0, channel 1
|
||||
task_example end: module 1, channel 0
|
||||
task_example end: module 1, channel 1
|
||||
*-* Test 4 Finished *-*
|
||||
*-* All Finished *-*
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2024 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=['--binary'])
|
||||
|
||||
test.execute(expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
|
@ -0,0 +1,82 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Targets issue 6194
|
||||
|
||||
module t;
|
||||
|
||||
logic clk;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
forever #(1) clk = ~clk;
|
||||
end
|
||||
|
||||
task automatic task_example(int module_id, int channel);
|
||||
$display("task_example start: module %0d, channel %0d", module_id, channel);
|
||||
@(posedge clk);
|
||||
$display("task_example end: module %0d, channel %0d", module_id, channel);
|
||||
endtask
|
||||
|
||||
initial begin : initial_block
|
||||
for (int m = 0; m < 2; m++) begin
|
||||
for (int i = 0; i < 2; i++) begin : forked_loop
|
||||
automatic int mod = m;
|
||||
automatic int ch = i;
|
||||
fork : forked_block
|
||||
task_example(mod, ch);
|
||||
join
|
||||
end
|
||||
end
|
||||
|
||||
#10
|
||||
$write("*-* Test 1 Finished *-*\n");
|
||||
|
||||
for (int m = 0; m < 2; m++) begin
|
||||
for (int i = 0; i < 2; i++) begin : forked_loop
|
||||
automatic int mod = m;
|
||||
automatic int ch = i;
|
||||
fork : forked_block
|
||||
task_example(mod, ch);
|
||||
join_any
|
||||
end
|
||||
end
|
||||
|
||||
#10
|
||||
$write("*-* Test 2 Finished *-*\n");
|
||||
|
||||
for (int m = 0; m < 2; m++) begin
|
||||
for (int i = 0; i < 2; i++) begin : forked_loop
|
||||
automatic int mod = m;
|
||||
automatic int ch = i;
|
||||
fork : forked_block
|
||||
task_example(mod, ch);
|
||||
$display("extra statement");
|
||||
join_any
|
||||
end
|
||||
end
|
||||
|
||||
#10
|
||||
$write("*-* Test 3 Finished *-*\n");
|
||||
|
||||
for (int m = 0; m < 2; m++) begin
|
||||
for (int i = 0; i < 2; i++) begin : forked_loop
|
||||
automatic int mod = m;
|
||||
automatic int ch = i;
|
||||
fork : forked_block
|
||||
task_example(mod, ch);
|
||||
join_none
|
||||
end
|
||||
end
|
||||
|
||||
#10
|
||||
$write("*-* Test 4 Finished *-*\n");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue