mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Fix real parameter assignment, bug1427.
This commit is contained in:
parent
3411279294
commit
59d7d9e8c3
2
Changes
2
Changes
@ -18,6 +18,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
**** Fix parameter function string returns, bug1441. [Denis Rystsov]
|
||||
|
||||
**** Fix real parameter assignment, bug1427. [Todd Strader]
|
||||
|
||||
|
||||
* Verilator 4.014 2019-05-08
|
||||
|
||||
|
@ -607,6 +607,7 @@ public:
|
||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_cellp); }
|
||||
virtual int widthAlignBytes() const { return 1; }
|
||||
virtual int widthTotalBytes() const { return 1; }
|
||||
string cellName() const { return m_cellName; }
|
||||
|
@ -663,6 +663,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
else if ( onoff (sw, "-covsp", flag/*ref*/) ) { } // TBD
|
||||
else if ( !strcmp (sw, "-debug-abort") ) { abort(); } // Undocumented, see also --debug-sigsegv
|
||||
else if ( onoff (sw, "-debug-check", flag/*ref*/) ){ m_debugCheck = flag; }
|
||||
else if ( onoff (sw, "-debug-collision", flag/*ref*/) ){ m_debugCollision = flag; } // Undocumented
|
||||
else if ( onoff (sw, "-debug-leak", flag/*ref*/) ){ m_debugLeak = flag; }
|
||||
else if ( onoff (sw, "-debug-nondeterminism", flag/*ref*/) ){ m_debugNondeterminism = flag; }
|
||||
else if ( onoff (sw, "-debug-partition", flag/*ref*/) ){ m_debugPartition = flag; } // Undocumented
|
||||
@ -1258,6 +1259,7 @@ V3Options::V3Options() {
|
||||
m_coverageUnderscore = false;
|
||||
m_coverageUser = false;
|
||||
m_debugCheck = false;
|
||||
m_debugCollision = false;
|
||||
m_debugLeak = true;
|
||||
m_debugNondeterminism = false;
|
||||
m_debugPartition = false;
|
||||
|
@ -114,6 +114,7 @@ class V3Options {
|
||||
bool m_coverageUnderscore;// main switch: --coverage-underscore
|
||||
bool m_coverageUser; // main switch: --coverage-func
|
||||
bool m_debugCheck; // main switch: --debug-check
|
||||
bool m_debugCollision; // main switch: --debug-collision
|
||||
bool m_debugLeak; // main switch: --debug-leak
|
||||
bool m_debugNondeterminism; // main switch: --debug-nondeterminism
|
||||
bool m_debugPartition; // main switch: --debug-partition
|
||||
@ -281,6 +282,7 @@ class V3Options {
|
||||
bool coverageUnderscore() const { return m_coverageUnderscore; }
|
||||
bool coverageUser() const { return m_coverageUser; }
|
||||
bool debugCheck() const { return m_debugCheck; }
|
||||
bool debugCollision() const { return m_debugCollision; }
|
||||
bool debugLeak() const { return m_debugLeak; }
|
||||
bool debugNondeterminism() const { return m_debugNondeterminism; }
|
||||
bool debugPartition() const { return m_debugPartition; }
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "V3Const.h"
|
||||
#include "V3Width.h"
|
||||
#include "V3Unroll.h"
|
||||
#include "V3Hashed.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <deque>
|
||||
@ -96,10 +97,10 @@ private:
|
||||
LongMap m_longMap; // Hash of very long names to unique identity number
|
||||
int m_longId;
|
||||
|
||||
typedef std::map<AstNode*,int> ValueMap;
|
||||
typedef std::map<int,int> NextValueMap;
|
||||
ValueMap m_valueMap; // Hash of node to param value
|
||||
NextValueMap m_nextValueMap;// Hash of param value to next value to be used
|
||||
typedef std::pair<int,string> ValueMapValue;
|
||||
typedef std::map<V3Hash,ValueMapValue> ValueMap;
|
||||
ValueMap m_valueMap; // Hash of node hash to (param value, name)
|
||||
int m_nextValue; // Next value to use in m_valueMap
|
||||
|
||||
typedef std::multimap<int,AstNodeModule*> LevelModMap;
|
||||
LevelModMap m_todoModps; // Modules left to process
|
||||
@ -148,26 +149,34 @@ private:
|
||||
return st;
|
||||
}
|
||||
string paramValueNumber(AstNode* nodep) {
|
||||
// Given a complicated object create a number to use for param module assignment
|
||||
// Ideally would be relatively stable if design changes (not use pointer value),
|
||||
// and must return same value given same input node
|
||||
// Return must presently be numeric so doesn't collide with 'small' alphanumeric parameter names
|
||||
ValueMap::iterator it = m_valueMap.find(nodep);
|
||||
if (it != m_valueMap.end()) {
|
||||
return cvtToStr(it->second);
|
||||
} else {
|
||||
static int BUCKETS = 1000;
|
||||
V3Hash hash (nodep->name());
|
||||
int bucket = hash.hshval() % BUCKETS;
|
||||
int offset = 0;
|
||||
NextValueMap::iterator it = m_nextValueMap.find(bucket);
|
||||
if (it != m_nextValueMap.end()) { offset = it->second; it->second = offset + 1; }
|
||||
else { m_nextValueMap.insert(make_pair(bucket, offset + 1)); }
|
||||
int num = bucket + offset * BUCKETS;
|
||||
m_valueMap.insert(make_pair(nodep, num));
|
||||
// 'z' just to make sure we don't collide with a normal non-hashed number
|
||||
return string("z")+cvtToStr(num);
|
||||
}
|
||||
string key = nodep->name();
|
||||
if (AstIfaceRefDType* ifrtp = VN_CAST(nodep, IfaceRefDType)) {
|
||||
if (ifrtp->cellp() && ifrtp->cellp()->modp()) {
|
||||
key = ifrtp->cellp()->modp()->name();
|
||||
} else if (ifrtp->ifacep()) {
|
||||
key = ifrtp->ifacep()->name();
|
||||
} else {
|
||||
nodep->v3fatalSrc("Can't parameterize interface without module name");
|
||||
}
|
||||
} else if (AstBasicDType* bdtp = VN_CAST(nodep, BasicDType)) {
|
||||
if (bdtp->isRanged()) {
|
||||
key += "["+cvtToStr(bdtp->left())+":"+cvtToStr(bdtp->right())+"]";
|
||||
}
|
||||
}
|
||||
V3Hash hash = V3Hashed::uncachedHash(nodep);
|
||||
// Force hash collisions -- for testing only
|
||||
if (VL_UNLIKELY(v3Global.opt.debugCollision())) {
|
||||
hash = V3Hash();
|
||||
}
|
||||
int num;
|
||||
ValueMap::iterator it = m_valueMap.find(hash);
|
||||
if (it != m_valueMap.end() && it->second.second == key) {
|
||||
num = it->second.first;
|
||||
} else {
|
||||
num = m_nextValue++;
|
||||
m_valueMap[hash] = make_pair(num, key);
|
||||
}
|
||||
return string("z")+cvtToStr(num);
|
||||
}
|
||||
void collectPins(CloneMap* clonemapp, AstNodeModule* modp) {
|
||||
// Grab all I/O so we can remap our pins later
|
||||
@ -528,9 +537,10 @@ private:
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
explicit ParamVisitor(AstNetlist* nodep) {
|
||||
m_longId = 0;
|
||||
m_modp = NULL;
|
||||
//
|
||||
m_longId = 0;
|
||||
m_modp = NULL;
|
||||
m_nextValue = 1;
|
||||
//
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~ParamVisitor() {}
|
||||
|
23
test_regress/t/t_interface_gen2_collision.pl
Executable file
23
test_regress/t/t_interface_gen2_collision.pl
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_interface_gen2.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["--debug-collision"]
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
23
test_regress/t/t_interface_gen3_collision.pl
Executable file
23
test_regress/t/t_interface_gen3_collision.pl
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_interface_gen3.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["--debug-collision"]
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
20
test_regress/t/t_param_real2.pl
Executable file
20
test_regress/t/t_param_real2.pl
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2019 by Todd Strader. 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
32
test_regress/t/t_param_real2.v
Normal file
32
test_regress/t/t_param_real2.v
Normal file
@ -0,0 +1,32 @@
|
||||
module foo
|
||||
#( parameter real bar = 2.0)
|
||||
();
|
||||
|
||||
endmodule
|
||||
|
||||
module t();
|
||||
|
||||
genvar m, r;
|
||||
generate
|
||||
for (m = 10; m <= 20; m+=10) begin : gen_m
|
||||
for (r = 0; r <= 1; r++) begin : gen_r
|
||||
localparam real lparam = m + (r + 0.5);
|
||||
initial begin
|
||||
if (lparam != foo_inst.bar) begin
|
||||
$display("%m: lparam != foo_inst.bar (%f, %f)",
|
||||
lparam, foo_inst.bar);
|
||||
$stop();
|
||||
end
|
||||
end
|
||||
|
||||
foo #(.bar (lparam)) foo_inst ();
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
23
test_regress/t/t_param_real2_collision.pl
Executable file
23
test_regress/t/t_param_real2_collision.pl
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2019 by Todd Strader. 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_param_real2.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["--debug-collision"]
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
23
test_regress/t/t_param_type_collision.pl
Executable file
23
test_regress/t/t_param_type_collision.pl
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_param_type.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["--debug-collision"]
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
20
test_regress/t/t_real_param.pl
Executable file
20
test_regress/t/t_real_param.pl
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2019 by Todd Strader. 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
37
test_regress/t/t_real_param.v
Normal file
37
test_regress/t/t_real_param.v
Normal file
@ -0,0 +1,37 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Todd Strader.
|
||||
|
||||
module foo
|
||||
#( parameter real bar = 2.0)
|
||||
();
|
||||
endmodule
|
||||
|
||||
module t();
|
||||
genvar m, r;
|
||||
generate
|
||||
for (m = 10; m <= 20; m+=10) begin : gen_m
|
||||
for (r = 0; r <= 1; r++) begin : gen_r
|
||||
localparam real lparam = m + (r + 0.5);
|
||||
initial begin
|
||||
$display("%m lparam = %f foo bar = %f", // TODO -- remove
|
||||
lparam, foo_inst.bar);
|
||||
if (lparam != foo_inst.bar) begin
|
||||
$display("%m: lparam != foo_inst.bar (%f, %f)",
|
||||
lparam, foo_inst.bar);
|
||||
$stop();
|
||||
end
|
||||
end
|
||||
|
||||
foo #(.bar (lparam)) foo_inst ();
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user