mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Internal code coverage improvements. No functional change intended.
This commit is contained in:
parent
c18b0eb122
commit
6a882f9dc6
@ -202,7 +202,7 @@ void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
close();
|
||||
break;
|
||||
// LCOV_EXCL_END
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -233,7 +233,7 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
close();
|
||||
break;
|
||||
// LCOV_EXCL_END
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
} else { // got==0, EOF
|
||||
// Fill buffer from here to end with NULLs so reader's don't
|
||||
|
@ -40,7 +40,7 @@
|
||||
// Threaded tracing
|
||||
|
||||
// A simple synchronized first in first out queue
|
||||
template <class T> class VerilatedThreadQueue {
|
||||
template <class T> class VerilatedThreadQueue { // LCOV_EXCL_LINE // lcov bug
|
||||
private:
|
||||
VerilatedMutex m_mutex; // Protects m_queue
|
||||
std::condition_variable_any m_cv;
|
||||
@ -233,8 +233,8 @@ protected:
|
||||
|
||||
// These hooks are called before a full or change based dump is produced.
|
||||
// The return value indicates whether to proceed with the dump.
|
||||
virtual bool preFullDump() { return true; }
|
||||
virtual bool preChangeDump() { return true; }
|
||||
virtual bool preFullDump() = 0;
|
||||
virtual bool preChangeDump() = 0;
|
||||
|
||||
public:
|
||||
//=========================================================================
|
||||
|
@ -194,13 +194,14 @@ template <> void VerilatedTrace<VL_DERIVED_T>::workerThreadMain() {
|
||||
shutdown = true;
|
||||
break;
|
||||
|
||||
//===
|
||||
// Unknown command
|
||||
default:
|
||||
//===
|
||||
// Unknown command
|
||||
default: { // LCOV_EXCL_START
|
||||
VL_TRACE_THREAD_DEBUG("Command UNKNOWN");
|
||||
VL_PRINTF_MT("Trace command: 0x%08x\n", cmd);
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", "Unknown trace command");
|
||||
break;
|
||||
} // LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
// The above switch will execute 'continue' when necessary,
|
||||
@ -376,12 +377,12 @@ template <> void VerilatedTrace<VL_DERIVED_T>::set_time_resolution(const std::st
|
||||
|
||||
template <> void VerilatedTrace<VL_DERIVED_T>::dump(vluint64_t timeui) {
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(m_timeLastDump && timeui <= m_timeLastDump)) {
|
||||
if (VL_UNCOVERABLE(m_timeLastDump && timeui <= m_timeLastDump)) { // LCOV_EXCL_START
|
||||
VL_PRINTF_MT("%%Warning: previous dump at t=%" VL_PRI64 "u, requesting t=%" VL_PRI64
|
||||
"u, dump call ignored\n",
|
||||
m_timeLastDump, timeui);
|
||||
return;
|
||||
}
|
||||
} // LCOV_EXCL_STOP
|
||||
m_timeLastDump = timeui;
|
||||
|
||||
Verilated::quiesce();
|
||||
@ -456,11 +457,11 @@ template <>
|
||||
void VerilatedTrace<VL_DERIVED_T>::addCallbackRecord(std::vector<CallbackRecord>& cbVec,
|
||||
CallbackRecord& cbRec) {
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(timeLastDump() != 0)) {
|
||||
if (VL_UNCOVERABLE(timeLastDump() != 0)) { // LCOV_EXCL_START
|
||||
std::string msg = (std::string("Internal: ") + __FILE__ + "::" + __FUNCTION__
|
||||
+ " called with already open file");
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
|
||||
}
|
||||
} // LCOV_EXCL_STOP
|
||||
cbVec.push_back(cbRec);
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,7 @@ void VerilatedVcd::bufferFlush() VL_MT_UNSAFE_ONE {
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
closeErr();
|
||||
break;
|
||||
// LCOV_EXCL_END
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,6 @@ remove_source("*examples/*");
|
||||
# Would just be removed with remove_source in later step
|
||||
remove_gcda_regexp(qr!test_regress/.*/(Vt_|Vtop_).*\.gcda!);
|
||||
|
||||
exclude_line_regexp(qr/(\bv3fatalSrc\b|\bVL_UNCOVERABLE\b|\bVL_FATAL|\bUASSERT\bERROR_RSVD_WORD\bV3ERROR_NA)/);
|
||||
exclude_line_regexp(qr/(\bv3fatalSrc\b|\bfatalSrc\b|\bVL_UNCOVERABLE\b|\bVL_FATAL|\bUASSERT\bERROR_RSVD_WORD\bV3ERROR_NA)/);
|
||||
|
||||
1;
|
||||
|
@ -197,7 +197,8 @@ private:
|
||||
UINFO(8, " Wordize ASSIGN(CONST) " << nodep << endl);
|
||||
// -> {for each_word{ ASSIGN(WORDSEL(wide,#),WORDSEL(CONST,#))}}
|
||||
if (rhsp->num().isFourState()) {
|
||||
rhsp->v3error("Unsupported: 4-state numbers in this context");
|
||||
rhsp->v3error( // LCOV_EXCL_LINE // impossible?
|
||||
"Unsupported: 4-state numbers in this context");
|
||||
}
|
||||
for (int w = 0; w < nodep->widthWords(); w++) {
|
||||
addWordAssign(
|
||||
|
@ -423,7 +423,7 @@ private:
|
||||
}
|
||||
}
|
||||
if (!varNewp) {
|
||||
if (debug() >= 9) m_deModVars.dump();
|
||||
if (debug() >= 9) m_deModVars.dump(); // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Module dearray failed for "
|
||||
<< AstNode::prettyNameQ(varNewName));
|
||||
}
|
||||
|
@ -467,8 +467,8 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
|
||||
|
||||
if (isDouble()) {
|
||||
out.precision(17);
|
||||
if (width() != 64) {
|
||||
out << "%E-bad-width-double";
|
||||
if (VL_UNCOVERABLE(width() != 64)) {
|
||||
out << "%E-bad-width-double"; // LCOV_EXCL_LINE
|
||||
} else {
|
||||
out << toDouble();
|
||||
}
|
||||
@ -476,8 +476,8 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
|
||||
} else if (isString()) {
|
||||
return '"' + toString() + '"';
|
||||
} else {
|
||||
if ((m_value[words() - 1] | m_valueX[words() - 1]) & ~hiWordMask()) {
|
||||
out << "%E-hidden-bits";
|
||||
if (VL_UNCOVERABLE((m_value[words() - 1] | m_valueX[words() - 1]) & ~hiWordMask())) {
|
||||
out << "%E-hidden-bits"; // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
if (prefixed) {
|
||||
@ -936,15 +936,6 @@ bool V3Number::isAnyXZ() const {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool V3Number::isLt(const V3Number& rhs) const {
|
||||
for (int bit = 0; bit < std::max(this->width(), rhs.width()); bit++) {
|
||||
if (this->bitIs1(bit) && rhs.bitIs0(bit)) { return 1; }
|
||||
if (rhs.bitIs1(bit) && this->bitIs0(bit)) { return 0; }
|
||||
if (this->bitIsXZ(bit)) { return 0; }
|
||||
if (rhs.bitIsXZ(bit)) { return 0; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
bool V3Number::isLtXZ(const V3Number& rhs) const {
|
||||
// Include X/Z in comparisons for sort ordering
|
||||
for (int bit = 0; bit < std::max(this->width(), rhs.width()); bit++) {
|
||||
|
@ -267,7 +267,6 @@ public:
|
||||
bool isEqOne() const;
|
||||
bool isEqAllOnes(int optwidth = 0) const;
|
||||
bool isCaseEq(const V3Number& rhs) const; // operator==
|
||||
bool isLt(const V3Number& rhs) const; // operator<
|
||||
bool isLtXZ(const V3Number& rhs) const; // operator< with XZ compared
|
||||
void isSigned(bool ssigned) { m_signed = ssigned; }
|
||||
bool isAnyX() const;
|
||||
|
@ -386,12 +386,12 @@ public:
|
||||
}
|
||||
virtual string name() const {
|
||||
string nm;
|
||||
if (logicp()) {
|
||||
if (VL_UNCOVERABLE(!logicp())) { // Avoid crash when debugging
|
||||
nm = "nul"; // LCOV_EXCL_LINE
|
||||
} else {
|
||||
nm = logicp()->name();
|
||||
nm += (string("\\nMV:") + " d=" + cvtToHex(logicp()->domainp())
|
||||
+ " s=" + cvtToHex(logicp()->scopep()));
|
||||
} else {
|
||||
nm = "nul";
|
||||
}
|
||||
return nm;
|
||||
}
|
||||
|
@ -410,11 +410,9 @@ private:
|
||||
string index = AstNode::encodeNumber(constp->toSInt());
|
||||
string replacestr = nodep->name() + "__BRA__??__KET__";
|
||||
size_t pos = m_unlinkedTxt.find(replacestr);
|
||||
if (pos == string::npos) {
|
||||
nodep->v3error("Could not find array index in unlinked text: '"
|
||||
<< m_unlinkedTxt << "' for node: " << nodep);
|
||||
return;
|
||||
}
|
||||
UASSERT_OBJ(pos != string::npos, nodep,
|
||||
"Could not find array index in unlinked text: '"
|
||||
<< m_unlinkedTxt << "' for node: " << nodep);
|
||||
m_unlinkedTxt.replace(pos, replacestr.length(),
|
||||
nodep->name() + "__BRA__" + index + "__KET__");
|
||||
} else {
|
||||
|
@ -549,7 +549,7 @@ void V3PreProcImp::unputString(const string& strg) {
|
||||
// However this can lead to "flex scanner push-back overflow"
|
||||
// so instead we scan from a temporary buffer, then on EOF return.
|
||||
// This is also faster than the old scheme, amazingly.
|
||||
if (m_lexp->m_bufferState != m_lexp->currentBuffer()) {
|
||||
if (VL_UNCOVERABLE(m_lexp->m_bufferState != m_lexp->currentBuffer())) {
|
||||
fatalSrc("bufferStack missing current buffer; will return incorrectly");
|
||||
// Hard to debug lost text as won't know till much later
|
||||
}
|
||||
@ -1087,7 +1087,7 @@ int V3PreProcImp::getStateToken() {
|
||||
stateChange(ps_DEFFORM);
|
||||
m_lexp->pushStateDefForm();
|
||||
goto next_tok;
|
||||
} else {
|
||||
} else { // LCOV_EXCL_LINE
|
||||
fatalSrc("Bad case\n");
|
||||
}
|
||||
goto next_tok;
|
||||
@ -1174,7 +1174,9 @@ int V3PreProcImp::getStateToken() {
|
||||
stateChange(ps_DEFARG);
|
||||
goto next_tok;
|
||||
} else {
|
||||
if (m_defRefs.empty()) fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
|
||||
if (VL_UNCOVERABLE(m_defRefs.empty())) {
|
||||
fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
|
||||
}
|
||||
VDefineRef* refp = &(m_defRefs.top());
|
||||
error(string("Expecting ( to begin argument list for define reference `")
|
||||
+ refp->name() + "\n");
|
||||
@ -1183,7 +1185,9 @@ int V3PreProcImp::getStateToken() {
|
||||
}
|
||||
}
|
||||
case ps_DEFARG: {
|
||||
if (m_defRefs.empty()) fatalSrc("Shouldn't be in DEFARG w/o active defref");
|
||||
if (VL_UNCOVERABLE(m_defRefs.empty())) {
|
||||
fatalSrc("Shouldn't be in DEFARG w/o active defref");
|
||||
}
|
||||
VDefineRef* refp = &(m_defRefs.top());
|
||||
refp->nextarg(refp->nextarg() + m_lexp->m_defValue);
|
||||
m_lexp->m_defValue = "";
|
||||
@ -1208,7 +1212,9 @@ int V3PreProcImp::getStateToken() {
|
||||
statePop();
|
||||
if (state()
|
||||
== ps_JOIN) { // Handle {left}```FOO(ARG) where `FOO(ARG) might be empty
|
||||
if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``");
|
||||
if (VL_UNCOVERABLE(m_joinStack.empty())) {
|
||||
fatalSrc("`` join stack empty, but in a ``");
|
||||
}
|
||||
string lhs = m_joinStack.top();
|
||||
m_joinStack.pop();
|
||||
out.insert(0, lhs);
|
||||
@ -1295,7 +1301,9 @@ int V3PreProcImp::getStateToken() {
|
||||
}
|
||||
case ps_JOIN: {
|
||||
if (tok == VP_SYMBOL || tok == VP_TEXT) {
|
||||
if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``");
|
||||
if (VL_UNCOVERABLE(m_joinStack.empty())) {
|
||||
fatalSrc("`` join stack empty, but in a ``");
|
||||
}
|
||||
string lhs = m_joinStack.top();
|
||||
m_joinStack.pop();
|
||||
UINFO(5, "`` LHS:" << lhs << endl);
|
||||
@ -1429,7 +1437,9 @@ int V3PreProcImp::getStateToken() {
|
||||
if (m_defRefs.empty()) {
|
||||
// Just output the substitution
|
||||
if (state() == ps_JOIN) { // Handle {left}```FOO where `FOO might be empty
|
||||
if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``");
|
||||
if (VL_UNCOVERABLE(m_joinStack.empty())) {
|
||||
fatalSrc("`` join stack empty, but in a ``");
|
||||
}
|
||||
string lhs = m_joinStack.top();
|
||||
m_joinStack.pop();
|
||||
out.insert(0, lhs);
|
||||
@ -1500,9 +1510,9 @@ int V3PreProcImp::getStateToken() {
|
||||
case VP_COMMENT: // Handled at top of loop
|
||||
case VP_DEFFORM: // Handled by state=ps_DEFFORM;
|
||||
case VP_DEFVALUE: // Handled by state=ps_DEFVALUE;
|
||||
default:
|
||||
default: // LCOV_EXCL_LINE
|
||||
fatalSrc(string("Internal error: Unexpected token ") + tokenName(tok) + "\n");
|
||||
break;
|
||||
break; // LCOV_EXCL_LINE
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
@ -508,7 +508,7 @@ private:
|
||||
iterateAndNextNull(valuep);
|
||||
if (optimizable()) newValue(nodep, fetchValue(valuep));
|
||||
} else {
|
||||
clearOptimizable(nodep, "No value found for enum item");
|
||||
clearOptimizable(nodep, "No value found for enum item"); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1275,7 +1275,7 @@ public:
|
||||
reason = "it is not an aggregate type of bit nor logic";
|
||||
if (!reason) reason = cannotSplitVarCommonReason(nodep);
|
||||
} else {
|
||||
reason = "its type is unknown";
|
||||
reason = "its type is unknown"; // LCOV_EXCL_LINE
|
||||
}
|
||||
if (reason)
|
||||
UINFO(5,
|
||||
|
@ -1511,7 +1511,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
||||
for (int i = 0; i < tpinnum; ++i) {
|
||||
UINFO(0, " pin " << i << " conn=" << cvtToHex(tconnects[i].second) << endl);
|
||||
}
|
||||
} // LCOV_EXCL_END
|
||||
} // LCOV_EXCL_STOP
|
||||
return tconnects;
|
||||
}
|
||||
|
||||
|
@ -1933,7 +1933,7 @@ private:
|
||||
// if (nodep->childDTypep()) {
|
||||
// nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern }
|
||||
// }
|
||||
//userIterateChildren(nodep, NULL);
|
||||
// userIterateChildren(nodep, NULL);
|
||||
}
|
||||
virtual void visit(AstMemberDType* nodep) VL_OVERRIDE {
|
||||
if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed
|
||||
|
@ -7,4 +7,10 @@
|
||||
%Error: t/t_number_bad.v:11:29: Number is missing value digits: 32'h
|
||||
11 | parameter integer FOO4 = 32'h;
|
||||
| ^~~~
|
||||
%Error: t/t_number_bad.v:13:29: Illegal character in binary constant: 2
|
||||
13 | parameter integer FOO5 = 32'b2;
|
||||
| ^~~~~
|
||||
%Error: t/t_number_bad.v:14:29: Illegal character in octal constant
|
||||
14 | parameter integer FOO6 = 32'o8;
|
||||
| ^~~~~
|
||||
%Error: Exiting due to
|
||||
|
@ -10,4 +10,7 @@ module t (/*AUTOARG*/);
|
||||
parameter integer FOO3 = 32'd;
|
||||
parameter integer FOO4 = 32'h;
|
||||
|
||||
parameter integer FOO5 = 32'b2;
|
||||
parameter integer FOO6 = 32'o8;
|
||||
|
||||
endmodule
|
||||
|
1
test_regress/t/t_vlcov_flag_invalid_bad.out
Normal file
1
test_regress/t/t_vlcov_flag_invalid_bad.out
Normal file
@ -0,0 +1 @@
|
||||
%Error: Invalid option: --invalid-dash
|
22
test_regress/t/t_vlcov_flag_invalid_bad.pl
Executable file
22
test_regress/t/t_vlcov_flag_invalid_bad.pl
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
run(cmd => ["../bin/verilator_coverage", '--invalid-dash'],
|
||||
logfile => $Self->{run_log_filename},
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
verilator_run => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
||||
1;
|
Loading…
Reference in New Issue
Block a user