Fix `VlForkSync` redeclaration (#4277)

Given nested forks, if the inner fork had a `join` or `join_any` at the end,
`V3Sched::transformForks()` would decide that the fork's `VlForkSync` variable
should be passed in from the outside. This resulted in the `VlForkSync` getting
redeclared as a function argument. Ultimately, it led to C++ compilation errors
due to variable redeclaration.

Fixed by rearranging the `if`s that decide whether a variable should be passed
in or left as-is.
This commit is contained in:
Krzysztof Bieganski 2023-06-15 13:49:50 +02:00 committed by GitHub
parent db7eb45433
commit 43fa6858f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 26 deletions

View File

@ -290,15 +290,18 @@ void transformForks(AstNetlist* const netlistp) {
funcp->foreach([&](AstNodeVarRef* refp) {
AstVar* const varp = refp->varp();
AstBasicDType* const dtypep = varp->dtypep()->basicp();
// If it a fork sync or an intra-assignment variable, pass it by value
const bool passByValue = (dtypep && dtypep->isForkSync())
|| VString::startsWith(varp->name(), "__Vintra");
if (passByValue) {
// We can just pass it to the new function
bool passByValue = false;
if (VString::startsWith(varp->name(), "__Vintra")) {
// Pass it by value to the new function, as otherwise there are issues with
// -flocalize (see t_timing_intra_assign)
passByValue = true;
} else if (!varp->user1() || !varp->isFuncLocal()) {
// Not func local, or not declared before the fork. Their lifetime is longer
// than the forked process. Skip
return;
} else if (dtypep && dtypep->isForkSync()) {
// We can just pass it by value to the new function
passByValue = true;
}
// Remap the reference
AstVarScope* const vscp = refp->varScopep();

View File

@ -219,16 +219,18 @@ module t;
#10 done++;
`WRITE_VERBOSE(("Forked process %0d ending at time %0t\n", done, $time));
end
begin
#20 done++;
`WRITE_VERBOSE(("Forked process %0d ending at time %0t\n", done, $time));
d = new;
end
begin
#30 d.do_delay;
done++;
`WRITE_VERBOSE(("Forked process %0d ending at time %0t\n", done, $time));
end
fork
begin
#20 done++;
`WRITE_VERBOSE(("Forked process %0d ending at time %0t\n", done, $time));
d = new;
end
begin
#30 d.do_delay;
done++;
`WRITE_VERBOSE(("Forked process %0d ending at time %0t\n", done, $time));
end
join
join
done++;
`WRITE_VERBOSE(("All forked processes ended at time %0t\n", $time));

View File

@ -64,7 +64,9 @@
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::__VnoInFunc_do_fork
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::__Vfork_h########__0__0
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::__Vfork_h########__0__1
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::__Vfork_h########__0__2
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::__Vfork_h########__0__0
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::__Vfork_h########__0__1
-V{t#,#} Awaiting join of fork at: t/t_timing_class.v:222
-V{t#,#} Awaiting join of fork at: t/t_timing_class.v:217
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__7
-V{t#,#}+ Vt_timing_debug2___024root___eval_settle
@ -97,11 +99,11 @@
-V{t#,#} Awaiting time 30: Process waiting at t/t_timing_class.v:109
-V{t#,#} Awaiting time 40: Process waiting at t/t_timing_class.v:145
-V{t#,#} Awaiting time 50: Process waiting at t/t_timing_class.v:219
-V{t#,#} Awaiting time 20: Process waiting at t/t_timing_class.v:223
-V{t#,#} Awaiting time 80: Process waiting at t/t_timing_class.v:228
-V{t#,#} Awaiting time 101: Process waiting at t/t_timing_class.v:244
-V{t#,#} Awaiting time 20: Process waiting at t/t_timing_class.v:224
-V{t#,#} Awaiting time 80: Process waiting at t/t_timing_class.v:229
-V{t#,#} Awaiting time 101: Process waiting at t/t_timing_class.v:246
-V{t#,#} Resuming delayed processes
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:244
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:246
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay10::__VnoInFunc_do_sth_else
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay20::__VnoInFunc_do_delay
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:146
@ -137,14 +139,14 @@
-V{t#,#} Awaiting time 30: Process waiting at t/t_timing_class.v:109
-V{t#,#} Awaiting time 40: Process waiting at t/t_timing_class.v:145
-V{t#,#} Awaiting time 50: Process waiting at t/t_timing_class.v:219
-V{t#,#} Awaiting time 101: Process waiting at t/t_timing_class.v:223
-V{t#,#} Awaiting time 80: Process waiting at t/t_timing_class.v:228
-V{t#,#} Awaiting time 101: Process waiting at t/t_timing_class.v:224
-V{t#,#} Awaiting time 80: Process waiting at t/t_timing_class.v:229
-V{t#,#} Resuming delayed processes
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:228
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:229
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkDelayClass::new
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkDelayClass::_ctor_var_reset
-V{t#,#} Process forked at t/t_timing_class.v:222 finished
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:223
-V{t#,#} Process forked at t/t_timing_class.v:223 finished
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:224
-V{t#,#}+ Vt_timing_debug2_t__03a__03aEventClass::__VnoInFunc_wake
-V{t#,#}+ Vt_timing_debug2___024root___eval_act
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -445,7 +447,9 @@
-V{t#,#} Awaiting time 70: Process waiting at t/t_timing_class.v:76
-V{t#,#} Resuming delayed processes
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:76
-V{t#,#} Process forked at t/t_timing_class.v:227 finished
-V{t#,#} Process forked at t/t_timing_class.v:228 finished
-V{t#,#} Resuming: Process waiting at (null):0
-V{t#,#} Process forked at t/t_timing_class.v:222 finished
-V{t#,#} Resuming: Process waiting at (null):0
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:109
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay40::__VnoInFunc_do_sth_else