mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 12:17:35 +00:00
Declare V3Tables static
git-svn-id: file://localhost/svn/verilator/trunk/verilator@763 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
eec5c8bf6d
commit
3b09ceae12
2
Changes
2
Changes
@ -7,6 +7,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
*** Added --inhibit-sim flag for environments using old __Vm_inhibitSim.
|
||||
|
||||
**** Declare tables static, to reduce D-Cache miss rate.
|
||||
|
||||
* Verilator 3.600 08/28/2006
|
||||
|
||||
** Support dotted cross-hierarchy variable and task references.
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
void displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, char fmtLetter);
|
||||
|
||||
void emitVarDecl(AstVar* nodep, const string& prefixIfImp);
|
||||
typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_ALL} EisWhich;
|
||||
typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_STATIC, EVL_ALL} EisWhich;
|
||||
void emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp);
|
||||
void emitVarCtors();
|
||||
bool emitSimpleOk(AstNodeMath* nodep);
|
||||
@ -597,16 +597,16 @@ class EmitCImp : EmitCStmts {
|
||||
+"<<endl; );\n");
|
||||
|
||||
if (nodep->initsp()) puts("// Variables\n");
|
||||
ofp()->putAlign(4);
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
|
||||
for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* varp=subnodep->castVar()) {
|
||||
if (varp->isFuncReturn()) emitVarDecl(varp, "");
|
||||
}
|
||||
}
|
||||
emitVarList(nodep->initsp(), EVL_ALL, "");
|
||||
ofp()->putAlign(4);
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
|
||||
emitVarList(nodep->stmtsp(), EVL_ALL, "");
|
||||
ofp()->putAlign(4);
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
|
||||
|
||||
nodep->initsp()->iterateAndNext(*this);
|
||||
|
||||
@ -693,7 +693,7 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
if (nodep->isIO()) {
|
||||
if (nodep->isSc()) {
|
||||
m_ctorVarsVec.push_back(nodep);
|
||||
ofp()->putAlign(4); // sc stuff is a structure, so bigger alignment
|
||||
ofp()->putAlign(nodep->isStatic(), 4); // sc stuff is a structure, so bigger alignment
|
||||
if (nodep->attrScClocked() && nodep->isInput()) {
|
||||
puts("sc_in_clk\t");
|
||||
} else {
|
||||
@ -708,7 +708,7 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
puts(nodep->name());
|
||||
puts(";\n");
|
||||
} else { // C++ signals
|
||||
ofp()->putAlign(nodep->widthAlignBytes());
|
||||
ofp()->putAlign(nodep->isStatic(), nodep->widthAlignBytes());
|
||||
if (nodep->isTristate()) puts("VL_INOUT");
|
||||
else if (nodep->isInput()) puts("VL_IN");
|
||||
else if (nodep->isOutput()) puts("VL_OUT");
|
||||
@ -731,8 +731,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
} else {
|
||||
// Arrays need a small alignment, but may need different padding after.
|
||||
// For example three VL_SIG8's needs alignment 1 but size 3.
|
||||
ofp()->putAlign(nodep->widthAlignBytes(), nodep->arrayElements()*nodep->widthAlignBytes());
|
||||
// if (nodep->isStatic()) puts("static "); // Need implementation declaration too - prefixIfImp is start in this direction
|
||||
ofp()->putAlign(nodep->isStatic(), nodep->widthAlignBytes(), nodep->arrayElements()*nodep->widthAlignBytes());
|
||||
if (nodep->isStatic() && prefixIfImp=="") puts("static ");
|
||||
if (nodep->widthMin() <= 8) {
|
||||
puts("VL_SIG8(");
|
||||
} else if (nodep->widthMin() <= 16) {
|
||||
@ -1109,7 +1109,7 @@ void EmitCImp::emitCoverageDecl(AstModule* modp) {
|
||||
ofp()->putsPrivate(true);
|
||||
puts("// Coverage\n");
|
||||
puts("SpZeroed<uint32_t>\t__Vcoverage["); puts(cvtToStr(m_coverIds.size())); puts("];\n");
|
||||
ofp()->putAlign(sizeof(uint32_t)*m_coverIds.size());
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint32_t)*m_coverIds.size());
|
||||
// Rather then putting out SP_COVER_INSERT calls directly, we do it via this function
|
||||
// This gets around gcc slowness constructing all of the template arguments
|
||||
puts("void _vlCoverInsert(SpZeroed<uint32_t>* countp, const char* filename, int lineno, int column,\n");
|
||||
@ -1239,35 +1239,41 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
||||
// Put out a list of signal declarations
|
||||
// in order of 0:clocks, 1:uint8, 2:uint16, 4:uint32, 5:uint64, 6:wide, 7:arrays
|
||||
// This aids cache packing and locality
|
||||
for (int size=0; size<8; size++) {
|
||||
if (size==3) continue;
|
||||
for (AstNode* nodep=firstp; nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
bool doit = true;
|
||||
switch (which) {
|
||||
case EVL_ALL: doit = true; break;
|
||||
case EVL_IO: doit = varp->isIO(); break;
|
||||
case EVL_SIG: doit = (varp->isSignal() && !varp->isIO()); break;
|
||||
case EVL_TEMP: doit = varp->isTemp(); break;
|
||||
default: v3fatalSrc("Bad Case");
|
||||
}
|
||||
if (doit) {
|
||||
int sigbytes = varp->widthAlignBytes();
|
||||
if (varp->isUsedClock() && varp->widthMin()==1) sigbytes = 0;
|
||||
else if (varp->arraysp()) sigbytes=7;
|
||||
else if (varp->isScWide()) sigbytes=6;
|
||||
else if (sigbytes==8) sigbytes=5;
|
||||
else if (sigbytes==4) sigbytes=4;
|
||||
else if (sigbytes==2) sigbytes=2;
|
||||
else if (sigbytes==1) sigbytes=1;
|
||||
if (size==sigbytes) {
|
||||
emitVarDecl(varp, prefixIfImp);
|
||||
// Largest->smallest reduces the number of pad variables.
|
||||
// But for now, Smallest->largest makes it more likely a small offset will allow access to the signal.
|
||||
for (int isstatic=1; isstatic>=0; isstatic--) {
|
||||
if (prefixIfImp!="" && !isstatic) continue;
|
||||
for (int size=0; size<8; size++) {
|
||||
if (size==3) continue;
|
||||
for (AstNode* nodep=firstp; nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
bool doit = true;
|
||||
switch (which) {
|
||||
case EVL_ALL: doit = true; break;
|
||||
case EVL_IO: doit = varp->isIO(); break;
|
||||
case EVL_SIG: doit = (varp->isSignal() && !varp->isIO()); break;
|
||||
case EVL_TEMP: doit = varp->isTemp(); break;
|
||||
default: v3fatalSrc("Bad Case");
|
||||
}
|
||||
if (varp->isStatic() ? !isstatic : isstatic) doit=false;
|
||||
if (doit) {
|
||||
int sigbytes = varp->widthAlignBytes();
|
||||
if (varp->isUsedClock() && varp->widthMin()==1) sigbytes = 0;
|
||||
else if (varp->arraysp()) sigbytes=7;
|
||||
else if (varp->isScWide()) sigbytes=6;
|
||||
else if (sigbytes==8) sigbytes=5;
|
||||
else if (sigbytes==4) sigbytes=4;
|
||||
else if (sigbytes==2) sigbytes=2;
|
||||
else if (sigbytes==1) sigbytes=1;
|
||||
if (size==sigbytes) {
|
||||
emitVarDecl(varp, prefixIfImp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ofp()->putAlign(isstatic, 4, 0, prefixIfImp.c_str());
|
||||
}
|
||||
ofp()->putAlign(4, 0, prefixIfImp.c_str());
|
||||
}
|
||||
|
||||
struct CmpName {
|
||||
@ -1354,22 +1360,22 @@ void EmitCImp::emitInt(AstModule* modp) {
|
||||
|
||||
puts("\n// INTERNAL VARIABLES\n");
|
||||
ofp()->putsPrivate(!modp->isTop()); // private: unless top
|
||||
ofp()->putAlign(8);
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 8);
|
||||
puts(symClassName()+"*\t__VlSymsp;\t\t// Symbol table\n");
|
||||
ofp()->putsPrivate(false); // public:
|
||||
if (modp->isTop()) {
|
||||
if (v3Global.opt.inhibitSim()) {
|
||||
ofp()->putAlign(sizeof(bool));
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
||||
puts("bool\t__Vm_inhibitSim;\t///< Set true to disable evaluation of module\n");
|
||||
}
|
||||
ofp()->putAlign(sizeof(bool));
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
||||
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
|
||||
ofp()->putAlign(sizeof(bool));
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
||||
puts("bool\t__Vm_didInit;\n");
|
||||
}
|
||||
ofp()->putAlign(8);
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 8);
|
||||
emitCoverageDecl(modp); // may flip public/private
|
||||
ofp()->putAlign(8);
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 8);
|
||||
|
||||
puts("\n// PARAMETERS\n");
|
||||
ofp()->putsPrivate(false); // public:
|
||||
@ -1482,6 +1488,13 @@ void EmitCImp::emitImp(AstModule* modp) {
|
||||
}
|
||||
|
||||
emitTextSection(AstType::SCIMPHDR);
|
||||
|
||||
if (m_slow && m_splitFilenum==0) {
|
||||
puts("\n//--------------------\n");
|
||||
puts("// STATIC VARIABLES\n\n");
|
||||
emitVarList(modp->stmtsp(), EVL_ALL, modClassName(modp));
|
||||
}
|
||||
|
||||
if (m_fast && m_splitFilenum==0) {
|
||||
emitTextSection(AstType::SCIMP);
|
||||
emitStaticDecl(modp);
|
||||
@ -1770,7 +1783,7 @@ class EmitCTrace : EmitCStmts {
|
||||
if (nodep->initsp()) puts("// Variables\n");
|
||||
emitVarList(nodep->initsp(), EVL_ALL, "");
|
||||
nodep->initsp()->iterateAndNext(*this);
|
||||
ofp()->putAlign(4);
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
|
||||
|
||||
puts("// Body\n");
|
||||
puts("{\n");
|
||||
|
@ -225,7 +225,7 @@ bool V3File::checkTimes(const string& filename, const string& cmdline) {
|
||||
|
||||
V3OutFile::V3OutFile(const string& filename)
|
||||
: m_lineno(1), m_column(0), m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
|
||||
, m_declAlign(0), m_declPadNum(0) {
|
||||
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
|
||||
if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) {
|
||||
v3fatal("Cannot write "<<filename);
|
||||
}
|
||||
@ -440,19 +440,20 @@ void V3OutFile::putcNoTracking (char chr) {
|
||||
fputc (chr, m_fp);
|
||||
}
|
||||
|
||||
void V3OutFile::putAlign (int align, int size, const char* prefix) {
|
||||
void V3OutFile::putAlign (bool/*AlignClass*/ isStatic, int align, int size, const char* prefix) {
|
||||
if (size==0) size=align;
|
||||
int alignSize = size; if (alignSize>8) alignSize=8;
|
||||
int padsize = alignSize - (m_declAlign % alignSize);
|
||||
int& alignr = isStatic ? m_declSAlign : m_declNSAlign;
|
||||
int padsize = alignSize - (alignr % alignSize);
|
||||
if (padsize && padsize!=alignSize) {
|
||||
puts("char\t");
|
||||
puts(prefix);
|
||||
puts("__VpadToAlign"+cvtToStr(m_declPadNum)
|
||||
puts("__VpadToAlign"+cvtToStr(alignr)
|
||||
+"["+cvtToStr(padsize)+"];\n");
|
||||
m_declAlign += padsize;
|
||||
alignr += padsize;
|
||||
m_declPadNum++;
|
||||
}
|
||||
m_declAlign += size;
|
||||
alignr += size;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
22
src/V3File.h
22
src/V3File.h
@ -64,24 +64,32 @@ public:
|
||||
// V3OutFile: A class for printing to a file, with automatic indentation of C++ code.
|
||||
|
||||
class V3OutFile {
|
||||
// TYPES
|
||||
enum MiscConsts {
|
||||
INDBLK = 4, // Indentation per block level
|
||||
WIDTH = 50, // Width after which to break at ,'s
|
||||
MAXSPACE = 80}; // After this indent, stop indenting more
|
||||
public:
|
||||
enum AlignClass {
|
||||
AL_AUTO = 0,
|
||||
AL_STATIC = 1};
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
FILE* m_fp;
|
||||
int m_lineno;
|
||||
int m_column;
|
||||
int m_nobreak; // Basic operator or begin paren, don't break next
|
||||
bool m_prependIndent;
|
||||
int m_indentLevel; // Current {} indentation
|
||||
int m_declAlign; // Byte alignment of next declaration
|
||||
int m_declSAlign; // Byte alignment of next declaration, statics
|
||||
int m_declNSAlign; // Byte alignment of next declaration, nonstatics
|
||||
int m_declPadNum; // Pad variable number
|
||||
stack<int> m_parenVec; // Stack of columns where last ( was
|
||||
|
||||
int endLevels(const char* strg);
|
||||
static const char* indentStr(int levels);
|
||||
|
||||
enum MiscConsts {
|
||||
INDBLK = 4, // Indentation per block level
|
||||
WIDTH = 50, // Width after which to break at ,'s
|
||||
MAXSPACE = 80}; // After this indent, stop indenting more
|
||||
|
||||
public:
|
||||
V3OutFile(const string& filename);
|
||||
~V3OutFile();
|
||||
@ -95,7 +103,7 @@ public:
|
||||
void putsNoTracking(const string& strg) { putsNoTracking(strg.c_str()); }
|
||||
void putBreak(); // Print linebreak if line is too wide
|
||||
void putBreakExpr(); // Print linebreak in expression if line is too wide
|
||||
void putAlign(int align, int size=0/*=align*/, const char* prefix=""); // Declare a variable, with natural alignment
|
||||
void putAlign(bool isstatic/*AlignClass*/, int align, int size=0/*=align*/, const char* prefix=""); // Declare a variable, with natural alignment
|
||||
void putbs(const char* strg) { putBreakExpr(); puts(strg); }
|
||||
void putbs(const string& strg) { putBreakExpr(); puts(strg); }
|
||||
bool exceededWidth() const { return m_column > WIDTH; }
|
||||
|
Loading…
Reference in New Issue
Block a user