Internals: Detab and fix spacing style issues in some include files. No functional change.
This commit is contained in:
parent
f818ddc71c
commit
b23fc06388
|
|
@ -1712,7 +1712,7 @@ This is an example similar to the above, but using SystemC.
|
||||||
#include "Vour.h"
|
#include "Vour.h"
|
||||||
int sc_main(int argc, char **argv) {
|
int sc_main(int argc, char **argv) {
|
||||||
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
||||||
sc_clock clk ("clk",10, 0.5, 3, true);
|
sc_clock clk ("clk", 10, 0.5, 3, true);
|
||||||
Vour* top;
|
Vour* top;
|
||||||
top = new Vour("top");
|
top = new Vour("top");
|
||||||
top->clk(clk);
|
top->clk(clk);
|
||||||
|
|
@ -3894,7 +3894,7 @@ Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by
|
||||||
synthesis which analyzes interconnection per-bit, but is circular to
|
synthesis which analyzes interconnection per-bit, but is circular to
|
||||||
simulation which analyzes per-bus:
|
simulation which analyzes per-bus:
|
||||||
|
|
||||||
wire [2:0] x = {x[1:0],shift_in};
|
wire [2:0] x = {x[1:0], shift_in};
|
||||||
|
|
||||||
This statement needs to be evaluated multiple times, as a change in
|
This statement needs to be evaluated multiple times, as a change in
|
||||||
"shift_in" requires "x" to be computed 3 times before it becomes stable.
|
"shift_in" requires "x" to be computed 3 times before it becomes stable.
|
||||||
|
|
@ -3903,12 +3903,12 @@ causes the warning.
|
||||||
|
|
||||||
For significantly better performance, split this into 2 separate signals:
|
For significantly better performance, split this into 2 separate signals:
|
||||||
|
|
||||||
wire [2:0] xout = {x[1:0],shift_in};
|
wire [2:0] xout = {x[1:0], shift_in};
|
||||||
|
|
||||||
and change all receiving logic to instead receive "xout". Alternatively,
|
and change all receiving logic to instead receive "xout". Alternatively,
|
||||||
change it to
|
change it to
|
||||||
|
|
||||||
wire [2:0] x = {xin[1:0],shift_in};
|
wire [2:0] x = {xin[1:0], shift_in};
|
||||||
|
|
||||||
and change all driving logic to instead drive "xin".
|
and change all driving logic to instead drive "xin".
|
||||||
|
|
||||||
|
|
@ -4024,7 +4024,7 @@ Concatenate leading zeros when doing arithmetic. In the statement
|
||||||
|
|
||||||
The best fix, which clarifies intent and will also make all tools happy is:
|
The best fix, which clarifies intent and will also make all tools happy is:
|
||||||
|
|
||||||
wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]};
|
wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0, carry[0]};
|
||||||
|
|
||||||
Ignoring this warning will only suppress the lint check, it will simulate
|
Ignoring this warning will only suppress the lint check, it will simulate
|
||||||
correctly.
|
correctly.
|
||||||
|
|
@ -4036,12 +4036,12 @@ has an indeterminate width. In most cases this violates the Verilog rule
|
||||||
that widths inside concatenates and replicates must be sized, and should be
|
that widths inside concatenates and replicates must be sized, and should be
|
||||||
fixed in the code.
|
fixed in the code.
|
||||||
|
|
||||||
wire [63:0] concat = {1,2};
|
wire [63:0] concat = {1, 2};
|
||||||
|
|
||||||
An example where this is technically legal (though still bad form) is:
|
An example where this is technically legal (though still bad form) is:
|
||||||
|
|
||||||
parameter PAR = 1;
|
parameter PAR = 1;
|
||||||
wire [63:0] concat = {PAR,PAR};
|
wire [63:0] concat = {PAR, PAR};
|
||||||
|
|
||||||
The correct fix is to either size the 1 ("32'h1"), or add the width to the
|
The correct fix is to either size the 1 ("32'h1"), or add the width to the
|
||||||
parameter definition ("parameter [31:0]"), or add the width to the
|
parameter definition ("parameter [31:0]"), or add the width to the
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@ public: // But only local to this file
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
// Derived classes should call zero() in their constructor
|
// Derived classes should call zero() in their constructor
|
||||||
VerilatedCovImpItem() {
|
VerilatedCovImpItem() {
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
m_keys[i]=KEY_UNDEF;
|
m_keys[i] = KEY_UNDEF;
|
||||||
m_vals[i]=0;
|
m_vals[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual ~VerilatedCovImpItem() {}
|
virtual ~VerilatedCovImpItem() {}
|
||||||
virtual vluint64_t count() const = 0;
|
virtual vluint64_t count() const = 0;
|
||||||
|
|
@ -96,7 +96,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
VerilatedMutex m_mutex; ///< Protects all members, when VL_THREADED. Wrapper deals with setting it.
|
VerilatedMutex m_mutex; ///< Protects all members, when VL_THREADED. Wrapper deals with setting it.
|
||||||
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
||||||
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
||||||
ItemList m_items VL_GUARDED_BY(m_mutex); ///< List of all items
|
ItemList m_items VL_GUARDED_BY(m_mutex); ///< List of all items
|
||||||
|
|
@ -107,294 +107,294 @@ private:
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedCovImp() {
|
VerilatedCovImp() {
|
||||||
m_insertp = NULL;
|
m_insertp = NULL;
|
||||||
m_insertFilenamep = NULL;
|
m_insertFilenamep = NULL;
|
||||||
m_insertLineno = 0;
|
m_insertLineno = 0;
|
||||||
}
|
}
|
||||||
VL_UNCOPYABLE(VerilatedCovImp);
|
VL_UNCOPYABLE(VerilatedCovImp);
|
||||||
public:
|
public:
|
||||||
~VerilatedCovImp() { clearGuts(); }
|
~VerilatedCovImp() { clearGuts(); }
|
||||||
static VerilatedCovImp& imp() VL_MT_SAFE {
|
static VerilatedCovImp& imp() VL_MT_SAFE {
|
||||||
static VerilatedCovImp s_singleton;
|
static VerilatedCovImp s_singleton;
|
||||||
return s_singleton;
|
return s_singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// PRIVATE METHODS
|
// PRIVATE METHODS
|
||||||
int valueIndex(const std::string& value) VL_REQUIRES(m_mutex) {
|
int valueIndex(const std::string& value) VL_REQUIRES(m_mutex) {
|
||||||
static int nextIndex = KEY_UNDEF+1;
|
static int nextIndex = KEY_UNDEF+1;
|
||||||
ValueIndexMap::iterator iter = m_valueIndexes.find(value);
|
ValueIndexMap::iterator iter = m_valueIndexes.find(value);
|
||||||
if (iter != m_valueIndexes.end()) return iter->second;
|
if (iter != m_valueIndexes.end()) return iter->second;
|
||||||
nextIndex++; assert(nextIndex>0);
|
nextIndex++; assert(nextIndex>0);
|
||||||
m_valueIndexes.insert(std::make_pair(value, nextIndex));
|
m_valueIndexes.insert(std::make_pair(value, nextIndex));
|
||||||
m_indexValues.insert(std::make_pair(nextIndex, value));
|
m_indexValues.insert(std::make_pair(nextIndex, value));
|
||||||
return nextIndex;
|
return nextIndex;
|
||||||
}
|
}
|
||||||
static std::string dequote(const std::string& text) VL_PURE {
|
static std::string dequote(const std::string& text) VL_PURE {
|
||||||
// Quote any special characters
|
// Quote any special characters
|
||||||
std::string rtn;
|
std::string rtn;
|
||||||
for (const char* pos = text.c_str(); *pos; ++pos) {
|
for (const char* pos = text.c_str(); *pos; ++pos) {
|
||||||
if (!isprint(*pos) || *pos=='%' || *pos=='"') {
|
if (!isprint(*pos) || *pos=='%' || *pos=='"') {
|
||||||
char hex[10]; sprintf(hex,"%%%02X",pos[0]);
|
char hex[10]; sprintf(hex, "%%%02X", pos[0]);
|
||||||
rtn += hex;
|
rtn += hex;
|
||||||
} else {
|
} else {
|
||||||
rtn += *pos;
|
rtn += *pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
static bool legalKey(const std::string& key) VL_PURE {
|
static bool legalKey(const std::string& key) VL_PURE {
|
||||||
// Because we compress long keys to a single letter, and
|
// Because we compress long keys to a single letter, and
|
||||||
// don't want applications to either get confused if they use
|
// don't want applications to either get confused if they use
|
||||||
// a letter differently, nor want them to rely on our compression...
|
// a letter differently, nor want them to rely on our compression...
|
||||||
// (Considered using numeric keys, but will remain back compatible.)
|
// (Considered using numeric keys, but will remain back compatible.)
|
||||||
if (key.length()<2) return false;
|
if (key.length()<2) return false;
|
||||||
if (key.length()==2 && isdigit(key[1])) return false;
|
if (key.length()==2 && isdigit(key[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static std::string keyValueFormatter(const std::string& key, const std::string& value) VL_PURE {
|
static std::string keyValueFormatter(const std::string& key, const std::string& value) VL_PURE {
|
||||||
std::string name;
|
std::string name;
|
||||||
if (key.length()==1 && isalpha(key[0])) {
|
if (key.length()==1 && isalpha(key[0])) {
|
||||||
name += std::string("\001")+key;
|
name += std::string("\001")+key;
|
||||||
} else {
|
} else {
|
||||||
name += std::string("\001")+dequote(key);
|
name += std::string("\001")+dequote(key);
|
||||||
}
|
}
|
||||||
name += std::string("\002")+dequote(value);
|
name += std::string("\002")+dequote(value);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
|
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
|
||||||
// (foo.a.x, foo.b.x) => foo.*.x
|
// (foo.a.x, foo.b.x) => foo.*.x
|
||||||
// (foo.a.x, foo.b.y) => foo.*
|
// (foo.a.x, foo.b.y) => foo.*
|
||||||
// (foo.a.x, foo.b) => foo.*
|
// (foo.a.x, foo.b) => foo.*
|
||||||
if (old == add) return add;
|
if (old == add) return add;
|
||||||
if (old.empty()) return add;
|
if (old.empty()) return add;
|
||||||
if (add.empty()) return old;
|
if (add.empty()) return old;
|
||||||
|
|
||||||
const char* a = old.c_str();
|
const char* a = old.c_str();
|
||||||
const char* b = add.c_str();
|
const char* b = add.c_str();
|
||||||
|
|
||||||
// Scan forward to first mismatch
|
// Scan forward to first mismatch
|
||||||
const char* apre = a;
|
const char* apre = a;
|
||||||
const char* bpre = b;
|
const char* bpre = b;
|
||||||
while (*apre == *bpre) { apre++; bpre++; }
|
while (*apre == *bpre) { apre++; bpre++; }
|
||||||
|
|
||||||
// We used to backup and split on only .'s but it seems better to be verbose
|
// We used to backup and split on only .'s but it seems better to be verbose
|
||||||
// and not assume . is the separator
|
// and not assume . is the separator
|
||||||
std::string prefix = std::string(a,apre-a);
|
std::string prefix = std::string(a, apre-a);
|
||||||
|
|
||||||
// Scan backward to last mismatch
|
// Scan backward to last mismatch
|
||||||
const char* apost = a+strlen(a)-1;
|
const char* apost = a+strlen(a)-1;
|
||||||
const char* bpost = b+strlen(b)-1;
|
const char* bpost = b+strlen(b)-1;
|
||||||
while (*apost == *bpost
|
while (*apost == *bpost
|
||||||
&& apost>apre && bpost>bpre) { apost--; bpost--; }
|
&& apost>apre && bpost>bpre) { apost--; bpost--; }
|
||||||
|
|
||||||
// Forward to . so we have a whole word
|
// Forward to . so we have a whole word
|
||||||
std::string suffix = *bpost ? std::string(bpost+1) : "";
|
std::string suffix = *bpost ? std::string(bpost+1) : "";
|
||||||
|
|
||||||
std::string out = prefix+"*"+suffix;
|
std::string out = prefix+"*"+suffix;
|
||||||
|
|
||||||
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
|
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) VL_REQUIRES(m_mutex) {
|
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) VL_REQUIRES(m_mutex) {
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
if (itemp->m_keys[i] != KEY_UNDEF) {
|
if (itemp->m_keys[i] != KEY_UNDEF) {
|
||||||
// We don't compare keys, only values
|
// We don't compare keys, only values
|
||||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||||
if (std::string::npos != val.find(match)) { // Found
|
if (std::string::npos != val.find(match)) { // Found
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static void selftest() VL_MT_SAFE {
|
static void selftest() VL_MT_SAFE {
|
||||||
// Little selftest
|
// Little selftest
|
||||||
if (combineHier ("a.b.c","a.b.c") !="a.b.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("a.b.c","a.b.c") !="a.b.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("a.b.c","a.b") !="a.b*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("a.b.c","a.b") !="a.b*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("a.x.c","a.y.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("a.x.c","a.y.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("a.z.z.z.c","a.b.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("a.z.z.z.c","a.b.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("z","a") !="*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("z","a") !="*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("q.a","q.b") !="q.*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("q.a","q.b") !="q.*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("q.za","q.zb") !="q.z*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("q.za","q.zb") !="q.z*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("1.2.3.a","9.8.7.a") !="*.a") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("1.2.3.a","9.8.7.a") !="*.a") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
}
|
}
|
||||||
void clearGuts() VL_REQUIRES(m_mutex) {
|
void clearGuts() VL_REQUIRES(m_mutex) {
|
||||||
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||||
VerilatedCovImpItem* itemp = *(it);
|
VerilatedCovImpItem* itemp = *(it);
|
||||||
delete itemp;
|
delete itemp;
|
||||||
}
|
}
|
||||||
m_items.clear();
|
m_items.clear();
|
||||||
m_indexValues.clear();
|
m_indexValues.clear();
|
||||||
m_valueIndexes.clear();
|
m_valueIndexes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// PUBLIC METHODS
|
// PUBLIC METHODS
|
||||||
void clear() VL_EXCLUDES(m_mutex) {
|
void clear() VL_EXCLUDES(m_mutex) {
|
||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
clearGuts();
|
clearGuts();
|
||||||
}
|
}
|
||||||
void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) {
|
void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) {
|
||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
if (matchp && matchp[0]) {
|
if (matchp && matchp[0]) {
|
||||||
ItemList newlist;
|
ItemList newlist;
|
||||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||||
VerilatedCovImpItem* itemp = *(it);
|
VerilatedCovImpItem* itemp = *(it);
|
||||||
if (!itemMatchesString(itemp, matchp)) {
|
if (!itemMatchesString(itemp, matchp)) {
|
||||||
delete itemp;
|
delete itemp;
|
||||||
} else {
|
} else {
|
||||||
newlist.push_back(itemp);
|
newlist.push_back(itemp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_items = newlist;
|
m_items = newlist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void zero() VL_EXCLUDES(m_mutex) {
|
void zero() VL_EXCLUDES(m_mutex) {
|
||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||||
(*it)->zero();
|
(*it)->zero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We assume there's always call to i/f/p in that order
|
// We assume there's always call to i/f/p in that order
|
||||||
void inserti(VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
|
void inserti(VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
assert(!m_insertp);
|
assert(!m_insertp);
|
||||||
m_insertp = itemp;
|
m_insertp = itemp;
|
||||||
}
|
}
|
||||||
void insertf(const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
|
void insertf(const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
m_insertFilenamep = filenamep;
|
m_insertFilenamep = filenamep;
|
||||||
m_insertLineno = lineno;
|
m_insertLineno = lineno;
|
||||||
}
|
}
|
||||||
void insertp(const char* ckeyps[MAX_KEYS],
|
void insertp(const char* ckeyps[MAX_KEYS],
|
||||||
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
|
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
assert(m_insertp);
|
assert(m_insertp);
|
||||||
// First two key/vals are filename
|
// First two key/vals are filename
|
||||||
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
|
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
|
||||||
std::string linestr = vlCovCvtToStr(m_insertLineno);
|
std::string linestr = vlCovCvtToStr(m_insertLineno);
|
||||||
ckeyps[1]="lineno"; valps[1]=linestr.c_str();
|
ckeyps[1]="lineno"; valps[1]=linestr.c_str();
|
||||||
// Default page if not specified
|
// Default page if not specified
|
||||||
const char* fnstartp = m_insertFilenamep;
|
const char* fnstartp = m_insertFilenamep;
|
||||||
while (const char* foundp = strchr(fnstartp,'/')) fnstartp=foundp+1;
|
while (const char* foundp = strchr(fnstartp,'/')) fnstartp = foundp+1;
|
||||||
const char* fnendp = fnstartp;
|
const char* fnendp = fnstartp;
|
||||||
while (*fnendp && *fnendp!='.') fnendp++;
|
while (*fnendp && *fnendp!='.') fnendp++;
|
||||||
std::string page_default = "sp_user/"+std::string(fnstartp,fnendp-fnstartp);
|
std::string page_default = "sp_user/"+std::string(fnstartp, fnendp-fnstartp);
|
||||||
ckeyps[2]="page"; valps[2]=page_default.c_str();
|
ckeyps[2]="page"; valps[2]=page_default.c_str();
|
||||||
|
|
||||||
// Keys -> strings
|
// Keys -> strings
|
||||||
std::string keys[MAX_KEYS];
|
std::string keys[MAX_KEYS];
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
if (ckeyps[i] && ckeyps[i][0]) {
|
if (ckeyps[i] && ckeyps[i][0]) {
|
||||||
keys[i] = ckeyps[i];
|
keys[i] = ckeyps[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Ignore empty keys
|
// Ignore empty keys
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
if (!keys[i].empty()) {
|
if (!keys[i].empty()) {
|
||||||
for (int j=i+1; j<MAX_KEYS; ++j) {
|
for (int j=i+1; j<MAX_KEYS; ++j) {
|
||||||
if (keys[i] == keys[j]) { // Duplicate key. Keep the last one
|
if (keys[i] == keys[j]) { // Duplicate key. Keep the last one
|
||||||
keys[i] = "";
|
keys[i] = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Insert the values
|
// Insert the values
|
||||||
int addKeynum=0;
|
int addKeynum = 0;
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
const std::string key = keys[i];
|
const std::string key = keys[i];
|
||||||
if (!keys[i].empty()) {
|
if (!keys[i].empty()) {
|
||||||
const std::string val = valps[i];
|
const std::string val = valps[i];
|
||||||
//cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
|
//cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
|
||||||
m_insertp->m_keys[addKeynum] = valueIndex(key);
|
m_insertp->m_keys[addKeynum] = valueIndex(key);
|
||||||
m_insertp->m_vals[addKeynum] = valueIndex(val);
|
m_insertp->m_vals[addKeynum] = valueIndex(val);
|
||||||
addKeynum++;
|
addKeynum++;
|
||||||
if (!legalKey(key)) {
|
if (!legalKey(key)) {
|
||||||
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
|
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_items.push_back(m_insertp);
|
m_items.push_back(m_insertp);
|
||||||
// Prepare for next
|
// Prepare for next
|
||||||
m_insertp = NULL;
|
m_insertp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const char* filename) VL_EXCLUDES(m_mutex) {
|
void write(const char* filename) VL_EXCLUDES(m_mutex) {
|
||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
#ifndef VM_COVERAGE
|
#ifndef VM_COVERAGE
|
||||||
VL_FATAL_MT("",0,"","%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
|
VL_FATAL_MT("", 0, "", "%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
|
||||||
#endif
|
#endif
|
||||||
selftest();
|
selftest();
|
||||||
|
|
||||||
std::ofstream os(filename);
|
std::ofstream os(filename);
|
||||||
if (os.fail()) {
|
if (os.fail()) {
|
||||||
std::string msg = std::string("%Error: Can't write '")+filename+"'";
|
std::string msg = std::string("%Error: Can't write '")+filename+"'";
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
os << "# SystemC::Coverage-3\n";
|
os << "# SystemC::Coverage-3\n";
|
||||||
|
|
||||||
// Build list of events; totalize if collapsing hierarchy
|
// Build list of events; totalize if collapsing hierarchy
|
||||||
typedef std::map<std::string,std::pair<std::string,vluint64_t> > EventMap;
|
typedef std::map<std::string,std::pair<std::string,vluint64_t> > EventMap;
|
||||||
EventMap eventCounts;
|
EventMap eventCounts;
|
||||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||||
VerilatedCovImpItem* itemp = *(it);
|
VerilatedCovImpItem* itemp = *(it);
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string hier;
|
std::string hier;
|
||||||
bool per_instance = false;
|
bool per_instance = false;
|
||||||
|
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
if (itemp->m_keys[i] != KEY_UNDEF) {
|
if (itemp->m_keys[i] != KEY_UNDEF) {
|
||||||
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
||||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||||
if (key == VL_CIK_PER_INSTANCE) {
|
if (key == VL_CIK_PER_INSTANCE) {
|
||||||
if (val != "0") per_instance = true;
|
if (val != "0") per_instance = true;
|
||||||
}
|
}
|
||||||
if (key == VL_CIK_HIER) {
|
if (key == VL_CIK_HIER) {
|
||||||
hier = val;
|
hier = val;
|
||||||
} else {
|
} else {
|
||||||
// Print it
|
// Print it
|
||||||
name += keyValueFormatter(key,val);
|
name += keyValueFormatter(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (per_instance) { // Not collapsing hierarchies
|
if (per_instance) { // Not collapsing hierarchies
|
||||||
name += keyValueFormatter(VL_CIK_HIER,hier);
|
name += keyValueFormatter(VL_CIK_HIER, hier);
|
||||||
hier = "";
|
hier = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group versus point labels don't matter here, downstream
|
// Group versus point labels don't matter here, downstream
|
||||||
// deals with it. Seems bad for sizing though and doesn't
|
// deals with it. Seems bad for sizing though and doesn't
|
||||||
// allow easy addition of new group codes (would be
|
// allow easy addition of new group codes (would be
|
||||||
// inefficient)
|
// inefficient)
|
||||||
|
|
||||||
// Find or insert the named event
|
// Find or insert the named event
|
||||||
EventMap::iterator cit = eventCounts.find(name);
|
EventMap::iterator cit = eventCounts.find(name);
|
||||||
if (cit != eventCounts.end()) {
|
if (cit != eventCounts.end()) {
|
||||||
const std::string& oldhier = cit->second.first;
|
const std::string& oldhier = cit->second.first;
|
||||||
cit->second.second += itemp->count();
|
cit->second.second += itemp->count();
|
||||||
cit->second.first = combineHier(oldhier, hier);
|
cit->second.first = combineHier(oldhier, hier);
|
||||||
} else {
|
} else {
|
||||||
eventCounts.insert(std::make_pair(name, make_pair(hier,itemp->count())));
|
eventCounts.insert(std::make_pair(name, make_pair(hier, itemp->count())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output body
|
// Output body
|
||||||
for (EventMap::const_iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
|
for (EventMap::const_iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
|
||||||
os<<"C '"<<std::dec;
|
os<<"C '"<<std::dec;
|
||||||
os<<it->first;
|
os<<it->first;
|
||||||
if (!it->second.first.empty()) os<<keyValueFormatter(VL_CIK_HIER,it->second.first);
|
if (!it->second.first.empty()) os<<keyValueFormatter(VL_CIK_HIER, it->second.first);
|
||||||
os<<"' "<<it->second.second;
|
os<<"' "<<it->second.second;
|
||||||
os<<std::endl;
|
os<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -420,7 +420,7 @@ void VerilatedCov::_inserti(vluint64_t* itemp) VL_MT_SAFE {
|
||||||
VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint64_t>(itemp));
|
VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint64_t>(itemp));
|
||||||
}
|
}
|
||||||
void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
||||||
VerilatedCovImp::imp().insertf(filename,lineno);
|
VerilatedCovImp::imp().insertf(filename, lineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define K(n) const char* key ## n
|
#define K(n) const char* key ## n
|
||||||
|
|
@ -446,14 +446,14 @@ void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||||
// And versions with fewer arguments (oh for a language with named parameters!)
|
// And versions with fewer arguments (oh for a language with named parameters!)
|
||||||
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE {
|
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE {
|
||||||
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
||||||
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
||||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||||
}
|
}
|
||||||
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||||
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE {
|
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE {
|
||||||
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
||||||
C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
|
C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
|
||||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||||
}
|
}
|
||||||
// Backward compatibility for Verilator
|
// Backward compatibility for Verilator
|
||||||
void VerilatedCov::_insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
void VerilatedCov::_insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
||||||
|
|
@ -461,10 +461,10 @@ void VerilatedCov::_insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
||||||
std::string val2str = vlCovCvtToStr(val2);
|
std::string val2str = vlCovCvtToStr(val2);
|
||||||
std::string val3str = vlCovCvtToStr(val3);
|
std::string val3str = vlCovCvtToStr(val3);
|
||||||
_insertp(C(0),C(1),
|
_insertp(C(0),C(1),
|
||||||
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
|
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
|
||||||
C(5),C(6),N(7),N(8),N(9),
|
C(5),C(6),N(7),N(8),N(9),
|
||||||
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
||||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||||
}
|
}
|
||||||
#undef A
|
#undef A
|
||||||
#undef C
|
#undef C
|
||||||
|
|
|
||||||
|
|
@ -44,31 +44,31 @@
|
||||||
/// The value may be a string, or another type which will be auto-converted to a string.
|
/// The value may be a string, or another type which will be auto-converted to a string.
|
||||||
///
|
///
|
||||||
/// Some typical keys:
|
/// Some typical keys:
|
||||||
/// filename File the recording occurs in. Defaults to __FILE__
|
/// filename File the recording occurs in. Defaults to __FILE__
|
||||||
/// lineno Line number the recording occurs in. Defaults to __LINE__
|
/// lineno Line number the recording occurs in. Defaults to __LINE__
|
||||||
/// column Column number (or occurrence# for dup file/lines). Defaults to undef.
|
/// column Column number (or occurrence# for dup file/lines). Defaults to undef.
|
||||||
/// hier Hierarchical name. Defaults to name()
|
/// hier Hierarchical name. Defaults to name()
|
||||||
/// type Type of coverage. Defaults to "user"
|
/// type Type of coverage. Defaults to "user"
|
||||||
/// Other types are 'block', 'fsm', 'toggle'.
|
/// Other types are 'block', 'fsm', 'toggle'.
|
||||||
/// comment Description of the coverage event. Should be set by the user.
|
/// comment Description of the coverage event. Should be set by the user.
|
||||||
/// Comments for type==block: 'if', 'else', 'elsif', 'case'
|
/// Comments for type==block: 'if', 'else', 'elsif', 'case'
|
||||||
/// thresh Threshold to consider fully covered.
|
/// thresh Threshold to consider fully covered.
|
||||||
/// If unspecified, downstream tools will determine it.
|
/// If unspecified, downstream tools will determine it.
|
||||||
///
|
///
|
||||||
/// Examples:
|
/// Examples:
|
||||||
///
|
///
|
||||||
/// vluint32_t m_cases[10];
|
/// vluint32_t m_cases[10];
|
||||||
/// constructor {
|
/// constructor {
|
||||||
/// for (int i=0; i<10; ++i) { m_cases[i]=0; }
|
/// for (int i=0; i<10; ++i) { m_cases[i]=0; }
|
||||||
|
/// }
|
||||||
|
/// for (int i=0; i<10; ++i) {
|
||||||
|
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
|
||||||
/// }
|
/// }
|
||||||
/// for (int i=0; i<10; ++i) {
|
|
||||||
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
|
|
||||||
/// }
|
|
||||||
|
|
||||||
#define VL_COVER_INSERT(countp,args...) \
|
#define VL_COVER_INSERT(countp,args...) \
|
||||||
VL_IF_COVER(VerilatedCov::_inserti(countp); \
|
VL_IF_COVER(VerilatedCov::_inserti(countp); \
|
||||||
VerilatedCov::_insertf(__FILE__,__LINE__); \
|
VerilatedCov::_insertf(__FILE__,__LINE__); \
|
||||||
VerilatedCov::_insertp("hier", name(), args))
|
VerilatedCov::_insertp("hier", name(), args))
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/// Convert VL_COVER_INSERT value arguments to strings
|
/// Convert VL_COVER_INSERT value arguments to strings
|
||||||
|
|
|
||||||
|
|
@ -56,17 +56,17 @@ bool VerilatedDeserialize::readDiffers(const void* __restrict datap, size_t size
|
||||||
const vluint8_t* __restrict dp = static_cast<const vluint8_t* __restrict>(datap);
|
const vluint8_t* __restrict dp = static_cast<const vluint8_t* __restrict>(datap);
|
||||||
vluint8_t miss = 0;
|
vluint8_t miss = 0;
|
||||||
while (size--) {
|
while (size--) {
|
||||||
miss |= (*dp++ ^ *m_cp++);
|
miss |= (*dp++ ^ *m_cp++);
|
||||||
}
|
}
|
||||||
return (miss!=0);
|
return (miss!=0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VerilatedDeserialize& VerilatedDeserialize::readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
VerilatedDeserialize& VerilatedDeserialize::readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
if (VL_UNLIKELY(readDiffers(datap,size))) {
|
if (VL_UNLIKELY(readDiffers(datap, size))) {
|
||||||
std::string fn = filename();
|
std::string fn = filename();
|
||||||
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
|
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
|
||||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
|
|
@ -84,10 +84,10 @@ void VerilatedSerialize::header() VL_MT_UNSAFE_ONE {
|
||||||
void VerilatedDeserialize::header() VL_MT_UNSAFE_ONE {
|
void VerilatedDeserialize::header() VL_MT_UNSAFE_ONE {
|
||||||
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
||||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) {
|
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) {
|
||||||
std::string fn = filename();
|
std::string fn = filename();
|
||||||
std::string msg = std::string("Can't deserialize; file has wrong header signature");
|
std::string msg = std::string("Can't deserialize; file has wrong header signature");
|
||||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
os.read(Verilated::serializedPtr(), Verilated::serializedSize());
|
os.read(Verilated::serializedPtr(), Verilated::serializedSize());
|
||||||
}
|
}
|
||||||
|
|
@ -101,10 +101,10 @@ void VerilatedSerialize::trailer() VL_MT_UNSAFE_ONE {
|
||||||
void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
|
void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
|
||||||
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
||||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
|
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
|
||||||
std::string fn = filename();
|
std::string fn = filename();
|
||||||
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature");
|
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature");
|
||||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,19 +116,19 @@ void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
|
||||||
void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||||
m_assertOne.check();
|
m_assertOne.check();
|
||||||
if (isOpen()) return;
|
if (isOpen()) return;
|
||||||
VL_DEBUG_IF(VL_DBG_MSGF("- save: opening save file %s\n",filenamep););
|
VL_DEBUG_IF(VL_DBG_MSGF("- save: opening save file %s\n", filenamep););
|
||||||
|
|
||||||
if (filenamep[0]=='|') {
|
if (filenamep[0]=='|') {
|
||||||
assert(0); // Not supported yet.
|
assert(0); // Not supported yet.
|
||||||
} else {
|
} else {
|
||||||
// cppcheck-suppress duplicateExpression
|
// cppcheck-suppress duplicateExpression
|
||||||
m_fd = ::open(filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK|O_CLOEXEC
|
m_fd = ::open(filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK|O_CLOEXEC
|
||||||
, 0666);
|
, 0666);
|
||||||
if (m_fd<0) {
|
if (m_fd<0) {
|
||||||
// User code can check isOpen()
|
// User code can check isOpen()
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_isOpen = true;
|
m_isOpen = true;
|
||||||
m_filename = filenamep;
|
m_filename = filenamep;
|
||||||
|
|
@ -139,19 +139,19 @@ void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||||
void VerilatedRestore::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
void VerilatedRestore::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||||
m_assertOne.check();
|
m_assertOne.check();
|
||||||
if (isOpen()) return;
|
if (isOpen()) return;
|
||||||
VL_DEBUG_IF(VL_DBG_MSGF("- restore: opening restore file %s\n",filenamep););
|
VL_DEBUG_IF(VL_DBG_MSGF("- restore: opening restore file %s\n", filenamep););
|
||||||
|
|
||||||
if (filenamep[0]=='|') {
|
if (filenamep[0]=='|') {
|
||||||
assert(0); // Not supported yet.
|
assert(0); // Not supported yet.
|
||||||
} else {
|
} else {
|
||||||
// cppcheck-suppress duplicateExpression
|
// cppcheck-suppress duplicateExpression
|
||||||
m_fd = ::open(filenamep, O_CREAT|O_RDONLY|O_LARGEFILE|O_CLOEXEC
|
m_fd = ::open(filenamep, O_CREAT|O_RDONLY|O_LARGEFILE|O_CLOEXEC
|
||||||
, 0666);
|
, 0666);
|
||||||
if (m_fd<0) {
|
if (m_fd<0) {
|
||||||
// User code can check isOpen()
|
// User code can check isOpen()
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_isOpen = true;
|
m_isOpen = true;
|
||||||
m_filename = filenamep;
|
m_filename = filenamep;
|
||||||
|
|
@ -184,21 +184,21 @@ void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
||||||
if (VL_UNLIKELY(!isOpen())) return;
|
if (VL_UNLIKELY(!isOpen())) return;
|
||||||
vluint8_t* wp = m_bufp;
|
vluint8_t* wp = m_bufp;
|
||||||
while (1) {
|
while (1) {
|
||||||
ssize_t remaining = (m_cp - wp);
|
ssize_t remaining = (m_cp - wp);
|
||||||
if (remaining==0) break;
|
if (remaining==0) break;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ssize_t got = ::write(m_fd, wp, remaining);
|
ssize_t got = ::write(m_fd, wp, remaining);
|
||||||
if (got>0) {
|
if (got>0) {
|
||||||
wp += got;
|
wp += got;
|
||||||
} else if (got < 0) {
|
} else if (got < 0) {
|
||||||
if (errno != EAGAIN && errno != EINTR) {
|
if (errno != EAGAIN && errno != EINTR) {
|
||||||
// write failed, presume error (perhaps out of disk space)
|
// write failed, presume error (perhaps out of disk space)
|
||||||
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_cp = m_bufp; // Reset buffer
|
m_cp = m_bufp; // Reset buffer
|
||||||
}
|
}
|
||||||
|
|
@ -213,30 +213,28 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
|
||||||
m_cp = m_bufp; // Reset buffer
|
m_cp = m_bufp; // Reset buffer
|
||||||
// Read into buffer starting at m_endp
|
// Read into buffer starting at m_endp
|
||||||
while (1) {
|
while (1) {
|
||||||
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
||||||
if (remaining==0) break;
|
if (remaining==0) break;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ssize_t got = ::read(m_fd, m_endp, remaining);
|
ssize_t got = ::read(m_fd, m_endp, remaining);
|
||||||
if (got>0) {
|
if (got>0) {
|
||||||
m_endp += got;
|
m_endp += got;
|
||||||
} else if (got < 0) {
|
} else if (got < 0) {
|
||||||
if (errno != EAGAIN && errno != EINTR) {
|
if (errno != EAGAIN && errno != EINTR) {
|
||||||
// write failed, presume error (perhaps out of disk space)
|
// write failed, presume error (perhaps out of disk space)
|
||||||
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else { // got==0, EOF
|
} else { // got==0, EOF
|
||||||
// Fill buffer from here to end with NULLs so reader's don't
|
// Fill buffer from here to end with NULLs so reader's don't
|
||||||
// need to check eof each character.
|
// need to check eof each character.
|
||||||
while (m_endp < m_bufp+bufferSize()) *m_endp++ = '\0';
|
while (m_endp < m_bufp+bufferSize()) *m_endp++ = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Serialization of types
|
// Serialization of types
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@ class VerilatedSerialize {
|
||||||
protected:
|
protected:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
// For speed, keep m_cp as the first member of this structure
|
// For speed, keep m_cp as the first member of this structure
|
||||||
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
||||||
vluint8_t* m_bufp; ///< Output buffer
|
vluint8_t* m_bufp; ///< Output buffer
|
||||||
bool m_isOpen; ///< True indicates open file/stream
|
bool m_isOpen; ///< True indicates open file/stream
|
||||||
std::string m_filename; ///< Filename, for error messages
|
std::string m_filename; ///< Filename, for error messages
|
||||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||||
|
|
||||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||||
|
|
@ -50,13 +50,13 @@ protected:
|
||||||
VL_UNCOPYABLE(VerilatedSerialize);
|
VL_UNCOPYABLE(VerilatedSerialize);
|
||||||
public:
|
public:
|
||||||
VerilatedSerialize() {
|
VerilatedSerialize() {
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
m_bufp = new vluint8_t [bufferSize()];
|
m_bufp = new vluint8_t [bufferSize()];
|
||||||
m_cp = m_bufp;
|
m_cp = m_bufp;
|
||||||
}
|
}
|
||||||
virtual ~VerilatedSerialize() {
|
virtual ~VerilatedSerialize() {
|
||||||
close();
|
close();
|
||||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||||
}
|
}
|
||||||
// METHODS
|
// METHODS
|
||||||
bool isOpen() const { return m_isOpen; }
|
bool isOpen() const { return m_isOpen; }
|
||||||
|
|
@ -64,24 +64,24 @@ public:
|
||||||
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
||||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||||
inline VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
inline VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
||||||
while (size) {
|
while (size) {
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
||||||
const vluint8_t* __restrict maxp = dp + blk;
|
const vluint8_t* __restrict maxp = dp + blk;
|
||||||
while (dp < maxp) *m_cp++ = *dp++;
|
while (dp < maxp) *m_cp++ = *dp++;
|
||||||
size -= blk;
|
size -= blk;
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
VerilatedSerialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
VerilatedSerialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
||||||
// Flush the write buffer if there's not enough space left for new information
|
// Flush the write buffer if there's not enough space left for new information
|
||||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||||
if (VL_UNLIKELY(m_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
|
if (VL_UNLIKELY(m_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -93,12 +93,12 @@ class VerilatedDeserialize {
|
||||||
protected:
|
protected:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
// For speed, keep m_cp as the first member of this structure
|
// For speed, keep m_cp as the first member of this structure
|
||||||
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
||||||
vluint8_t* m_bufp; ///< Output buffer
|
vluint8_t* m_bufp; ///< Output buffer
|
||||||
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
|
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
|
||||||
bool m_isOpen; ///< True indicates open file/stream
|
bool m_isOpen; ///< True indicates open file/stream
|
||||||
std::string m_filename; ///< Filename, for error messages
|
std::string m_filename; ///< Filename, for error messages
|
||||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||||
|
|
||||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||||
inline static size_t bufferInsertSize() { return 16*1024; }
|
inline static size_t bufferInsertSize() { return 16*1024; }
|
||||||
|
|
@ -111,14 +111,14 @@ protected:
|
||||||
VL_UNCOPYABLE(VerilatedDeserialize);
|
VL_UNCOPYABLE(VerilatedDeserialize);
|
||||||
public:
|
public:
|
||||||
VerilatedDeserialize() {
|
VerilatedDeserialize() {
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
m_bufp = new vluint8_t [bufferSize()];
|
m_bufp = new vluint8_t [bufferSize()];
|
||||||
m_cp = m_bufp;
|
m_cp = m_bufp;
|
||||||
m_endp = NULL;
|
m_endp = NULL;
|
||||||
}
|
}
|
||||||
virtual ~VerilatedDeserialize() {
|
virtual ~VerilatedDeserialize() {
|
||||||
close();
|
close();
|
||||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||||
}
|
}
|
||||||
// METHODS
|
// METHODS
|
||||||
bool isOpen() const { return m_isOpen; }
|
bool isOpen() const { return m_isOpen; }
|
||||||
|
|
@ -126,15 +126,15 @@ public:
|
||||||
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
||||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||||
inline VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
inline VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
|
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
|
||||||
while (size) {
|
while (size) {
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
||||||
const vluint8_t* __restrict maxp = dp + blk;
|
const vluint8_t* __restrict maxp = dp + blk;
|
||||||
while (dp < maxp) *dp++ = *m_cp++;
|
while (dp < maxp) *dp++ = *m_cp++;
|
||||||
size -= blk;
|
size -= blk;
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
// Read a datum and compare with expected value
|
// Read a datum and compare with expected value
|
||||||
VerilatedDeserialize& readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
VerilatedDeserialize& readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
||||||
|
|
@ -143,12 +143,12 @@ public:
|
||||||
private:
|
private:
|
||||||
bool readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
bool readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
||||||
VerilatedDeserialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
VerilatedDeserialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
||||||
// Flush the write buffer if there's not enough space left for new information
|
// Flush the write buffer if there's not enough space left for new information
|
||||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||||
if (VL_UNLIKELY((m_cp+bufferInsertSize()) > m_endp)) {
|
if (VL_UNLIKELY((m_cp+bufferInsertSize()) > m_endp)) {
|
||||||
fill();
|
fill();
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -158,7 +158,7 @@ private:
|
||||||
|
|
||||||
class VerilatedSave : public VerilatedSerialize {
|
class VerilatedSave : public VerilatedSerialize {
|
||||||
private:
|
private:
|
||||||
int m_fd; ///< File descriptor we're writing to
|
int m_fd; ///< File descriptor we're writing to
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
|
|
@ -177,7 +177,7 @@ public:
|
||||||
|
|
||||||
class VerilatedRestore : public VerilatedDeserialize {
|
class VerilatedRestore : public VerilatedDeserialize {
|
||||||
private:
|
private:
|
||||||
int m_fd; ///< File descriptor we're writing to
|
int m_fd; ///< File descriptor we're writing to
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
|
|
@ -237,12 +237,12 @@ inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
|
||||||
return os.read(&rhs, sizeof(rhs));
|
return os.read(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, std::string& rhs) {
|
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, std::string& rhs) {
|
||||||
vluint32_t len=rhs.length();
|
vluint32_t len = rhs.length();
|
||||||
os<<len;
|
os<<len;
|
||||||
return os.write(rhs.data(), len);
|
return os.write(rhs.data(), len);
|
||||||
}
|
}
|
||||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
|
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
|
||||||
vluint32_t len=0;
|
vluint32_t len = 0;
|
||||||
os>>len;
|
os>>len;
|
||||||
rhs.resize(len);
|
rhs.resize(len);
|
||||||
return os.read((void*)rhs.data(), len);
|
return os.read((void*)rhs.data(), len);
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@
|
||||||
/// \file
|
/// \file
|
||||||
/// \brief Verilator: Common include for OS portability (verilated & verilator)
|
/// \brief Verilator: Common include for OS portability (verilated & verilator)
|
||||||
///
|
///
|
||||||
/// This header is used by both the Verilator source code (run on the
|
/// This header is used by both the Verilator source code (run on the
|
||||||
/// build and host system), and the Verilated output (run on the target
|
/// build and host system), and the Verilated output (run on the target
|
||||||
/// system). Code needed by only the host system goes into
|
/// system). Code needed by only the host system goes into
|
||||||
/// config_build.h.in, code needed by Verilated code only goes into
|
/// config_build.h.in, code needed by Verilated code only goes into
|
||||||
/// verilated.h, and code needed by both goes here (verilatedos.h).
|
/// verilated.h, and code needed by both goes here (verilatedos.h).
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: http://www.veripool.org/verilator
|
||||||
///
|
///
|
||||||
|
|
@ -54,8 +54,8 @@
|
||||||
# define VL_EXCLUDES(x) __attribute__ ((locks_excluded(x)))
|
# define VL_EXCLUDES(x) __attribute__ ((locks_excluded(x)))
|
||||||
# define VL_SCOPED_CAPABILITY __attribute__ ((scoped_lockable))
|
# define VL_SCOPED_CAPABILITY __attribute__ ((scoped_lockable))
|
||||||
# endif
|
# endif
|
||||||
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
|
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||||
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||||
# define VL_UNREACHABLE __builtin_unreachable();
|
# define VL_UNREACHABLE __builtin_unreachable();
|
||||||
# define VL_PREFETCH_RD(p) __builtin_prefetch((p),0)
|
# define VL_PREFETCH_RD(p) __builtin_prefetch((p),0)
|
||||||
# define VL_PREFETCH_RW(p) __builtin_prefetch((p),1)
|
# define VL_PREFETCH_RW(p) __builtin_prefetch((p),1)
|
||||||
|
|
@ -65,51 +65,51 @@
|
||||||
|
|
||||||
// Defaults for unsupported compiler features
|
// Defaults for unsupported compiler features
|
||||||
#ifndef VL_ATTR_ALIGNED
|
#ifndef VL_ATTR_ALIGNED
|
||||||
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
|
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_ATTR_ALWINLINE
|
#ifndef VL_ATTR_ALWINLINE
|
||||||
# define VL_ATTR_ALWINLINE ///< Inline, even when not optimizing
|
# define VL_ATTR_ALWINLINE ///< Inline, even when not optimizing
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_ATTR_NORETURN
|
#ifndef VL_ATTR_NORETURN
|
||||||
# define VL_ATTR_NORETURN ///< Function does not ever return
|
# define VL_ATTR_NORETURN ///< Function does not ever return
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_ATTR_PRINTF
|
#ifndef VL_ATTR_PRINTF
|
||||||
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
|
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_ATTR_PURE
|
#ifndef VL_ATTR_PURE
|
||||||
# define VL_ATTR_PURE ///< Function is pure (and thus also VL_MT_SAFE)
|
# define VL_ATTR_PURE ///< Function is pure (and thus also VL_MT_SAFE)
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_ATTR_UNUSED
|
#ifndef VL_ATTR_UNUSED
|
||||||
# define VL_ATTR_UNUSED ///< Function that may be never used
|
# define VL_ATTR_UNUSED ///< Function that may be never used
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_FUNC
|
#ifndef VL_FUNC
|
||||||
# define VL_FUNC "__func__" ///< Name of current function for error macros
|
# define VL_FUNC "__func__" ///< Name of current function for error macros
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_CAPABILITY
|
#ifndef VL_CAPABILITY
|
||||||
# define VL_ACQUIRE(...) ///< Function requires a capability/lock (-fthread-safety)
|
# define VL_ACQUIRE(...) ///< Function requires a capability/lock (-fthread-safety)
|
||||||
# define VL_ACQUIRE_SHARED(...) ///< Function aquires a shared capability/lock (-fthread-safety)
|
# define VL_ACQUIRE_SHARED(...) ///< Function aquires a shared capability/lock (-fthread-safety)
|
||||||
# define VL_RELEASE(...) ///< Function releases a capability/lock (-fthread-safety)
|
# define VL_RELEASE(...) ///< Function releases a capability/lock (-fthread-safety)
|
||||||
# define VL_RELEASE_SHARED(...) ///< Function releases a shared capability/lock (-fthread-safety)
|
# define VL_RELEASE_SHARED(...) ///< Function releases a shared capability/lock (-fthread-safety)
|
||||||
# define VL_TRY_ACQUIRE(...) ///< Function returns bool if aquired a capability (-fthread-safety)
|
# define VL_TRY_ACQUIRE(...) ///< Function returns bool if aquired a capability (-fthread-safety)
|
||||||
# define VL_TRY_ACQUIRE_SHARED(...) ///< Function returns bool if aquired a shared capability (-fthread-safety)
|
# define VL_TRY_ACQUIRE_SHARED(...) ///< Function returns bool if aquired a shared capability (-fthread-safety)
|
||||||
# define VL_REQUIRES(x) ///< Function requires a capability inbound (-fthread-safety)
|
# define VL_REQUIRES(x) ///< Function requires a capability inbound (-fthread-safety)
|
||||||
# define VL_EXCLUDES(x) ///< Function requires not having a capability inbound (-fthread-safety)
|
# define VL_EXCLUDES(x) ///< Function requires not having a capability inbound (-fthread-safety)
|
||||||
# define VL_CAPABILITY(x) ///< Name of capability/lock (-fthread-safety)
|
# define VL_CAPABILITY(x) ///< Name of capability/lock (-fthread-safety)
|
||||||
# define VL_GUARDED_BY(x) ///< Name of mutex protecting this variable (-fthread-safety)
|
# define VL_GUARDED_BY(x) ///< Name of mutex protecting this variable (-fthread-safety)
|
||||||
# define VL_SCOPED_CAPABILITY ///< Scoped threaded capability/lock (-fthread-safety)
|
# define VL_SCOPED_CAPABILITY ///< Scoped threaded capability/lock (-fthread-safety)
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_LIKELY
|
#ifndef VL_LIKELY
|
||||||
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
|
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
|
||||||
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
|
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_UNREACHABLE
|
#ifndef VL_UNREACHABLE
|
||||||
# define VL_UNREACHABLE ///< Point that may never be reached
|
# define VL_UNREACHABLE ///< Point that may never be reached
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_PREFETCH_RD
|
#ifndef VL_PREFETCH_RD
|
||||||
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
|
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
|
||||||
#endif
|
#endif
|
||||||
#ifndef VL_PREFETCH_RW
|
#ifndef VL_PREFETCH_RW
|
||||||
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
|
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
|
|
@ -120,12 +120,12 @@
|
||||||
# else
|
# else
|
||||||
# error "Unsupported compiler for VL_THREADED: No thread-local declarator"
|
# error "Unsupported compiler for VL_THREADED: No thread-local declarator"
|
||||||
# endif
|
# endif
|
||||||
# define VL_THREAD_LOCAL thread_local ///< Use new C++ static local thread
|
# define VL_THREAD_LOCAL thread_local ///< Use new C++ static local thread
|
||||||
#else
|
#else
|
||||||
# define VL_THREAD_LOCAL ///< Use new C++ static local thread
|
# define VL_THREAD_LOCAL ///< Use new C++ static local thread
|
||||||
#endif
|
#endif
|
||||||
#define VL_THREAD ///< Deprecated
|
#define VL_THREAD ///< Deprecated
|
||||||
#define VL_STATIC_OR_THREAD static ///< Deprecated
|
#define VL_STATIC_OR_THREAD static ///< Deprecated
|
||||||
|
|
||||||
#define VL_PURE ///< Comment tag that Function is pure (and thus also VL_MT_SAFE)
|
#define VL_PURE ///< Comment tag that Function is pure (and thus also VL_MT_SAFE)
|
||||||
#define VL_MT_SAFE ///< Comment tag that function is threadsafe when VL_THREADED
|
#define VL_MT_SAFE ///< Comment tag that function is threadsafe when VL_THREADED
|
||||||
|
|
@ -134,18 +134,18 @@
|
||||||
#define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED, protected to make sure single-caller
|
#define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED, protected to make sure single-caller
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define VL_ULL(c) (c##ui64) ///< Add appropriate suffix to 64-bit constant
|
# define VL_ULL(c) (c##ui64) ///< Add appropriate suffix to 64-bit constant
|
||||||
#else
|
#else
|
||||||
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant
|
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This is not necessarily the same as #UL, depending on what the IData typedef is.
|
// This is not necessarily the same as #UL, depending on what the IData typedef is.
|
||||||
#define VL_UL(c) (static_cast<IData>(c##UL)) ///< Add appropriate suffix to 32-bit constant
|
#define VL_UL(c) (static_cast<IData>(c##UL)) ///< Add appropriate suffix to 32-bit constant
|
||||||
|
|
||||||
#if defined(VL_CPPCHECK) || defined(__clang_analyzer__)
|
#if defined(VL_CPPCHECK) || defined(__clang_analyzer__)
|
||||||
# define VL_DANGLING(v)
|
# define VL_DANGLING(v)
|
||||||
#else
|
#else
|
||||||
# define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later
|
# define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
@ -176,7 +176,7 @@
|
||||||
// Optimization
|
// Optimization
|
||||||
|
|
||||||
#ifndef VL_INLINE_OPT
|
#ifndef VL_INLINE_OPT
|
||||||
# define VL_INLINE_OPT ///< "inline" if compiling all objects in single compiler run
|
# define VL_INLINE_OPT ///< "inline" if compiling all objects in single compiler run
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
@ -203,37 +203,37 @@
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# include <sys/types.h> // __WORDSIZE
|
# include <sys/types.h> // __WORDSIZE
|
||||||
# include <unistd.h> // ssize_t
|
# include <unistd.h> // ssize_t
|
||||||
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||||
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||||
# if defined(__uint32_t_defined) || defined(___int32_t_defined) // Newer Cygwin uint32_t in stdint.h as an unsigned int
|
# if defined(__uint32_t_defined) || defined(___int32_t_defined) // Newer Cygwin uint32_t in stdint.h as an unsigned int
|
||||||
typedef int32_t vlsint32_t; ///< 32-bit signed type
|
typedef int32_t vlsint32_t; ///< 32-bit signed type
|
||||||
typedef uint32_t vluint32_t; ///< 32-bit unsigned type
|
typedef uint32_t vluint32_t; ///< 32-bit unsigned type
|
||||||
# else // Older Cygwin has long==uint32_t
|
# else // Older Cygwin has long==uint32_t
|
||||||
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||||
typedef long vlsint32_t; ///< 32-bit signed type
|
typedef long vlsint32_t; ///< 32-bit signed type
|
||||||
typedef unsigned long vluint32_t; ///< 32-bit unsigned type
|
typedef unsigned long vluint32_t; ///< 32-bit unsigned type
|
||||||
# endif
|
# endif
|
||||||
# if defined(__WORDSIZE) && (__WORDSIZE == 64)
|
# if defined(__WORDSIZE) && (__WORDSIZE == 64)
|
||||||
typedef long vlsint64_t; ///< 64-bit signed type
|
typedef long vlsint64_t; ///< 64-bit signed type
|
||||||
typedef unsigned long vluint64_t; ///< 64-bit unsigned type
|
typedef unsigned long vluint64_t; ///< 64-bit unsigned type
|
||||||
# else
|
# else
|
||||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||||
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#elif defined(_WIN32) && defined(_MSC_VER)
|
#elif defined(_WIN32) && defined(_MSC_VER)
|
||||||
|
|
||||||
typedef unsigned __int8 uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
typedef unsigned __int8 uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned __int16 uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
typedef unsigned __int16 uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned __int32 uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
typedef unsigned __int32 uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||||
typedef unsigned __int8 vluint8_t; ///< 8-bit unsigned type
|
typedef unsigned __int8 vluint8_t; ///< 8-bit unsigned type
|
||||||
typedef unsigned __int16 vluint16_t; ///< 16-bit unsigned type
|
typedef unsigned __int16 vluint16_t; ///< 16-bit unsigned type
|
||||||
typedef signed __int32 vlsint32_t; ///< 32-bit signed type
|
typedef signed __int32 vlsint32_t; ///< 32-bit signed type
|
||||||
typedef unsigned __int32 vluint32_t; ///< 32-bit unsigned type
|
typedef unsigned __int32 vluint32_t; ///< 32-bit unsigned type
|
||||||
typedef signed __int64 vlsint64_t; ///< 64-bit signed type
|
typedef signed __int64 vlsint64_t; ///< 64-bit signed type
|
||||||
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
|
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
|
||||||
|
|
||||||
# ifndef _SSIZE_T_DEFINED
|
# ifndef _SSIZE_T_DEFINED
|
||||||
# ifdef _WIN64
|
# ifdef _WIN64
|
||||||
|
|
@ -249,16 +249,16 @@ typedef signed __int32 ssize_t; ///< signed size_t; returned fro
|
||||||
# include <stdint.h> // Linux and most flavors
|
# include <stdint.h> // Linux and most flavors
|
||||||
# include <sys/types.h> // __WORDSIZE
|
# include <sys/types.h> // __WORDSIZE
|
||||||
# include <unistd.h> // ssize_t
|
# include <unistd.h> // ssize_t
|
||||||
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
|
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
|
||||||
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
|
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
|
||||||
typedef int vlsint32_t; ///< 32-bit signed type
|
typedef int vlsint32_t; ///< 32-bit signed type
|
||||||
typedef uint32_t vluint32_t; ///< 32-bit signed type
|
typedef uint32_t vluint32_t; ///< 32-bit signed type
|
||||||
# if defined(__WORDSIZE) && (__WORDSIZE == 64)
|
# if defined(__WORDSIZE) && (__WORDSIZE == 64)
|
||||||
typedef long vlsint64_t; ///< 64-bit signed type
|
typedef long vlsint64_t; ///< 64-bit signed type
|
||||||
typedef unsigned long vluint64_t; ///< 64-bit unsigned type
|
typedef unsigned long vluint64_t; ///< 64-bit unsigned type
|
||||||
# else
|
# else
|
||||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||||
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -305,11 +305,11 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Integer size macros
|
// Integer size macros
|
||||||
|
|
||||||
#define VL_BYTESIZE 8 ///< Bits in a byte
|
#define VL_BYTESIZE 8 ///< Bits in a byte
|
||||||
#define VL_SHORTSIZE 16 ///< Bits in a short
|
#define VL_SHORTSIZE 16 ///< Bits in a short
|
||||||
#define VL_WORDSIZE 32 ///< Bits in a word
|
#define VL_WORDSIZE 32 ///< Bits in a word
|
||||||
#define VL_QUADSIZE 64 ///< Bits in a quadword
|
#define VL_QUADSIZE 64 ///< Bits in a quadword
|
||||||
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
||||||
|
|
||||||
/// Bytes this number of bits needs (1 bit=1 byte)
|
/// Bytes this number of bits needs (1 bit=1 byte)
|
||||||
#define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE)
|
#define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE)
|
||||||
|
|
@ -327,21 +327,21 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Verilated function size macros
|
// Verilated function size macros
|
||||||
|
|
||||||
#define VL_MULS_MAX_WORDS 16 ///< Max size in words of MULS operation
|
#define VL_MULS_MAX_WORDS 16 ///< Max size in words of MULS operation
|
||||||
#define VL_TO_STRING_MAX_WORDS 64 ///< Max size in words of String conversion operation
|
#define VL_TO_STRING_MAX_WORDS 64 ///< Max size in words of String conversion operation
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Base macros
|
// Base macros
|
||||||
|
|
||||||
#define VL_SIZEBITS_I (VL_WORDSIZE-1) ///< Bit mask for bits in a word
|
#define VL_SIZEBITS_I (VL_WORDSIZE-1) ///< Bit mask for bits in a word
|
||||||
#define VL_SIZEBITS_Q (VL_QUADSIZE-1) ///< Bit mask for bits in a quad
|
#define VL_SIZEBITS_Q (VL_QUADSIZE-1) ///< Bit mask for bits in a quad
|
||||||
|
|
||||||
/// Mask for words with 1's where relevant bits are (0=all bits)
|
/// Mask for words with 1's where relevant bits are (0=all bits)
|
||||||
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) \
|
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) \
|
||||||
? ((1U << ((nbits) & VL_SIZEBITS_I) )-1) : ~0)
|
? ((1U << ((nbits) & VL_SIZEBITS_I) )-1) : ~0)
|
||||||
/// Mask for quads with 1's where relevant bits are (0=all bits)
|
/// Mask for quads with 1's where relevant bits are (0=all bits)
|
||||||
#define VL_MASK_Q(nbits) (((nbits) & VL_SIZEBITS_Q) \
|
#define VL_MASK_Q(nbits) (((nbits) & VL_SIZEBITS_Q) \
|
||||||
? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q) )-VL_ULL(1)) : VL_ULL(~0))
|
? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q) )-VL_ULL(1)) : VL_ULL(~0))
|
||||||
#define VL_BITWORD_I(bit) ((bit)/VL_WORDSIZE) ///< Word number for a wide quantity
|
#define VL_BITWORD_I(bit) ((bit)/VL_WORDSIZE) ///< Word number for a wide quantity
|
||||||
#define VL_BITBIT_I(bit) ((bit)&VL_SIZEBITS_I) ///< Bit number for a bit in a long
|
#define VL_BITBIT_I(bit) ((bit)&VL_SIZEBITS_I) ///< Bit number for a bit in a long
|
||||||
#define VL_BITBIT_Q(bit) ((bit)&VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
|
#define VL_BITBIT_Q(bit) ((bit)&VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
|
||||||
|
|
|
||||||
116
src/VlcBucket.h
116
src/VlcBucket.h
|
|
@ -32,35 +32,35 @@
|
||||||
class VlcBuckets {
|
class VlcBuckets {
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
vluint64_t* m_datap; ///< Pointer to first bucket (dynamically allocated)
|
vluint64_t* m_datap; ///< Pointer to first bucket (dynamically allocated)
|
||||||
vluint64_t m_dataSize; ///< Current entries in m_datap
|
vluint64_t m_dataSize; ///< Current entries in m_datap
|
||||||
vluint64_t m_bucketsCovered; ///< Num buckets with sufficient coverage
|
vluint64_t m_bucketsCovered; ///< Num buckets with sufficient coverage
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline vluint64_t covBit(vluint64_t point) { return 1ULL<<(point & 63); }
|
static inline vluint64_t covBit(vluint64_t point) { return 1ULL<<(point & 63); }
|
||||||
inline vluint64_t allocSize() const { return sizeof(vluint64_t) * m_dataSize / 64; }
|
inline vluint64_t allocSize() const { return sizeof(vluint64_t) * m_dataSize / 64; }
|
||||||
void allocate(vluint64_t point) {
|
void allocate(vluint64_t point) {
|
||||||
vluint64_t oldsize = m_dataSize;
|
vluint64_t oldsize = m_dataSize;
|
||||||
if (m_dataSize<point) m_dataSize=(point+64) & ~63ULL; // Keep power of two
|
if (m_dataSize<point) m_dataSize=(point+64) & ~63ULL; // Keep power of two
|
||||||
m_dataSize *= 2;
|
m_dataSize *= 2;
|
||||||
//UINFO(9, "Realloc "<<allocSize()<<" for "<<point<<" "<<cvtToHex(m_datap)<<endl);
|
//UINFO(9, "Realloc "<<allocSize()<<" for "<<point<<" "<<cvtToHex(m_datap)<<endl);
|
||||||
vluint64_t* newp = (vluint64_t*)realloc(m_datap, allocSize());
|
vluint64_t* newp = (vluint64_t*)realloc(m_datap, allocSize());
|
||||||
if (!newp) { free(m_datap); v3fatal("Out of memory increasing buckets"); }
|
if (!newp) { free(m_datap); v3fatal("Out of memory increasing buckets"); }
|
||||||
m_datap = newp;
|
m_datap = newp;
|
||||||
for (vluint64_t i=oldsize; i<m_dataSize; i+=64) m_datap[i/64] = 0;
|
for (vluint64_t i=oldsize; i<m_dataSize; i+=64) m_datap[i/64] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VlcBuckets() {
|
VlcBuckets() {
|
||||||
m_dataSize = 0;
|
m_dataSize = 0;
|
||||||
m_datap = NULL;
|
m_datap = NULL;
|
||||||
m_bucketsCovered = 0;
|
m_bucketsCovered = 0;
|
||||||
allocate(1024);
|
allocate(1024);
|
||||||
}
|
}
|
||||||
~VlcBuckets() {
|
~VlcBuckets() {
|
||||||
m_dataSize = 0;
|
m_dataSize = 0;
|
||||||
free(m_datap); m_datap=NULL;
|
free(m_datap); m_datap=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
|
|
@ -69,66 +69,66 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void addData(vluint64_t point, vluint64_t hits) {
|
void addData(vluint64_t point, vluint64_t hits) {
|
||||||
if (hits >= sufficient()) {
|
if (hits >= sufficient()) {
|
||||||
//UINFO(9," addData "<<point<<" "<<hits<<" size="<<m_dataSize<<endl);
|
//UINFO(9," addData "<<point<<" "<<hits<<" size="<<m_dataSize<<endl);
|
||||||
if (point >= m_dataSize) allocate(point);
|
if (point >= m_dataSize) allocate(point);
|
||||||
m_datap[point/64] |= covBit(point);
|
m_datap[point/64] |= covBit(point);
|
||||||
m_bucketsCovered++;
|
m_bucketsCovered++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void clearHits(vluint64_t point) const {
|
void clearHits(vluint64_t point) const {
|
||||||
if (point >= m_dataSize) {
|
if (point >= m_dataSize) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
m_datap[point/64] &= ~covBit(point);
|
m_datap[point/64] &= ~covBit(point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool exists(vluint64_t point) const {
|
bool exists(vluint64_t point) const {
|
||||||
if (point >= m_dataSize) {
|
if (point >= m_dataSize) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return (m_datap[point/64] & covBit(point)) ? 1:0;
|
return (m_datap[point/64] & covBit(point)) ? 1:0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vluint64_t hits(vluint64_t point) const {
|
vluint64_t hits(vluint64_t point) const {
|
||||||
if (point >= m_dataSize) {
|
if (point >= m_dataSize) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return (m_datap[point/64] & covBit(point)) ? 1:0;
|
return (m_datap[point/64] & covBit(point)) ? 1:0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vluint64_t popCount() const {
|
vluint64_t popCount() const {
|
||||||
vluint64_t pop = 0;
|
vluint64_t pop = 0;
|
||||||
for (vluint64_t i=0; i<m_dataSize; i++) {
|
for (vluint64_t i=0; i<m_dataSize; i++) {
|
||||||
if (hits(i)) pop++;
|
if (hits(i)) pop++;
|
||||||
}
|
}
|
||||||
return pop;
|
return pop;
|
||||||
}
|
}
|
||||||
vluint64_t dataPopCount(const VlcBuckets& remaining) {
|
vluint64_t dataPopCount(const VlcBuckets& remaining) {
|
||||||
vluint64_t pop = 0;
|
vluint64_t pop = 0;
|
||||||
for (vluint64_t i=0; i<m_dataSize; i++) {
|
for (vluint64_t i=0; i<m_dataSize; i++) {
|
||||||
if (hits(i) && remaining.hits(i)) pop++;
|
if (hits(i) && remaining.hits(i)) pop++;
|
||||||
}
|
}
|
||||||
return pop;
|
return pop;
|
||||||
}
|
}
|
||||||
void orData(const VlcBuckets& ordata) {
|
void orData(const VlcBuckets& ordata) {
|
||||||
for (vluint64_t i=0; i<m_dataSize; i++) {
|
for (vluint64_t i=0; i<m_dataSize; i++) {
|
||||||
if (hits(i) && ordata.hits(i)) {
|
if (hits(i) && ordata.hits(i)) {
|
||||||
clearHits(i);
|
clearHits(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump() const {
|
void dump() const {
|
||||||
cout<<"# ";
|
cout<<"# ";
|
||||||
for (vluint64_t i=0; i<m_dataSize; i++) {
|
for (vluint64_t i=0; i<m_dataSize; i++) {
|
||||||
if (hits(i)) cout<<","<<i;
|
if (hits(i)) cout<<","<<i;
|
||||||
}
|
}
|
||||||
cout<<endl;
|
cout<<endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|
|
||||||
135
src/VlcMain.cpp
135
src/VlcMain.cpp
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
void VlcOptions::addReadFile(const string& filename) {
|
void VlcOptions::addReadFile(const string& filename) {
|
||||||
if (m_readFiles.find(filename) == m_readFiles.end()) {
|
if (m_readFiles.find(filename) == m_readFiles.end()) {
|
||||||
m_readFiles.insert(filename);
|
m_readFiles.insert(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,9 +59,9 @@ bool VlcOptions::onoff(const char* sw, const char* arg, bool& flag) {
|
||||||
// if sw=="-noarg", then return true (found it), and flag=false
|
// if sw=="-noarg", then return true (found it), and flag=false
|
||||||
// else return false
|
// else return false
|
||||||
if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash.");
|
if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash.");
|
||||||
if (0==strcmp(sw,arg)) { flag=true; return true; }
|
if (0==strcmp(sw,arg)) { flag = true; return true; }
|
||||||
else if (0==strncmp(sw,"-no",3) && (0==strcmp(sw+3,arg+1))) { flag=false; return true; }
|
else if (0==strncmp(sw,"-no",3) && (0==strcmp(sw+3,arg+1))) { flag = false; return true; }
|
||||||
else if (0==strncmp(sw,"-no-",4) && (0==strcmp(sw+4,arg+1))) { flag=false; return true; }
|
else if (0==strncmp(sw,"-no-",4) && (0==strcmp(sw+4,arg+1))) { flag = false; return true; }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,58 +71,58 @@ void VlcOptions::parseOptsList(int argc, char** argv) {
|
||||||
// May be called recursively when there are -f files.
|
// May be called recursively when there are -f files.
|
||||||
#define shift { ++i; }
|
#define shift { ++i; }
|
||||||
for (int i=0; i<argc; ) {
|
for (int i=0; i<argc; ) {
|
||||||
UINFO(9, " Option: "<<argv[i]<<endl);
|
UINFO(9, " Option: "<<argv[i]<<endl);
|
||||||
if (argv[i][0]=='-') {
|
if (argv[i][0]=='-') {
|
||||||
const char *sw = argv[i];
|
const char *sw = argv[i];
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
// Allow gnu -- switches
|
// Allow gnu -- switches
|
||||||
if (sw[0]=='-' && sw[1]=='-') ++sw;
|
if (sw[0]=='-' && sw[1]=='-') ++sw;
|
||||||
if (0) {}
|
if (0) {}
|
||||||
// Single switches
|
// Single switches
|
||||||
else if ( onoff (sw, "-annotate-all", flag/*ref*/) ) { m_annotateAll = flag; }
|
else if ( onoff (sw, "-annotate-all", flag/*ref*/) ) { m_annotateAll = flag; }
|
||||||
else if ( onoff (sw, "-rank", flag/*ref*/) ) { m_rank = flag; }
|
else if ( onoff (sw, "-rank", flag/*ref*/) ) { m_rank = flag; }
|
||||||
else if ( onoff (sw, "-unlink", flag/*ref*/) ) { m_unlink = flag; }
|
else if ( onoff (sw, "-unlink", flag/*ref*/) ) { m_unlink = flag; }
|
||||||
// Parameterized switches
|
// Parameterized switches
|
||||||
else if ( !strcmp (sw, "-annotate-min") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-annotate-min") && (i+1)<argc ) {
|
||||||
shift;
|
shift;
|
||||||
m_annotateMin = atoi(argv[i]);
|
m_annotateMin = atoi(argv[i]);
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-annotate") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-annotate") && (i+1)<argc ) {
|
||||||
shift;
|
shift;
|
||||||
m_annotateOut = argv[i];
|
m_annotateOut = argv[i];
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-debug") ) {
|
else if ( !strcmp (sw, "-debug") ) {
|
||||||
V3Error::debugDefault(3);
|
V3Error::debugDefault(3);
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-debugi") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-debugi") && (i+1)<argc ) {
|
||||||
shift;
|
shift;
|
||||||
V3Error::debugDefault(atoi(argv[i]));
|
V3Error::debugDefault(atoi(argv[i]));
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-V") ) {
|
else if ( !strcmp (sw, "-V") ) {
|
||||||
showVersion(true);
|
showVersion(true);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-version") ) {
|
else if ( !strcmp (sw, "-version") ) {
|
||||||
showVersion(false);
|
showVersion(false);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-write") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-write") && (i+1)<argc ) {
|
||||||
shift;
|
shift;
|
||||||
m_writeFile = argv[i];
|
m_writeFile = argv[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v3fatal("Invalid option: "<<argv[i]);
|
v3fatal("Invalid option: "<<argv[i]);
|
||||||
}
|
}
|
||||||
shift;
|
shift;
|
||||||
} // - options
|
} // - options
|
||||||
else if (1) {
|
else if (1) {
|
||||||
addReadFile(argv[i]);
|
addReadFile(argv[i]);
|
||||||
shift;
|
shift;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v3fatal("Invalid argument: "<<argv[i]);
|
v3fatal("Invalid argument: "<<argv[i]);
|
||||||
shift;
|
shift;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef shift
|
#undef shift
|
||||||
}
|
}
|
||||||
|
|
@ -154,20 +154,20 @@ int main(int argc, char** argv, char** env) {
|
||||||
top.opt.parseOptsList(argc-1, argv+1);
|
top.opt.parseOptsList(argc-1, argv+1);
|
||||||
|
|
||||||
if (top.opt.readFiles().empty()) {
|
if (top.opt.readFiles().empty()) {
|
||||||
top.opt.addReadFile("vlt_coverage.dat");
|
top.opt.addReadFile("vlt_coverage.dat");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const VlStringSet& readFiles = top.opt.readFiles();
|
const VlStringSet& readFiles = top.opt.readFiles();
|
||||||
for (VlStringSet::iterator it = readFiles.begin(); it != readFiles.end(); ++it) {
|
for (VlStringSet::iterator it = readFiles.begin(); it != readFiles.end(); ++it) {
|
||||||
string filename = *it;
|
string filename = *it;
|
||||||
top.readCoverage(filename);
|
top.readCoverage(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug() >= 9) {
|
if (debug() >= 9) {
|
||||||
top.tests().dump(true);
|
top.tests().dump(true);
|
||||||
top.points().dump();
|
top.points().dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Error::abortIfWarnings();
|
V3Error::abortIfWarnings();
|
||||||
|
|
@ -176,19 +176,19 @@ int main(int argc, char** argv, char** env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (top.opt.rank()) {
|
if (top.opt.rank()) {
|
||||||
top.rank();
|
top.rank();
|
||||||
top.tests().dump(false);
|
top.tests().dump(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!top.opt.writeFile().empty()) {
|
if (!top.opt.writeFile().empty()) {
|
||||||
top.writeCoverage(top.opt.writeFile());
|
top.writeCoverage(top.opt.writeFile());
|
||||||
V3Error::abortIfWarnings();
|
V3Error::abortIfWarnings();
|
||||||
if (top.opt.unlink()) {
|
if (top.opt.unlink()) {
|
||||||
const VlStringSet& readFiles = top.opt.readFiles();
|
const VlStringSet& readFiles = top.opt.readFiles();
|
||||||
for (VlStringSet::iterator it = readFiles.begin(); it != readFiles.end(); ++it) {
|
for (VlStringSet::iterator it = readFiles.begin(); it != readFiles.end(); ++it) {
|
||||||
string filename = *it;
|
string filename = *it;
|
||||||
unlink(filename.c_str());
|
unlink(filename.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,4 +201,3 @@ int main(int argc, char** argv, char** env) {
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// compile-command: "v4make bin/verilator_coverage --debugi 9 test_regress/t/t_vlcov_data_*.dat"
|
// compile-command: "v4make bin/verilator_coverage --debugi 9 test_regress/t/t_vlcov_data_*.dat"
|
||||||
// End:
|
// End:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,13 @@ typedef std::set<string> VlStringSet;
|
||||||
|
|
||||||
class VlcOptions {
|
class VlcOptions {
|
||||||
// MEMBERS (general options)
|
// MEMBERS (general options)
|
||||||
string m_annotateOut; // main switch: --annotate I<output_directory>
|
string m_annotateOut; // main switch: --annotate I<output_directory>
|
||||||
bool m_annotateAll; // main switch: --annotate-all
|
bool m_annotateAll; // main switch: --annotate-all
|
||||||
int m_annotateMin; // main switch: --annotate-min I<count>
|
int m_annotateMin; // main switch: --annotate-min I<count>
|
||||||
VlStringSet m_readFiles; // main switch: --read
|
VlStringSet m_readFiles; // main switch: --read
|
||||||
bool m_rank; // main switch: --rank
|
bool m_rank; // main switch: --rank
|
||||||
bool m_unlink; // main switch: --unlink
|
bool m_unlink; // main switch: --unlink
|
||||||
string m_writeFile; // main switch: --write
|
string m_writeFile; // main switch: --write
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// METHODS
|
// METHODS
|
||||||
|
|
@ -54,10 +54,10 @@ private:
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VlcOptions() {
|
VlcOptions() {
|
||||||
m_annotateAll = false;
|
m_annotateAll = false;
|
||||||
m_annotateMin = 10;
|
m_annotateMin = 10;
|
||||||
m_rank = false;
|
m_rank = false;
|
||||||
m_unlink = false;
|
m_unlink = false;
|
||||||
}
|
}
|
||||||
~VlcOptions() {}
|
~VlcOptions() {}
|
||||||
void setDebugMode(int level);
|
void setDebugMode(int level);
|
||||||
|
|
@ -81,4 +81,4 @@ public:
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|
|
||||||
|
|
@ -36,18 +36,18 @@
|
||||||
class VlcPoint {
|
class VlcPoint {
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
string m_name; //< Name of the point
|
string m_name; //< Name of the point
|
||||||
vluint64_t m_pointNum; //< Point number
|
vluint64_t m_pointNum; //< Point number
|
||||||
vluint64_t m_testsCovering;//< Number tests with non-zero coverage of this point
|
vluint64_t m_testsCovering; //< Number tests with non-zero coverage of this point
|
||||||
vluint64_t m_count; //< Count of hits across all tests
|
vluint64_t m_count; //< Count of hits across all tests
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VlcPoint(const string& name, int pointNum) {
|
VlcPoint(const string& name, int pointNum) {
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_pointNum = pointNum;
|
m_pointNum = pointNum;
|
||||||
m_testsCovering = 0;
|
m_testsCovering = 0;
|
||||||
m_count = 0;
|
m_count = 0;
|
||||||
}
|
}
|
||||||
~VlcPoint() {}
|
~VlcPoint() {}
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
|
|
@ -66,31 +66,31 @@ public:
|
||||||
int column() const { return atoi(keyExtract(VL_CIK_COLUMN).c_str()); }
|
int column() const { return atoi(keyExtract(VL_CIK_COLUMN).c_str()); }
|
||||||
// METHODS
|
// METHODS
|
||||||
string keyExtract(const char* shortKey) const {
|
string keyExtract(const char* shortKey) const {
|
||||||
// Hot function
|
// Hot function
|
||||||
size_t shortLen = strlen(shortKey);
|
size_t shortLen = strlen(shortKey);
|
||||||
const string namestr = name();
|
const string namestr = name();
|
||||||
for (const char* cp = namestr.c_str(); *cp; ++cp) {
|
for (const char* cp = namestr.c_str(); *cp; ++cp) {
|
||||||
if (*cp == '\001') {
|
if (*cp == '\001') {
|
||||||
if (0==strncmp(cp+1, shortKey, shortLen)
|
if (0==strncmp(cp+1, shortKey, shortLen)
|
||||||
&& cp[shortLen+1] == '\002') {
|
&& cp[shortLen+1] == '\002') {
|
||||||
cp += shortLen+2; // Skip \001+short+\002
|
cp += shortLen+2; // Skip \001+short+\002
|
||||||
const char* ep = cp;
|
const char* ep = cp;
|
||||||
while (*ep && *ep != '\001') ++ep;
|
while (*ep && *ep != '\001') ++ep;
|
||||||
return string(cp, ep-cp);
|
return string(cp, ep-cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
static void dumpHeader() {
|
static void dumpHeader() {
|
||||||
cout<<"Points:\n";
|
cout<<"Points:\n";
|
||||||
cout<<" Num, TestsCover, Count, Name"<<endl;
|
cout<<" Num, TestsCover, Count, Name"<<endl;
|
||||||
}
|
}
|
||||||
void dump() const {
|
void dump() const {
|
||||||
cout<<" "<<std::setw(8)<<std::setfill('0')<<pointNum()
|
cout<<" "<<std::setw(8)<<std::setfill('0')<<pointNum()
|
||||||
<<", "<<std::setw(7)<<std::setfill(' ')<<testsCovering()
|
<<", "<<std::setw(7)<<std::setfill(' ')<<testsCovering()
|
||||||
<<", "<<std::setw(7)<<std::setfill(' ')<<count()
|
<<", "<<std::setw(7)<<std::setfill(' ')<<count()
|
||||||
<<", \""<<name()<<"\""<<endl;
|
<<", \""<<name()<<"\""<<endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -115,40 +115,40 @@ public:
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VlcPoints() {
|
VlcPoints() {
|
||||||
m_numPoints = 0;
|
m_numPoints = 0;
|
||||||
}
|
}
|
||||||
~VlcPoints() {}
|
~VlcPoints() {}
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void dump() {
|
void dump() {
|
||||||
UINFO(2,"dumpPoints...\n");
|
UINFO(2,"dumpPoints...\n");
|
||||||
VlcPoint::dumpHeader();
|
VlcPoint::dumpHeader();
|
||||||
for (VlcPoints::ByName::iterator it=begin(); it!=end(); ++it) {
|
for (VlcPoints::ByName::iterator it=begin(); it!=end(); ++it) {
|
||||||
const VlcPoint& point = pointNumber(it->second);
|
const VlcPoint& point = pointNumber(it->second);
|
||||||
point.dump();
|
point.dump();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VlcPoint& pointNumber(vluint64_t num) {
|
VlcPoint& pointNumber(vluint64_t num) {
|
||||||
return m_points[num];
|
return m_points[num];
|
||||||
}
|
}
|
||||||
vluint64_t findAddPoint(const string& name, vluint64_t count) {
|
vluint64_t findAddPoint(const string& name, vluint64_t count) {
|
||||||
vluint64_t pointnum;
|
vluint64_t pointnum;
|
||||||
NameMap::iterator iter = m_nameMap.find(name);
|
NameMap::iterator iter = m_nameMap.find(name);
|
||||||
if (iter != m_nameMap.end()) {
|
if (iter != m_nameMap.end()) {
|
||||||
pointnum = iter->second;
|
pointnum = iter->second;
|
||||||
m_points[pointnum].countInc(count);
|
m_points[pointnum].countInc(count);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pointnum = m_numPoints++;
|
pointnum = m_numPoints++;
|
||||||
VlcPoint point (name, pointnum);
|
VlcPoint point (name, pointnum);
|
||||||
point.countInc(count);
|
point.countInc(count);
|
||||||
m_points.push_back(point);
|
m_points.push_back(point);
|
||||||
m_nameMap.insert(make_pair(point.name(), point.pointNum()));
|
m_nameMap.insert(make_pair(point.name(), point.pointNum()));
|
||||||
}
|
}
|
||||||
return pointnum;
|
return pointnum;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|
|
||||||
|
|
@ -33,18 +33,18 @@
|
||||||
class VlcSourceCount {
|
class VlcSourceCount {
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
int m_lineno; ///< Line number
|
int m_lineno; ///< Line number
|
||||||
int m_column; ///< Column number
|
int m_column; ///< Column number
|
||||||
vluint64_t m_count; ///< Count
|
vluint64_t m_count; ///< Count
|
||||||
bool m_ok; ///< Coverage is above threshold
|
bool m_ok; ///< Coverage is above threshold
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VlcSourceCount(int lineno, int column) {
|
VlcSourceCount(int lineno, int column) {
|
||||||
m_lineno = lineno;
|
m_lineno = lineno;
|
||||||
m_column = column;
|
m_column = column;
|
||||||
m_count = 0;
|
m_count = 0;
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
}
|
}
|
||||||
~VlcSourceCount() {}
|
~VlcSourceCount() {}
|
||||||
|
|
||||||
|
|
@ -56,8 +56,8 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void incCount(vluint64_t count, bool ok) {
|
void incCount(vluint64_t count, bool ok) {
|
||||||
m_count += count;
|
m_count += count;
|
||||||
if (ok) m_ok = true;
|
if (ok) m_ok = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -72,15 +72,15 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
string m_name; //< Name of the source file
|
string m_name; //< Name of the source file
|
||||||
bool m_needed; //< Need to annotate; has low coverage
|
bool m_needed; //< Need to annotate; has low coverage
|
||||||
LinenoMap m_lines; //< Map of each annotated line
|
LinenoMap m_lines; //< Map of each annotated line
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit VlcSource(const string& name) {
|
explicit VlcSource(const string& name) {
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_needed = false;
|
m_needed = false;
|
||||||
}
|
}
|
||||||
~VlcSource() {}
|
~VlcSource() {}
|
||||||
|
|
||||||
|
|
@ -92,17 +92,17 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void incCount(int lineno, int column, vluint64_t count, bool ok) {
|
void incCount(int lineno, int column, vluint64_t count, bool ok) {
|
||||||
LinenoMap::iterator lit = m_lines.find(lineno);
|
LinenoMap::iterator lit = m_lines.find(lineno);
|
||||||
if (lit == m_lines.end()) {
|
if (lit == m_lines.end()) {
|
||||||
lit = m_lines.insert(make_pair(lineno,ColumnMap())).first;
|
lit = m_lines.insert(make_pair(lineno, ColumnMap())).first;
|
||||||
}
|
}
|
||||||
ColumnMap& cmap = lit->second;
|
ColumnMap& cmap = lit->second;
|
||||||
ColumnMap::iterator cit = cmap.find(column);
|
ColumnMap::iterator cit = cmap.find(column);
|
||||||
if (cit == cmap.end()) {
|
if (cit == cmap.end()) {
|
||||||
cit = cmap.insert(make_pair(column,VlcSourceCount(lineno, column))).first;
|
cit = cmap.insert(make_pair(column, VlcSourceCount(lineno, column))).first;
|
||||||
}
|
}
|
||||||
VlcSourceCount& sc = cit->second;
|
VlcSourceCount& sc = cit->second;
|
||||||
sc.incCount(count,ok);
|
sc.incCount(count, ok);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -115,7 +115,7 @@ public:
|
||||||
typedef std::map<string,VlcSource> NameMap;
|
typedef std::map<string,VlcSource> NameMap;
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
NameMap m_sources; //< List of all sources
|
NameMap m_sources; //< List of all sources
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// ITERATORS
|
// ITERATORS
|
||||||
|
|
@ -130,17 +130,17 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
VlcSource& findNewSource(const string& name) {
|
VlcSource& findNewSource(const string& name) {
|
||||||
NameMap::iterator iter = m_sources.find(name);
|
NameMap::iterator iter = m_sources.find(name);
|
||||||
if (iter != m_sources.end()) {
|
if (iter != m_sources.end()) {
|
||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
iter = m_sources.insert(make_pair(name, VlcSource(name))).first;
|
iter = m_sources.insert(make_pair(name, VlcSource(name))).first;
|
||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|
|
||||||
|
|
@ -36,23 +36,23 @@
|
||||||
class VlcTest {
|
class VlcTest {
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
string m_name; //< Name of the test
|
string m_name; //< Name of the test
|
||||||
double m_computrons; //< Runtime for the test
|
double m_computrons; //< Runtime for the test
|
||||||
vluint64_t m_testrun; //< Test run number, for database use
|
vluint64_t m_testrun; //< Test run number, for database use
|
||||||
vluint64_t m_rank; //< Execution rank suggestion
|
vluint64_t m_rank; //< Execution rank suggestion
|
||||||
vluint64_t m_rankPoints; //< Ranked additional points
|
vluint64_t m_rankPoints; //< Ranked additional points
|
||||||
vluint64_t m_user; //< User data for algorithms (not persisted in .dat file)
|
vluint64_t m_user; //< User data for algorithms (not persisted in .dat file)
|
||||||
VlcBuckets m_buckets; //< Coverage data for each coverage point
|
VlcBuckets m_buckets; //< Coverage data for each coverage point
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VlcTest(const string& name, vluint64_t testrun, double comp) {
|
VlcTest(const string& name, vluint64_t testrun, double comp) {
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_computrons = comp;
|
m_computrons = comp;
|
||||||
m_testrun = testrun;
|
m_testrun = testrun;
|
||||||
m_rank = 0;
|
m_rank = 0;
|
||||||
m_rankPoints = 0;
|
m_rankPoints = 0;
|
||||||
m_user = 0;
|
m_user = 0;
|
||||||
}
|
}
|
||||||
~VlcTest() {}
|
~VlcTest() {}
|
||||||
|
|
||||||
|
|
@ -71,20 +71,20 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
static void dumpHeader() {
|
static void dumpHeader() {
|
||||||
cout<<"Tests:\n";
|
cout<<"Tests:\n";
|
||||||
//cout<<" Testrun, Computrons,"; // Currently not loaded
|
//cout<<" Testrun, Computrons,"; // Currently not loaded
|
||||||
cout<<" Covered, Rank, RankPts, Filename"<<endl;
|
cout<<" Covered, Rank, RankPts, Filename"<<endl;
|
||||||
}
|
}
|
||||||
void dump(bool bucketsToo) {
|
void dump(bool bucketsToo) {
|
||||||
if (testrun() || computrons()!=0.0) {
|
if (testrun() || computrons()!=0.0) {
|
||||||
cout<<" "<<std::setw(8)<<std::setfill('0')<<testrun()
|
cout<<" "<<std::setw(8)<<std::setfill('0')<<testrun()
|
||||||
<<", "<<std::setw(7)<<std::setfill(' ')<<computrons()<<",";
|
<<", "<<std::setw(7)<<std::setfill(' ')<<computrons()<<",";
|
||||||
}
|
}
|
||||||
cout<<" "<<std::setw(7)<<std::setfill(' ')<<bucketsCovered()
|
cout<<" "<<std::setw(7)<<std::setfill(' ')<<bucketsCovered()
|
||||||
<<", "<<std::setw(7)<<std::setfill(' ')<<rank()
|
<<", "<<std::setw(7)<<std::setfill(' ')<<rank()
|
||||||
<<", "<<std::setw(7)<<std::setfill(' ')<<rankPoints()
|
<<", "<<std::setw(7)<<std::setfill(' ')<<rankPoints()
|
||||||
<<", \""<<name()<<"\""<<endl;
|
<<", \""<<name()<<"\""<<endl;
|
||||||
if (bucketsToo) m_buckets.dump();
|
if (bucketsToo) m_buckets.dump();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ public:
|
||||||
typedef std::vector<VlcTest*> ByName;
|
typedef std::vector<VlcTest*> ByName;
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
ByName m_tests; //< List of all tests
|
ByName m_tests; //< List of all tests
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// ITERATORS
|
// ITERATORS
|
||||||
|
|
@ -109,31 +109,31 @@ public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VlcTests() {}
|
VlcTests() {}
|
||||||
~VlcTests() {
|
~VlcTests() {
|
||||||
for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) {
|
for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) {
|
||||||
delete *it; *it=NULL;
|
delete *it; *it=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void dump(bool bucketsToo) {
|
void dump(bool bucketsToo) {
|
||||||
UINFO(2,"dumpTests...\n");
|
UINFO(2,"dumpTests...\n");
|
||||||
VlcTest::dumpHeader();
|
VlcTest::dumpHeader();
|
||||||
for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) {
|
for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) {
|
||||||
(*it)->dump(bucketsToo);
|
(*it)->dump(bucketsToo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VlcTest* newTest(const string& name, vluint64_t testrun, double comp) {
|
VlcTest* newTest(const string& name, vluint64_t testrun, double comp) {
|
||||||
VlcTest* testp = new VlcTest(name, testrun, comp);
|
VlcTest* testp = new VlcTest(name, testrun, comp);
|
||||||
m_tests.push_back(testp);
|
m_tests.push_back(testp);
|
||||||
return testp;
|
return testp;
|
||||||
}
|
}
|
||||||
void clearUser() {
|
void clearUser() {
|
||||||
for (ByName::iterator it = m_tests.begin(); it != m_tests.end(); ++it) {
|
for (ByName::iterator it = m_tests.begin(); it != m_tests.end(); ++it) {
|
||||||
(*it)->user(0);
|
(*it)->user(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|
|
||||||
244
src/VlcTop.cpp
244
src/VlcTop.cpp
|
|
@ -34,8 +34,8 @@ void VlcTop::readCoverage(const string& filename, bool nonfatal) {
|
||||||
|
|
||||||
std::ifstream is(filename.c_str());
|
std::ifstream is(filename.c_str());
|
||||||
if (!is) {
|
if (!is) {
|
||||||
if (!nonfatal) v3fatal("Can't read "<<filename);
|
if (!nonfatal) v3fatal("Can't read "<<filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testrun and computrons argument unsupported as yet
|
// Testrun and computrons argument unsupported as yet
|
||||||
|
|
@ -45,23 +45,23 @@ void VlcTop::readCoverage(const string& filename, bool nonfatal) {
|
||||||
string line = V3Os::getline(is);
|
string line = V3Os::getline(is);
|
||||||
//UINFO(9," got "<<line<<endl);
|
//UINFO(9," got "<<line<<endl);
|
||||||
if (line[0] == 'C') {
|
if (line[0] == 'C') {
|
||||||
string::size_type secspace=3;
|
string::size_type secspace = 3;
|
||||||
for (; secspace<line.length(); secspace++) {
|
for (; secspace<line.length(); secspace++) {
|
||||||
if (line[secspace]=='\'' && line[secspace+1]==' ') break;
|
if (line[secspace]=='\'' && line[secspace+1]==' ') break;
|
||||||
}
|
}
|
||||||
string point = line.substr(3,secspace-3);
|
string point = line.substr(3, secspace-3);
|
||||||
vluint64_t hits = atoll(line.c_str()+secspace+1);
|
vluint64_t hits = atoll(line.c_str()+secspace+1);
|
||||||
//UINFO(9," point '"<<point<<"'"<<" "<<hits<<endl);
|
//UINFO(9," point '"<<point<<"'"<<" "<<hits<<endl);
|
||||||
|
|
||||||
vluint64_t pointnum = points().findAddPoint(point, hits);
|
vluint64_t pointnum = points().findAddPoint(point, hits);
|
||||||
if (pointnum) {} // Prevent unused
|
if (pointnum) {} // Prevent unused
|
||||||
if (opt.rank()) { // Only if ranking - uses a lot of memory
|
if (opt.rank()) { // Only if ranking - uses a lot of memory
|
||||||
if (hits >= VlcBuckets::sufficient()) {
|
if (hits >= VlcBuckets::sufficient()) {
|
||||||
points().pointNumber(pointnum).testsCoveringInc();
|
points().pointNumber(pointnum).testsCoveringInc();
|
||||||
testp->buckets().addData(pointnum, hits);
|
testp->buckets().addData(pointnum, hits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,14 +70,14 @@ void VlcTop::writeCoverage(const string& filename) {
|
||||||
|
|
||||||
std::ofstream os(filename.c_str());
|
std::ofstream os(filename.c_str());
|
||||||
if (!os) {
|
if (!os) {
|
||||||
v3fatal("Can't write "<<filename);
|
v3fatal("Can't write "<<filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "# SystemC::Coverage-3" << endl;
|
os << "# SystemC::Coverage-3" << endl;
|
||||||
for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
|
for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
|
||||||
const VlcPoint& point = m_points.pointNumber(it->second);
|
const VlcPoint& point = m_points.pointNumber(it->second);
|
||||||
os <<"C '"<<point.name()<<"' " << point.count()<<endl;
|
os <<"C '"<<point.name()<<"' " << point.count()<<endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,32 +85,32 @@ void VlcTop::writeCoverage(const string& filename) {
|
||||||
|
|
||||||
struct CmpComputrons {
|
struct CmpComputrons {
|
||||||
inline bool operator() (const VlcTest* lhsp, const VlcTest* rhsp) const {
|
inline bool operator() (const VlcTest* lhsp, const VlcTest* rhsp) const {
|
||||||
if (lhsp->computrons() != rhsp->computrons()) {
|
if (lhsp->computrons() != rhsp->computrons()) {
|
||||||
return lhsp->computrons() < rhsp->computrons();
|
return lhsp->computrons() < rhsp->computrons();
|
||||||
}
|
}
|
||||||
return lhsp->bucketsCovered() > rhsp->bucketsCovered();
|
return lhsp->bucketsCovered() > rhsp->bucketsCovered();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void VlcTop::rank() {
|
void VlcTop::rank() {
|
||||||
UINFO(2,"rank...\n");
|
UINFO(2,"rank...\n");
|
||||||
vluint64_t nextrank=1;
|
vluint64_t nextrank = 1;
|
||||||
|
|
||||||
// Sort by computrons, so fast tests get selected first
|
// Sort by computrons, so fast tests get selected first
|
||||||
std::vector<VlcTest*> bytime;
|
std::vector<VlcTest*> bytime;
|
||||||
for (VlcTests::ByName::iterator it=m_tests.begin(); it!=m_tests.end(); ++it) {
|
for (VlcTests::ByName::iterator it=m_tests.begin(); it!=m_tests.end(); ++it) {
|
||||||
VlcTest* testp = *it;
|
VlcTest* testp = *it;
|
||||||
if (testp->bucketsCovered()) { // else no points, so can't help us
|
if (testp->bucketsCovered()) { // else no points, so can't help us
|
||||||
bytime.push_back(*it);
|
bytime.push_back(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort(bytime.begin(), bytime.end(), CmpComputrons()); // Sort the vector
|
sort(bytime.begin(), bytime.end(), CmpComputrons()); // Sort the vector
|
||||||
|
|
||||||
VlcBuckets remaining;
|
VlcBuckets remaining;
|
||||||
for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
|
for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
|
||||||
VlcPoint* pointp = &points().pointNumber(it->second);
|
VlcPoint* pointp = &points().pointNumber(it->second);
|
||||||
// If any tests hit this point, then we'll need to cover it.
|
// If any tests hit this point, then we'll need to cover it.
|
||||||
if (pointp->testsCovering()) { remaining.addData(pointp->pointNum(), 1); }
|
if (pointp->testsCovering()) { remaining.addData(pointp->pointNum(), 1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional Greedy algorithm
|
// Additional Greedy algorithm
|
||||||
|
|
@ -118,26 +118,26 @@ void VlcTop::rank() {
|
||||||
// then hierarchically solve a small subset of tests, and take resulting
|
// then hierarchically solve a small subset of tests, and take resulting
|
||||||
// solution and move up to larger subset of tests. (Aka quick sort.)
|
// solution and move up to larger subset of tests. (Aka quick sort.)
|
||||||
while (1) {
|
while (1) {
|
||||||
if (debug()) { UINFO(9,"Left on iter"<<nextrank<<": "); remaining.dump(); }
|
if (debug()) { UINFO(9,"Left on iter"<<nextrank<<": "); remaining.dump(); }
|
||||||
VlcTest* bestTestp = NULL;
|
VlcTest* bestTestp = NULL;
|
||||||
vluint64_t bestRemain = 0;
|
vluint64_t bestRemain = 0;
|
||||||
for (std::vector<VlcTest*>::iterator it=bytime.begin(); it!=bytime.end(); ++it) {
|
for (std::vector<VlcTest*>::iterator it=bytime.begin(); it!=bytime.end(); ++it) {
|
||||||
VlcTest* testp = *it;
|
VlcTest* testp = *it;
|
||||||
if (!testp->rank()) {
|
if (!testp->rank()) {
|
||||||
vluint64_t remain = testp->buckets().dataPopCount(remaining);
|
vluint64_t remain = testp->buckets().dataPopCount(remaining);
|
||||||
if (remain > bestRemain) {
|
if (remain > bestRemain) {
|
||||||
bestTestp = testp;
|
bestTestp = testp;
|
||||||
bestRemain = remain;
|
bestRemain = remain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (VlcTest* testp = bestTestp) {
|
if (VlcTest* testp = bestTestp) {
|
||||||
testp->rank(nextrank++);
|
testp->rank(nextrank++);
|
||||||
testp->rankPoints(bestRemain);
|
testp->rankPoints(bestRemain);
|
||||||
remaining.orData(bestTestp->buckets());
|
remaining.orData(bestTestp->buckets());
|
||||||
} else {
|
} else {
|
||||||
break; // No test covering more stuff found
|
break; // No test covering more stuff found
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,18 +146,18 @@ void VlcTop::rank() {
|
||||||
void VlcTop::annotateCalc() {
|
void VlcTop::annotateCalc() {
|
||||||
// Calculate per-line information into filedata structure
|
// Calculate per-line information into filedata structure
|
||||||
for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
|
for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
|
||||||
const VlcPoint& point = m_points.pointNumber(it->second);
|
const VlcPoint& point = m_points.pointNumber(it->second);
|
||||||
string filename = point.filename();
|
string filename = point.filename();
|
||||||
int lineno = point.lineno();
|
int lineno = point.lineno();
|
||||||
if (!filename.empty() && lineno!=0) {
|
if (!filename.empty() && lineno!=0) {
|
||||||
int column = point.column();
|
int column = point.column();
|
||||||
VlcSource& source = sources().findNewSource(filename);
|
VlcSource& source = sources().findNewSource(filename);
|
||||||
string threshStr = point.thresh();
|
string threshStr = point.thresh();
|
||||||
unsigned thresh = (!threshStr.empty()) ? atoi(threshStr.c_str()) : opt.annotateMin();
|
unsigned thresh = (!threshStr.empty()) ? atoi(threshStr.c_str()) : opt.annotateMin();
|
||||||
bool ok = (point.count() >= thresh);
|
bool ok = (point.count() >= thresh);
|
||||||
UINFO(9, "AnnoCalc count "<<filename<<" "<<lineno<<" "<<point.count()<<endl);
|
UINFO(9, "AnnoCalc count "<<filename<<" "<<lineno<<" "<<point.count()<<endl);
|
||||||
source.incCount(lineno, column, point.count(), ok);
|
source.incCount(lineno, column, point.count(), ok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,23 +167,23 @@ void VlcTop::annotateCalcNeeded() {
|
||||||
int totCases = 0;
|
int totCases = 0;
|
||||||
int totOk = 0;
|
int totOk = 0;
|
||||||
for (VlcSources::NameMap::iterator sit=m_sources.begin(); sit!=m_sources.end(); ++sit) {
|
for (VlcSources::NameMap::iterator sit=m_sources.begin(); sit!=m_sources.end(); ++sit) {
|
||||||
VlcSource& source = sit->second;
|
VlcSource& source = sit->second;
|
||||||
//UINFO(1,"Source "<<source.name()<<endl);
|
//UINFO(1,"Source "<<source.name()<<endl);
|
||||||
if (opt.annotateAll()) source.needed(true);
|
if (opt.annotateAll()) source.needed(true);
|
||||||
VlcSource::LinenoMap& lines = source.lines();
|
VlcSource::LinenoMap& lines = source.lines();
|
||||||
for (VlcSource::LinenoMap::iterator lit=lines.begin(); lit!=lines.end(); ++lit) {
|
for (VlcSource::LinenoMap::iterator lit=lines.begin(); lit!=lines.end(); ++lit) {
|
||||||
VlcSource::ColumnMap& cmap = lit->second;
|
VlcSource::ColumnMap& cmap = lit->second;
|
||||||
for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) {
|
for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) {
|
||||||
VlcSourceCount& col = cit->second;
|
VlcSourceCount& col = cit->second;
|
||||||
//UINFO(0,"Source "<<source.name()<<" lineno="<<col.lineno()<<" col="<<col.column()<<endl);
|
//UINFO(0,"Source "<<source.name()<<" lineno="<<col.lineno()<<" col="<<col.column()<<endl);
|
||||||
++totCases;
|
++totCases;
|
||||||
if (col.ok()) {
|
if (col.ok()) {
|
||||||
++totOk;
|
++totOk;
|
||||||
} else {
|
} else {
|
||||||
source.needed(true);
|
source.needed(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float pct = totCases ? (100*totOk / totCases) : 0;
|
float pct = totCases ? (100*totOk / totCases) : 0;
|
||||||
cout<<"Total coverage ("<<totOk<<"/"<<totCases<<") "
|
cout<<"Total coverage ("<<totOk<<"/"<<totCases<<") "
|
||||||
|
|
@ -195,60 +195,61 @@ void VlcTop::annotateOutputFiles(const string& dirname) {
|
||||||
// Create if uncreated, ignore errors
|
// Create if uncreated, ignore errors
|
||||||
V3Os::createDir(dirname);
|
V3Os::createDir(dirname);
|
||||||
for (VlcSources::NameMap::iterator sit=m_sources.begin(); sit!=m_sources.end(); ++sit) {
|
for (VlcSources::NameMap::iterator sit=m_sources.begin(); sit!=m_sources.end(); ++sit) {
|
||||||
VlcSource& source = sit->second;
|
VlcSource& source = sit->second;
|
||||||
if (!source.needed()) continue;
|
if (!source.needed()) continue;
|
||||||
string filename = source.name();
|
string filename = source.name();
|
||||||
string outfilename = dirname+"/"+V3Os::filenameNonDir(filename);
|
string outfilename = dirname+"/"+V3Os::filenameNonDir(filename);
|
||||||
|
|
||||||
UINFO(1,"annotateOutputFile "<<filename<<" -> "<<outfilename<<endl);
|
UINFO(1,"annotateOutputFile "<<filename<<" -> "<<outfilename<<endl);
|
||||||
|
|
||||||
std::ifstream is(filename.c_str());
|
std::ifstream is(filename.c_str());
|
||||||
if (!is) {
|
if (!is) {
|
||||||
v3error("Can't read "<<filename);
|
v3error("Can't read "<<filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ofstream os(outfilename.c_str());
|
std::ofstream os(outfilename.c_str());
|
||||||
if (!os) {
|
if (!os) {
|
||||||
v3fatal("Can't write "<<outfilename);
|
v3fatal("Can't write "<<outfilename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "\t// verilator_coverage annotation"<<endl;
|
os << "\t// verilator_coverage annotation"<<endl;
|
||||||
|
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
while (!is.eof()) {
|
while (!is.eof()) {
|
||||||
lineno++;
|
lineno++;
|
||||||
string line = V3Os::getline(is);
|
string line = V3Os::getline(is);
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
VlcSource::LinenoMap& lines = source.lines();
|
VlcSource::LinenoMap& lines = source.lines();
|
||||||
VlcSource::LinenoMap::iterator lit=lines.find(lineno);
|
VlcSource::LinenoMap::iterator lit=lines.find(lineno);
|
||||||
if (lit != lines.end()) {
|
if (lit != lines.end()) {
|
||||||
VlcSource::ColumnMap& cmap = lit->second;
|
VlcSource::ColumnMap& cmap = lit->second;
|
||||||
for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) {
|
for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) {
|
||||||
VlcSourceCount& col = cit->second;
|
VlcSourceCount& col = cit->second;
|
||||||
//UINFO(0,"Source "<<source.name()<<" lineno="<<col.lineno()<<" col="<<col.column()<<endl);
|
//UINFO(0,"Source "<<source.name()<<" lineno="<<col.lineno()<<" col="<<col.column()<<endl);
|
||||||
os<<(col.ok()?" ":"%")
|
os<<(col.ok()?" ":"%")
|
||||||
<<std::setfill('0')<<std::setw(6)<<col.count()
|
<<std::setfill('0')<<std::setw(6)<<col.count()
|
||||||
<<"\t"<<line<<endl;
|
<<"\t"<<line<<endl;
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
// Multiple columns on same line; print line just once
|
// Multiple columns on same line; print line just once
|
||||||
string indent;
|
string indent;
|
||||||
for (string::const_iterator pos=line.begin(); pos!=line.end() && isspace(*pos); ++pos) {
|
for (string::const_iterator pos=line.begin();
|
||||||
indent += *pos;
|
pos!=line.end() && isspace(*pos); ++pos) {
|
||||||
}
|
indent += *pos;
|
||||||
line = indent + "verilator_coverage: (next point on previous line)\n";
|
}
|
||||||
}
|
line = indent + "verilator_coverage: (next point on previous line)\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
os<<"\t"<<line<<endl;
|
os<<"\t"<<line<<endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,4 +259,3 @@ void VlcTop::annotate(const string& dirname) {
|
||||||
annotateCalcNeeded();
|
annotateCalcNeeded();
|
||||||
annotateOutputFiles(dirname);
|
annotateOutputFiles(dirname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1420,16 +1420,16 @@ sub _make_top_v {
|
||||||
# Test
|
# Test
|
||||||
print $fh "\n";
|
print $fh "\n";
|
||||||
print $fh " initial begin\n";
|
print $fh " initial begin\n";
|
||||||
print $fh " fastclk=0;\n" if $self->{inputs}{fastclk};
|
print $fh " fastclk = 0;\n" if $self->{inputs}{fastclk};
|
||||||
print $fh " clk=0;\n" if $self->{inputs}{clk};
|
print $fh " clk = 0;\n" if $self->{inputs}{clk};
|
||||||
print $fh " #10;\n";
|
print $fh " #10;\n";
|
||||||
print $fh " fastclk=1;\n" if $self->{inputs}{fastclk};
|
print $fh " fastclk = 1;\n" if $self->{inputs}{fastclk};
|
||||||
print $fh " clk=1;\n" if $self->{inputs}{clk};
|
print $fh " clk = 1;\n" if $self->{inputs}{clk};
|
||||||
print $fh " while (\$time < $self->{sim_time}) begin\n";
|
print $fh " while (\$time < $self->{sim_time}) begin\n";
|
||||||
for (my $i=0; $i<5; $i++) {
|
for (my $i=0; $i<5; $i++) {
|
||||||
print $fh " #1;\n";
|
print $fh " #1;\n";
|
||||||
print $fh " fastclk=!fastclk;\n" if $self->{inputs}{fastclk};
|
print $fh " fastclk = !fastclk;\n" if $self->{inputs}{fastclk};
|
||||||
print $fh " clk=!clk;\n" if $i==4 && $self->{inputs}{clk};
|
print $fh " clk = !clk;\n" if $i==4 && $self->{inputs}{clk};
|
||||||
}
|
}
|
||||||
print $fh " end\n";
|
print $fh " end\n";
|
||||||
print $fh " end\n";
|
print $fh " end\n";
|
||||||
|
|
@ -1657,7 +1657,7 @@ sub vcd_identical {
|
||||||
# Also provides backup if vcddiff not installed
|
# Also provides backup if vcddiff not installed
|
||||||
my $h1 = $self->_vcd_read($fn1);
|
my $h1 = $self->_vcd_read($fn1);
|
||||||
my $h2 = $self->_vcd_read($fn2);
|
my $h2 = $self->_vcd_read($fn2);
|
||||||
$Data::Dumper::Sortkeys=1;
|
$Data::Dumper::Sortkeys = 1;
|
||||||
my $a = Dumper($h1);
|
my $a = Dumper($h1);
|
||||||
my $b = Dumper($h2);
|
my $b = Dumper($h2);
|
||||||
if ($a ne $b) {
|
if ($a ne $b) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue