Skip to content

Commit

Permalink
Fix access type of function arguments (verilator#4692) (verilator#4694)
Browse files Browse the repository at this point in the history
  • Loading branch information
RRozak authored Nov 14, 2023
1 parent 9fd5634 commit 2dba76a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 11 deletions.
14 changes: 3 additions & 11 deletions src/V3Task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include "V3Const.h"
#include "V3EmitCBase.h"
#include "V3Graph.h"
#include "V3LinkLValue.h"

#include <tuple>

Expand Down Expand Up @@ -503,7 +502,6 @@ class TaskVisitor final : public VNVisitor {
}
} else if (portp->isInoutish()) {
// if (debug() >= 9) pinp->dumpTree("-pinrsize- ");
V3LinkLValue::linkLValueSet(pinp);

AstVarScope* const newvscp
= createVarScope(portp, namePrefix + "__" + portp->shortName());
Expand All @@ -524,12 +522,6 @@ class TaskVisitor final : public VNVisitor {
beginp->addNext(postassp);
// if (debug() >= 9) beginp->dumpTreeAndNext(cout, "-pinrsize-out- ");
} else if (portp->isWritable()) {
// Make output variables
// Correct lvalue; we didn't know when we linked
// This is slightly scary; are we sure no decisions were made
// before here based on this not being a lvalue?
// Doesn't seem so; V3Unknown uses it earlier, but works ok.
V3LinkLValue::linkLValueSet(pinp);
// Even if it's referencing a varref, we still make a temporary
// Else task(x,x,x) might produce incorrect results
AstVarScope* const newvscp
Expand Down Expand Up @@ -1859,9 +1851,9 @@ AstNodeFTask* V3Task::taskConnectWrapNew(AstNodeFTask* taskp, const string& newn
newTaskp->addStmtsp(newAssignp);
}
oldNewVars.emplace(portp, newPortp);
AstArg* const newArgp
= new AstArg{portp->fileline(), portp->name(),
new AstVarRef{portp->fileline(), newPortp, VAccess::READ}};
const VAccess pinAccess = portp->isWritable() ? VAccess::WRITE : VAccess::READ;
AstArg* const newArgp = new AstArg{portp->fileline(), portp->name(),
new AstVarRef{portp->fileline(), newPortp, pinAccess}};
newCallp->addPinsp(newArgp);
}
// Create wrapper call to original, passing arguments, adding setting of return value
Expand Down
2 changes: 2 additions & 0 deletions src/V3Width.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#include "V3Const.h"
#include "V3Error.h"
#include "V3Global.h"
#include "V3LinkLValue.h"
#include "V3MemberMap.h"
#include "V3Number.h"
#include "V3Randomize.h"
Expand Down Expand Up @@ -5687,6 +5688,7 @@ class WidthVisitor final : public VNVisitor {
AstNodeExpr* const newp = new AstResizeLValue{pinp->fileline(), pinp};
relinkHandle.relink(newp);
}
if (portp->isWritable()) V3LinkLValue::linkLValueSet(pinp);
if (!portp->basicp() || portp->basicp()->isOpaque()) {
checkClassAssign(nodep, "Function Argument", pinp, portDTypep);
userIterate(pinp, WidthVP{portDTypep, FINAL}.p());
Expand Down
23 changes: 23 additions & 0 deletions test_regress/t/t_fork_output_arg.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2023 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

scenarios(simulator => 1);

compile(
verilator_flags2 => ["--exe --main --timing"],
make_main => 0,
);

execute(
check_finished => 1,
);

ok(1);
1;
29 changes: 29 additions & 0 deletions test_regress/t/t_fork_output_arg.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0

class Cls;
int x = 100;
task get_x(output int arg);
arg = x;
endtask
endclass

task automatic test;
int o;
Cls c = new;
fork
c.get_x(o);
join_any
if (o != 100) $stop;
endtask

module t();
initial begin
test();
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

0 comments on commit 2dba76a

Please sign in to comment.