Emit timescale in hierarchical block only when timescale is specified (#2735)

* Add a test for hierarchical verilation without timescale

* Emit timeunit in hierarchical wrapper only when it is specified in the input design or command line option.

* Update src/V3AstNodes.h

Co-authored-by: Wilson Snyder <wsnyder@wsnyder.org>

Co-authored-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Yutetsu TAKATSUKASA 2021-01-02 08:31:27 +09:00 committed by GitHub
parent bd602d0e2d
commit 7a18adc716
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 15 additions and 9 deletions

View File

@ -9210,6 +9210,7 @@ private:
AstExecGraph* m_execGraphp = nullptr; // Execution MTask graph for threads>1 mode
VTimescale m_timeunit; // Global time unit
VTimescale m_timeprecision; // Global time precision
bool m_timescaleSpecified = false; // Input HDL specified timescale
public:
AstNetlist()
: ASTGEN_SUPER(new FileLine(FileLine::builtInFilename())) {}
@ -9261,6 +9262,8 @@ public:
m_timeprecision = v3Global.opt.timeDefaultPrec();
}
void timeprecisionMerge(FileLine*, const VTimescale& value);
void timescaleSpecified(bool specified) { m_timescaleSpecified = specified; }
bool timescaleSpecified() const { return m_timescaleSpecified; }
};
//######################################################################

View File

@ -115,6 +115,8 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
}
}
v3Global.rootp()->timescaleSpecified(modTimedp); // true if some module specifies timescale
if (v3Global.rootp()->timeprecision().isNone()) {
v3Global.rootp()->timeprecisionMerge(v3Global.rootp()->fileline(),
VTimescale(VTimescale::TS_DEFAULT));

View File

@ -135,20 +135,18 @@ private:
"See instructions in your simulator for how"
" to use DPI libraries\n");
bool timescaleShown = false;
if (v3Global.opt.hierChild() && !modp->timeunit().isNone()) {
// Emit timescale for hierarhical verilation
timescaleShown = true;
txtp->addText(fl, string("`timescale ") + modp->timeunit().ascii() + "/"
+ v3Global.rootp()->timeprecision().ascii() + "\n\n");
}
// Module declaration
m_modPortsp = new AstTextBlock(fl, "module " + m_libName + " (\n", false, true);
txtp->addNodep(m_modPortsp);
txtp->addText(fl, ");\n\n");
// Timescale
if (!timescaleShown) {
if (v3Global.opt.hierChild() && v3Global.rootp()->timescaleSpecified()) {
// Emit timescale for hierarhical verilation if input HDL specifies timespec
txtp->addText(fl, string("timeunit ") + modp->timeunit().ascii() + ";\n");
txtp->addText(fl, string("timeprecision ") + +v3Global.rootp()->timeprecision().ascii()
+ ";\n");
} else {
addComment(txtp, fl,
"Precision of submodule"
" (commented out to avoid requiring timescale on all modules)");

View File

@ -28,6 +28,7 @@ execute(
check_finished => 1,
);
file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", qr/^\s+\/\/\s+timeprecision\s+(\d+)ps;/mi, 1);
file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", /^module\s+(\S+)\s+/, "sub0");
file_grep($Self->{obj_dir} . "/Vsub1/sub1.sv", /^module\s+(\S+)\s+/, "sub1");
file_grep($Self->{obj_dir} . "/Vsub2/sub2.sv", /^module\s+(\S+)\s+/, "sub2");

View File

@ -9,7 +9,7 @@
`define HIER_BLOCK /*verilator hier_block*/
`endif
`ifndef PROTLIB_TOP
`ifdef SHOW_TIMESCALE
`timescale 1ns/1ps
`endif

View File

@ -20,6 +20,7 @@ compile(
v_flags2 => ['t/t_hier_block.cpp'],
verilator_flags2 => ['--stats',
'--hierarchical',
'+define+SHOW_TIMESCALE',
'+define+USE_VLT', 't/t_hier_block_vlt.vlt',
'--CFLAGS', '"-pipe -DCPP_MACRO=cplusplus"',
($Self->{vltmt} ? ' --threads 6' : '')],
@ -29,6 +30,7 @@ execute(
check_finished => 1,
);
file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", qr/^\s+timeprecision\s+(\d+)ps;/mi, 1);
file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", /^module\s+(\S+)\s+/, "sub0");
file_grep($Self->{obj_dir} . "/Vsub1/sub1.sv", /^module\s+(\S+)\s+/, "sub1");
file_grep($Self->{obj_dir} . "/Vsub2/sub2.sv", /^module\s+(\S+)\s+/, "sub2");