mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 08:33:21 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce531c5a67 | ||
|
|
52e36fb434 | ||
|
|
100d5b386c | ||
|
|
699563c9bd | ||
|
|
a599fbea18 |
@@ -3,12 +3,16 @@ Revision history for Verilator
|
||||
The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.62***
|
||||
* Verilator 3.630 12/19/2006
|
||||
|
||||
** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich]
|
||||
|
||||
*** Fixed configure and compiling under Solaris. [Bob Farrell]
|
||||
|
||||
*** When dotted signal lookup fails, help the user by showing known scopes.
|
||||
|
||||
*** Reduce depth of priority encoded case statements. [Eugene Weber]
|
||||
|
||||
**** Fix dotted references inside generated cells. [David Hewson]
|
||||
|
||||
**** Fix missed split optimization points underneath other re-split blocks.
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ DISTDEP = info Makefile
|
||||
# Files to distribute.
|
||||
DISTBIN = $(wildcard bin/verilator-*)
|
||||
|
||||
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in \
|
||||
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in *.ac \
|
||||
Changes README TODO \
|
||||
bin/* \
|
||||
install-sh configure mkinstalldirs *.texi \
|
||||
|
||||
+25
-10
@@ -879,6 +879,10 @@ disadvantage of this approach is that include/verilatedos.h must
|
||||
self-detect the requirements of the target system, rather then using
|
||||
configure.
|
||||
|
||||
The target system may also require edits to the Makefiles, the simple
|
||||
Makefiles produced by Verilator presume the target system is the same type
|
||||
as the build system.
|
||||
|
||||
=head1 VERILOG 2001 SUPPORT
|
||||
|
||||
Verilator supports the more common Verilog 2001 language features. This
|
||||
@@ -992,16 +996,6 @@ Verilog standard, %x prints a number with the natural width, %0x prints a
|
||||
number with minimum width, however %5x prints 5 digits per the C standard
|
||||
(it's unspecified in Verilog).
|
||||
|
||||
=item $fopen, $fclose, $fdisplay, $fwrite
|
||||
|
||||
File descriptors passed to the file PLI calls must be file descriptors, not
|
||||
MCDs, which includes the mode parameter to $fopen being mandatory.
|
||||
Verilator will convert the integer used to hold the file descriptor into a
|
||||
internal FILE*. To prevent core dumps due to mis-use, and because integers
|
||||
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
|
||||
reg [63:0] rather then an integer. The define `verilator_file_descriptor in
|
||||
verilated.v can be used to hide this difference.
|
||||
|
||||
=item `coverage_block_off
|
||||
|
||||
Specifies the entire begin/end block should be ignored for coverage analysis.
|
||||
@@ -1312,6 +1306,27 @@ appropriate width.
|
||||
$display and friends must have a constant format string as the first
|
||||
argument (as with C's printf), you cannot simply list variables standalone.
|
||||
|
||||
=item $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc
|
||||
|
||||
The sized display functions are rarely used and so not supported. Replace
|
||||
them with a $write with the appropriate format specifier.
|
||||
|
||||
=item $fopen, $fclose, $fdisplay, $fwrite
|
||||
|
||||
File descriptors passed to the file PLI calls must be file descriptors, not
|
||||
MCDs, which includes the mode parameter to $fopen being mandatory.
|
||||
Verilator will convert the integer used to hold the file descriptor into a
|
||||
internal FILE*. To prevent core dumps due to mis-use, and because integers
|
||||
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
|
||||
reg [63:0] rather then an integer. The define `verilator_file_descriptor in
|
||||
verilated.v can be used to hide this difference.
|
||||
|
||||
=item $readmemb, $readmemh
|
||||
|
||||
Read memory commands should work properly. Note Verilator and the Verilog
|
||||
specification does not include support for readmem to multi-dimensional
|
||||
arrays.
|
||||
|
||||
=head1 ERRORS AND WARNINGS
|
||||
|
||||
Warnings may be disabled in two ways. First, when the warning is
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "verilated.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
|
||||
|
||||
@@ -238,6 +239,113 @@ QData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
|
||||
return VL_CVT_FP_Q(fopen(filenamez,modez));
|
||||
}
|
||||
|
||||
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
|
||||
QData ofilename, void* memp, IData start, IData end) {
|
||||
IData fnw[2]; VL_SET_WQ(fnw, ofilename);
|
||||
return VL_READMEM_W(hex,2,width,depth,array_lsb, fnw,memp,start,end);
|
||||
}
|
||||
|
||||
void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
WDataInP ofilenamep, void* memp, IData start, IData end) {
|
||||
char ofilenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
|
||||
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, ofilenamez, ofilenamep);
|
||||
FILE* fp = fopen(ofilenamez, "r");
|
||||
if (!fp) {
|
||||
// We don't report the Verilog source filename as it slow to have to pass it down
|
||||
vl_fatal (ofilenamez, 0, "", "$readmem file not found");
|
||||
return;
|
||||
}
|
||||
// Prep for reading
|
||||
IData addr = start;
|
||||
int linenum = 0;
|
||||
bool innum = false;
|
||||
bool ignore_to_eol = false;
|
||||
bool ignore_to_cmt = false;
|
||||
bool needinc = false;
|
||||
bool reading_addr = false;
|
||||
int lastc = ' ';
|
||||
// Read the data
|
||||
// We process a character at a time, as then we don't need to deal
|
||||
// with changing buffer sizes dynamically, etc.
|
||||
while (1) {
|
||||
int c = fgetc(fp);
|
||||
if (c==EOF) break;
|
||||
//printf("%d: Got '%c' Addr%x IN%d IgE%d IgC%d ninc%d\n", linenum, c, addr, innum, ignore_to_eol, ignore_to_cmt, needinc);
|
||||
if (c=='\n') { linenum++; ignore_to_eol=false; if (innum) reading_addr=false; innum=false; }
|
||||
else if (c=='\t' || c==' ' || c=='\r' || c=='\f') { if (innum) reading_addr=false; innum=false; }
|
||||
// Skip // comments and detect /* comments
|
||||
else if (ignore_to_cmt && lastc=='*' && c=='/') {
|
||||
ignore_to_cmt = false; if (innum) reading_addr=false; innum=false;
|
||||
} else if (!ignore_to_eol && !ignore_to_cmt) {
|
||||
if (lastc=='/' && c=='*') { ignore_to_cmt = true; }
|
||||
else if (lastc=='/' && c=='/') { ignore_to_eol = true; }
|
||||
else if (c=='/') {} // Part of /* or //
|
||||
else if (c=='_') {}
|
||||
else if (c=='@') { reading_addr = true; innum=false; needinc=false; }
|
||||
// Check for hex or binary digits as file format requests
|
||||
else if (isxdigit(c)) {
|
||||
c = tolower(c);
|
||||
int value = (c >= 'a' ? (c-'a'+10) : (c-'0'));
|
||||
if (!innum) { // Prep for next number
|
||||
if (needinc) { addr++; needinc=false; }
|
||||
}
|
||||
if (reading_addr) {
|
||||
// Decode @ addresses
|
||||
if (!innum) addr=0;
|
||||
addr = (addr<<4) + value;
|
||||
} else {
|
||||
needinc = true;
|
||||
//printf(" Value width=%d @%x = %c\n", width, addr, c);
|
||||
if (addr >= (IData)(depth+array_lsb) || addr < (IData)(array_lsb)) {
|
||||
vl_fatal (ofilenamez, linenum, "", "$readmem file address beyond bounds of array");
|
||||
} else {
|
||||
int entry = addr - array_lsb;
|
||||
QData shift = hex ? VL_ULL(4) : VL_ULL(1);
|
||||
// Shift value in
|
||||
if (width<=8) {
|
||||
CData* datap = &((CData*)(memp))[entry];
|
||||
if (!innum) { *datap = 0; }
|
||||
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
|
||||
} else if (width<=16) {
|
||||
SData* datap = &((SData*)(memp))[entry];
|
||||
if (!innum) { *datap = 0; }
|
||||
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
|
||||
} else if (width<=VL_WORDSIZE) {
|
||||
IData* datap = &((IData*)(memp))[entry];
|
||||
if (!innum) { *datap = 0; }
|
||||
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
|
||||
} else if (width<=VL_QUADSIZE) {
|
||||
QData* datap = &((QData*)(memp))[entry];
|
||||
if (!innum) { *datap = 0; }
|
||||
*datap = ((*datap << (QData)(shift)) + (QData)(value)) & VL_MASK_Q(width);
|
||||
} else {
|
||||
WDataOutP datap = &((WDataOutP)(memp))[ entry*VL_WORDS_I(width) ];
|
||||
if (!innum) { VL_ZERO_RESET_W(width, datap); }
|
||||
_VL_SHIFTL_INPLACE_W(width, datap, shift);
|
||||
datap[0] |= value;
|
||||
}
|
||||
if (value>=(1<<shift)) {
|
||||
vl_fatal (ofilenamez, linenum, "", "$readmemb (binary) file contains hex characters");
|
||||
}
|
||||
}
|
||||
}
|
||||
innum = true;
|
||||
}
|
||||
else {
|
||||
vl_fatal (ofilenamez, linenum, "", "$readmem file syntax error");
|
||||
}
|
||||
}
|
||||
lastc = c;
|
||||
}
|
||||
if (needinc) { addr++; needinc=false; }
|
||||
|
||||
// Final checks
|
||||
fclose(fp);
|
||||
if (end != (IData)(~ VL_ULL(0)) && addr != (end+1)) {
|
||||
vl_fatal (ofilenamez, linenum, "", "$readmem file ended before specified ending-address");
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Verilated:: Methods
|
||||
|
||||
|
||||
+30
-3
@@ -194,9 +194,17 @@ inline const char* VL_VALUE_FORMATTED_I(int obits, char fmt, bool drop0, IData l
|
||||
}
|
||||
|
||||
/// File I/O
|
||||
extern QData VL_FOPEN_WI(int fnwords, WDataInP filename, IData mode);
|
||||
extern QData VL_FOPEN_QI(QData filename, IData mode);
|
||||
inline QData VL_FOPEN_II(IData filename, IData mode) { return VL_FOPEN_QI(filename,mode); }
|
||||
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
|
||||
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
||||
|
||||
extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
WDataInP ofilename, void* memp, IData start, IData end);
|
||||
extern void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
QData ofilename, void* memp, IData start, IData end);
|
||||
inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
IData ofilename, void* memp, IData start, IData end) {
|
||||
VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); }
|
||||
|
||||
//=========================================================================
|
||||
// Base macros
|
||||
@@ -226,6 +234,13 @@ static inline QData VL_CVT_FP_Q(FILE* fp) { union { FILE* fp; QData q; } u; u.q
|
||||
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); }
|
||||
static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); }
|
||||
|
||||
// Debugging prints
|
||||
static inline void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) {
|
||||
printf(" Data: w%d: ", lbits);
|
||||
for (int i=VL_WORDS_I(lbits)-1; i>=0; i--) { printf("%08x ",iwp[i]); }
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Pli macros
|
||||
|
||||
@@ -1035,6 +1050,18 @@ static inline WDataOutP VL_CONCAT_WWW(int obits,int lbits,int rbits,WDataOutP ow
|
||||
//===================================================================
|
||||
// Shifts
|
||||
|
||||
// Static shift, used by internal functions
|
||||
// The output is the same as the input - it overlaps!
|
||||
static inline void _VL_SHIFTL_INPLACE_W(int obits,WDataOutP iowp,IData rd/*1 or 4*/) {
|
||||
int words = VL_WORDS_I(obits);
|
||||
IData linsmask = VL_MASK_I(rd);
|
||||
for (int i=words-1; i>=1; i--) {
|
||||
iowp[i] = ((iowp[i]<<rd) & ~linsmask) | ((iowp[i-1] >> (32-rd)) & linsmask);
|
||||
}
|
||||
iowp[0] = ((iowp[0]<<rd) & ~linsmask);
|
||||
iowp[VL_WORDS_I(obits)-1] &= VL_MASK_I(obits);
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_SHIFTL: oclean=lclean; rclean==clean;
|
||||
// Important: Unlike most other funcs, the shift might well be a computed
|
||||
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
|
||||
|
||||
@@ -1167,6 +1167,7 @@ public:
|
||||
virtual int instrCount() const { return widthInstrs()+instrCountBranch(); }
|
||||
AstNode* condsp() const { return op1p()->castNode(); } // op1= list of possible matching expressions
|
||||
AstNode* bodysp() const { return op2p()->castNode(); } // op2= what to do
|
||||
void condsp(AstNode* nodep) { setOp1p(nodep); }
|
||||
void addBodysp(AstNode* newp) { addOp2p(newp); }
|
||||
bool isDefault() const { return condsp()==NULL; }
|
||||
bool ignoreOverlap() const { return m_ignoreOverlap; }
|
||||
@@ -1251,6 +1252,34 @@ struct AstFOpen : public AstNodeStmt {
|
||||
AstNode* modep() const { return op3p(); }
|
||||
};
|
||||
|
||||
struct AstReadMem : public AstNodeStmt {
|
||||
private:
|
||||
bool m_isHex; // readmemh, not readmemb
|
||||
public:
|
||||
AstReadMem(FileLine* fileline, bool hex,
|
||||
AstNode* filenamep, AstNode* memp, AstNode* lsbp, AstNode* msbp)
|
||||
: AstNodeStmt (fileline), m_isHex(hex) {
|
||||
setOp1p(filenamep); setOp2p(memp); setNOp3p(lsbp); setNOp4p(msbp);
|
||||
}
|
||||
virtual ~AstReadMem() {}
|
||||
virtual AstType type() const { return AstType::READMEM;}
|
||||
virtual AstNode* clone() { return new AstReadMem(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string verilogKwd() const { return (isHex()?"$readmemh":"$readmemb"); };
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual bool isSplittable() const { return false; }
|
||||
virtual bool isOutputter() const { return true; }
|
||||
virtual bool isUnlikely() const { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return isHex()==samep->castReadMem()->isHex(); }
|
||||
bool isHex() const { return m_isHex; }
|
||||
AstNode* filenamep() const { return op1p()->castNode(); }
|
||||
AstNode* memp() const { return op2p()->castNode(); }
|
||||
AstNode* lsbp() const { return op3p()->castNode(); }
|
||||
AstNode* msbp() const { return op4p()->castNode(); }
|
||||
};
|
||||
|
||||
struct AstGenFor : public AstNodeFor {
|
||||
AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
|
||||
AstNode* incsp, AstNode* bodysp)
|
||||
|
||||
+63
-25
@@ -52,6 +52,7 @@
|
||||
|
||||
#define CASE_OVERLAP_WIDTH 12 // Maximum width we can check for overlaps in
|
||||
#define CASE_BARF 999999 // Magic width when non-constant
|
||||
#define CASE_ENCODER_GROUP_DEPTH 8 // Levels of priority to be ORed together in top IF tree
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -275,21 +276,15 @@ private:
|
||||
// IF((EQ (AND MASK cexpr) (AND MASK icond1)
|
||||
// ,istmts2, istmts3
|
||||
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
|
||||
AstNode* ifrootp = NULL;
|
||||
AstNode* ifnextp = NULL;
|
||||
// We'll do this in two stages. First stage, convert the conditions to
|
||||
// the appropriate IF AND terms.
|
||||
if (debug()>=9) nodep->dumpTree(cout," _comp_IN: ");
|
||||
bool hadDefault = false;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
|
||||
if (istmtsp) istmtsp->unlinkFrBackWithNext();
|
||||
if (!itemp->condsp()) {
|
||||
// Default clause. We reordered in link, so default is always last
|
||||
if (ifnextp) {
|
||||
if (istmtsp) ifnextp->castIf()->addElsesp(istmtsp);
|
||||
} else { // Just a empty case default: endcase
|
||||
ifnextp = istmtsp;
|
||||
}
|
||||
if (!ifrootp) ifrootp = istmtsp;
|
||||
ifnextp = istmtsp;
|
||||
itemp = NULL; break;
|
||||
// Default clause. Just make true, we'll optimize it away later
|
||||
itemp->condsp(new AstConst(itemp->fileline(), V3Number(itemp->fileline(), 1,1)));
|
||||
hadDefault = true;
|
||||
} else {
|
||||
// Expressioned clause
|
||||
AstNode* icondNextp = NULL;
|
||||
@@ -324,24 +319,67 @@ private:
|
||||
ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the new IF and attach in the tree
|
||||
if (ifexprp) {
|
||||
AstIf* newp = new AstIf(itemp->fileline(), ifexprp, istmtsp, NULL);
|
||||
if (ifnextp) {
|
||||
ifnextp->castIf()->addElsesp(newp);
|
||||
}
|
||||
if (!ifrootp) ifrootp = newp;
|
||||
ifnextp = newp;
|
||||
}
|
||||
// Replace expression in tree
|
||||
itemp->condsp(ifexprp);
|
||||
}
|
||||
}
|
||||
if (!hadDefault) {
|
||||
// If there was no default, add a empty one, this greatly simplifies below code
|
||||
// and constant propagation will just eliminate it for us later.
|
||||
nodep->addItemsp(new AstCaseItem(nodep->fileline(),
|
||||
new AstConst(nodep->fileline(), V3Number(nodep->fileline(),1,1)),
|
||||
NULL));
|
||||
}
|
||||
if (debug()>=9) nodep->dumpTree(cout," _comp_COND: ");
|
||||
// Now build the IF statement tree
|
||||
// The tree can be quite huge. Pull ever group of 8 out, and make a OR tree.
|
||||
// This reduces the depth for the bottom elements, at the cost of some of the top elements.
|
||||
// If we ever have profiling data, we should pull out the most common item from here and
|
||||
// instead make it the first IF branch.
|
||||
int depth = 0;
|
||||
AstNode* grouprootp = NULL;
|
||||
AstIf* groupnextp = NULL;
|
||||
AstIf* itemnextp = NULL;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
|
||||
if (istmtsp) istmtsp->unlinkFrBackWithNext();
|
||||
// Expressioned clause
|
||||
AstNode* ifexprp = itemp->condsp()->unlinkFrBack();
|
||||
{ // Prepare for next group
|
||||
if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1;
|
||||
if (depth == 1) { // First group or starting new group
|
||||
itemnextp = NULL;
|
||||
AstIf* newp = new AstIf(itemp->fileline(), ifexprp->cloneTree(true), NULL, NULL);
|
||||
if (groupnextp) groupnextp->addElsesp(newp);
|
||||
else grouprootp = newp;
|
||||
groupnextp = newp;
|
||||
} else { // Continue group, modify if condition to OR in this new condition
|
||||
AstNode* condp = groupnextp->condp()->unlinkFrBack();
|
||||
groupnextp->condp(new AstOr(ifexprp->fileline(),
|
||||
condp,
|
||||
ifexprp->cloneTree(true)));
|
||||
}
|
||||
}
|
||||
{ // Make the new lower IF and attach in the tree
|
||||
AstNode* itemexprp = ifexprp; ifexprp=NULL;
|
||||
if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition
|
||||
itemexprp->deleteTree(); itemexprp=NULL;
|
||||
itemexprp = new AstConst(itemp->fileline(), V3Number(itemp->fileline(),1,1));
|
||||
}
|
||||
AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, NULL);
|
||||
if (itemnextp) itemnextp->addElsesp(newp);
|
||||
else groupnextp->addIfsp(newp); // First in a new group
|
||||
itemnextp = newp;
|
||||
}
|
||||
}
|
||||
if (debug()>=9) nodep->dumpTree(cout," _comp_TREE: ");
|
||||
// Handle any assertions
|
||||
replaceCaseParallel(nodep, false);
|
||||
// Replace the CASE... with IF...
|
||||
if (ifrootp) nodep->replaceWith(ifrootp);
|
||||
if (debug()>=9) grouprootp->dumpTree(cout," _new: ");
|
||||
if (grouprootp) nodep->replaceWith(grouprootp);
|
||||
else nodep->unlinkFrBack();
|
||||
if (debug()>=9) ifrootp->dumpTree(cout," _new: ");
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
}
|
||||
|
||||
void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) {
|
||||
|
||||
@@ -249,6 +249,39 @@ public:
|
||||
nodep->modep()->iterateAndNext(*this);
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||
puts("VL_READMEM_");
|
||||
emitIQW(nodep->filenamep());
|
||||
puts(" ("); // We take a void* rather then emitIQW(nodep->memp());
|
||||
puts(nodep->isHex()?"true":"false");
|
||||
putbs(",");
|
||||
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
|
||||
putbs(",");
|
||||
uint32_t array_lsb = 0;
|
||||
{
|
||||
AstVarRef* varrefp = nodep->memp()->castVarRef();
|
||||
if (!varrefp || !varrefp->varp()->arrayp(0)) { nodep->v3error("Readmem loading non-arrayed variable"); }
|
||||
else {
|
||||
puts(cvtToStr(varrefp->varp()->arrayElements()));
|
||||
array_lsb = varrefp->varp()->arrayp(0)->lsbConst();
|
||||
}
|
||||
}
|
||||
putbs(", ");
|
||||
puts(cvtToStr(array_lsb));
|
||||
putbs(",");
|
||||
puts(cvtToStr(nodep->filenamep()->widthWords()));
|
||||
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
|
||||
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
|
||||
}
|
||||
putbs(", ");
|
||||
nodep->filenamep()->iterateAndNext(*this);
|
||||
putbs(", ");
|
||||
nodep->memp()->iterateAndNext(*this);
|
||||
putbs(","); if (nodep->lsbp()) { nodep->lsbp()->iterateAndNext(*this); }
|
||||
else puts(cvtToStr(array_lsb));
|
||||
putbs(","); if (nodep->msbp()) { nodep->msbp()->iterateAndNext(*this); } else puts("~0");
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFClose* nodep, AstNUser*) {
|
||||
puts("if (");
|
||||
nodep->filep()->iterateAndNext(*this);
|
||||
|
||||
@@ -193,6 +193,16 @@ public:
|
||||
if (nodep->filep()) nodep->filep()->iterateChildren(*this);
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||
putbs(nodep->verilogKwd());
|
||||
putbs(" (");
|
||||
if (nodep->filenamep()) nodep->filenamep()->iterateChildren(*this);
|
||||
putbs(",");
|
||||
if (nodep->memp()) nodep->memp()->iterateChildren(*this);
|
||||
if (nodep->lsbp()) { putbs(","); nodep->lsbp()->iterateChildren(*this); }
|
||||
if (nodep->msbp()) { putbs(","); nodep->msbp()->iterateChildren(*this); }
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstNodeFor* nodep, AstNUser*) {
|
||||
puts("for (");
|
||||
m_suppressSemi = true;
|
||||
|
||||
@@ -554,6 +554,12 @@ private:
|
||||
virtual void visit(AstFClose* nodep, AstNUser*) {
|
||||
nodep->filep()->iterateAndNext(*this,WidthVP(64,64,BOTH).p());
|
||||
}
|
||||
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||
nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->msbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
}
|
||||
virtual void visit(AstUCStmt* nodep, AstNUser*) {
|
||||
// TOP LEVEL NODE
|
||||
// Just let all arguments seek their natural sizes
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
//**********************************************************************
|
||||
//**** Version and host name
|
||||
|
||||
#define DTVERSION "Verilator 3.623 12/05/2006"
|
||||
#define DTVERSION "Verilator 3.630 12/19/2006"
|
||||
|
||||
//**********************************************************************
|
||||
//**** Functions
|
||||
|
||||
@@ -174,6 +174,8 @@ escid \\[^ \t\f\r\n]+
|
||||
<VLG,PSL>"$onehot0" {yylval.fileline = CRELINE(); return yD_ONEHOT0;}
|
||||
<VLG,PSL>"$period" {yylval.fileline = CRELINE(); return yTIMINGSPEC;}
|
||||
<VLG,PSL>"$realtime" {yylval.fileline = CRELINE(); return yD_TIME;}
|
||||
<VLG,PSL>"$readmemb" {yylval.fileline = CRELINE(); return yD_READMEMB;}
|
||||
<VLG,PSL>"$readmemh" {yylval.fileline = CRELINE(); return yD_READMEMH;}
|
||||
<VLG,PSL>"$recovery" {yylval.fileline = CRELINE(); return yTIMINGSPEC;}
|
||||
<VLG,PSL>"$recrem" {yylval.fileline = CRELINE(); return yTIMINGSPEC;}
|
||||
<VLG,PSL>"$removal" {yylval.fileline = CRELINE(); return yTIMINGSPEC;}
|
||||
|
||||
+38
-30
@@ -136,31 +136,33 @@ class AstSenTree;
|
||||
%token<fileline> yBUF yNOT yAND yNAND yNOR yXOR yXNOR
|
||||
%token<fileline> ySCALARED yVECTORED
|
||||
|
||||
%token<fileline> yASSERT "assert"
|
||||
%token<fileline> yCLOCK "clock"
|
||||
%token<fileline> yCOVER "cover"
|
||||
%token<fileline> yFINAL "final"
|
||||
%token<fileline> yPSL "psl"
|
||||
%token<fileline> yREPORT "report"
|
||||
%token<fileline> yTRUE "true"
|
||||
%token<fileline> yASSERT "assert"
|
||||
%token<fileline> yCLOCK "clock"
|
||||
%token<fileline> yCOVER "cover"
|
||||
%token<fileline> yFINAL "final"
|
||||
%token<fileline> yPSL "psl"
|
||||
%token<fileline> yREPORT "report"
|
||||
%token<fileline> yTRUE "true"
|
||||
|
||||
%token<fileline> yD_BITS "$bits"
|
||||
%token<fileline> yD_C "$c"
|
||||
%token<fileline> yD_COUNTONES "$countones"
|
||||
%token<fileline> yD_DISPLAY "$display"
|
||||
%token<fileline> yD_FCLOSE "$fclose"
|
||||
%token<fileline> yD_FDISPLAY "$fdisplay"
|
||||
%token<fileline> yD_FINISH "$finish"
|
||||
%token<fileline> yD_FOPEN "$fopen"
|
||||
%token<fileline> yD_FWRITE "$fwrite"
|
||||
%token<fileline> yD_ISUNKNOWN "$isunknown"
|
||||
%token<fileline> yD_ONEHOT "$onehot"
|
||||
%token<fileline> yD_ONEHOT0 "$onehot0"
|
||||
%token<fileline> yD_SIGNED "$signed"
|
||||
%token<fileline> yD_STOP "$stop"
|
||||
%token<fileline> yD_TIME "$time"
|
||||
%token<fileline> yD_UNSIGNED "$unsigned"
|
||||
%token<fileline> yD_WRITE "$write"
|
||||
%token<fileline> yD_BITS "$bits"
|
||||
%token<fileline> yD_C "$c"
|
||||
%token<fileline> yD_COUNTONES "$countones"
|
||||
%token<fileline> yD_DISPLAY "$display"
|
||||
%token<fileline> yD_FCLOSE "$fclose"
|
||||
%token<fileline> yD_FDISPLAY "$fdisplay"
|
||||
%token<fileline> yD_FINISH "$finish"
|
||||
%token<fileline> yD_FOPEN "$fopen"
|
||||
%token<fileline> yD_FWRITE "$fwrite"
|
||||
%token<fileline> yD_ISUNKNOWN "$isunknown"
|
||||
%token<fileline> yD_ONEHOT "$onehot"
|
||||
%token<fileline> yD_ONEHOT0 "$onehot0"
|
||||
%token<fileline> yD_READMEMB "$readmemb"
|
||||
%token<fileline> yD_READMEMH "$readmemh"
|
||||
%token<fileline> yD_SIGNED "$signed"
|
||||
%token<fileline> yD_STOP "$stop"
|
||||
%token<fileline> yD_TIME "$time"
|
||||
%token<fileline> yD_UNSIGNED "$unsigned"
|
||||
%token<fileline> yD_WRITE "$write"
|
||||
|
||||
%token<fileline> yVL_CLOCK "/*verilator sc_clock*/"
|
||||
%token<fileline> yVL_CLOCK_ENABLE "/*verilator clock_enable*/"
|
||||
@@ -670,15 +672,21 @@ stmt: ';' { $$ = NULL; }
|
||||
| stateCaseForIf { $$ = $1; }
|
||||
| taskRef ';' { $$ = $1; }
|
||||
|
||||
| yD_DISPLAY ';' { $$ = new AstDisplay($1,'\n',"",NULL,NULL); }
|
||||
| yD_DISPLAY '(' ySTRING ')' ';' { $$ = new AstDisplay($1,'\n',*$3,NULL,NULL); }
|
||||
| yD_DISPLAY '(' ySTRING ',' eList ')' ';' { $$ = new AstDisplay($1,'\n',*$3,NULL,$5); }
|
||||
| yD_WRITE '(' ySTRING ')' ';' { $$ = new AstDisplay($1,'\0',*$3,NULL,NULL); }
|
||||
| yD_DISPLAY ';' { $$ = new AstDisplay($1,'\n',"",NULL,NULL); }
|
||||
| yD_DISPLAY '(' ySTRING ')' ';' { $$ = new AstDisplay($1,'\n',*$3,NULL,NULL); }
|
||||
| yD_DISPLAY '(' ySTRING ',' eList ')' ';' { $$ = new AstDisplay($1,'\n',*$3,NULL,$5); }
|
||||
| yD_WRITE '(' ySTRING ')' ';' { $$ = new AstDisplay($1,'\0',*$3,NULL,NULL); }
|
||||
| yD_WRITE '(' ySTRING ',' eList ')' ';' { $$ = new AstDisplay($1,'\0',*$3,NULL,$5); }
|
||||
| yD_FDISPLAY '(' idVarXRef ',' ySTRING ')' ';' { $$ = new AstDisplay($1,'\n',*$5,$3,NULL); }
|
||||
| yD_FDISPLAY '(' idVarXRef ',' ySTRING ',' eList ')' ';' { $$ = new AstDisplay($1,'\n',*$5,$3,$7); }
|
||||
| yD_FDISPLAY '(' idVarXRef ',' ySTRING ',' eList ')' ';' { $$ = new AstDisplay($1,'\n',*$5,$3,$7); }
|
||||
| yD_FWRITE '(' idVarXRef ',' ySTRING ')' ';' { $$ = new AstDisplay($1,'\0',*$5,$3,NULL); }
|
||||
| yD_FWRITE '(' idVarXRef ',' ySTRING ',' eList ')' ';' { $$ = new AstDisplay($1,'\0',*$5,$3,$7); }
|
||||
| yD_FWRITE '(' idVarXRef ',' ySTRING ',' eList ')' ';' { $$ = new AstDisplay($1,'\0',*$5,$3,$7); }
|
||||
| yD_READMEMB '(' expr ',' lhIdArrayed ')' ';' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); }
|
||||
| yD_READMEMB '(' expr ',' lhIdArrayed ',' expr ')' ';' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); }
|
||||
| yD_READMEMB '(' expr ',' lhIdArrayed ',' expr ',' expr ')' ';' { $$ = new AstReadMem($1,false,$3,$5,$7,$9); }
|
||||
| yD_READMEMH '(' expr ',' lhIdArrayed ')' ';' { $$ = new AstReadMem($1,true, $3,$5,NULL,NULL); }
|
||||
| yD_READMEMH '(' expr ',' lhIdArrayed ',' expr ')' ';' { $$ = new AstReadMem($1,true, $3,$5,$7,NULL); }
|
||||
| yD_READMEMH '(' expr ',' lhIdArrayed ',' expr ',' expr ')' ';' { $$ = new AstReadMem($1,true, $3,$5,$7,$9); }
|
||||
;
|
||||
|
||||
stateCaseForIf: caseStmt caseAttrE caseList yENDCASE { $$ = $1; $1->addItemsp($3); }
|
||||
|
||||
+7
-4
@@ -12,20 +12,23 @@
|
||||
#
|
||||
#****************************************************************************/
|
||||
|
||||
default: test_default
|
||||
|
||||
# This must point to the root of the VERILATOR kit
|
||||
VERILATOR_ROOT := $(shell pwd)/..
|
||||
export VERILATOR_ROOT
|
||||
|
||||
PERL = perl
|
||||
# Pick up PERL and other variable settings
|
||||
include $(VERILATOR_ROOT)/include/verilated.mk
|
||||
|
||||
DEBUG_ON = --debug --trace-dups
|
||||
#DEBUG = $(DEBUG_ON)
|
||||
VALGRIND_ON = $(DEBUG_ON) --gdb "valgrind -v --leak-check=yes"
|
||||
|
||||
######################################################################
|
||||
default: prep compile run
|
||||
debug: prep_dbg compile run
|
||||
valgrind: prep_vg compile run
|
||||
test_default: prep compile run
|
||||
test_debug: prep_dbg compile run
|
||||
test_valgrind: prep_vg compile run
|
||||
|
||||
VERILATOR_FLAGS = --cc -f $(VERILATOR_ROOT)/test_v/input.vc top.v
|
||||
#Note turning on traces requires SystemPerl to be installed
|
||||
|
||||
@@ -12,15 +12,17 @@
|
||||
#
|
||||
#****************************************************************************/
|
||||
|
||||
default: test
|
||||
|
||||
# This must point to the root of the VERILATOR kit
|
||||
VERILATOR_ROOT := $(shell pwd)/..
|
||||
export VERILATOR_ROOT
|
||||
PERL = perl
|
||||
|
||||
# Pick up PERL and other variable settings
|
||||
include $(VERILATOR_ROOT)/include/verilated.mk
|
||||
|
||||
######################################################################
|
||||
|
||||
default: test
|
||||
|
||||
ifneq ($(VCS_HOME),)
|
||||
PRODUCTS += --vcs
|
||||
endif
|
||||
|
||||
@@ -57,6 +57,7 @@ my $opt_stop;
|
||||
my $opt_optimize;
|
||||
my $opt_gdb;
|
||||
my $opt_jobs = 1;
|
||||
my $opt_verbose;
|
||||
my $Opt_Verilated_Debug;
|
||||
if (! GetOptions (
|
||||
"help" => \&usage,
|
||||
@@ -69,6 +70,7 @@ if (! GetOptions (
|
||||
"gdb!" => \$opt_gdb,
|
||||
"stop!" => \$opt_stop,
|
||||
"optimize:s" => \$opt_optimize,
|
||||
"verbose!" => \$opt_verbose,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
usage();
|
||||
@@ -187,7 +189,9 @@ sub new {
|
||||
make_top_shell => 1, # Make a default __top.v file
|
||||
make_main => 1, # Make __main.cpp
|
||||
# All compilers
|
||||
v_flags => [split(/\s+/," -f input.vc --debug-check")],
|
||||
v_flags => [split(/\s+/,(" -f input.vc --debug-check"
|
||||
.($opt_verbose ? " +define+TEST_VERBOSE+1":"")
|
||||
))],
|
||||
v_flags2 => [], # Overridden in some sim files
|
||||
v_other_filenames => [], # After the filename so we can spec multiple files
|
||||
# VCS
|
||||
@@ -827,6 +831,10 @@ Stop on the first error
|
||||
|
||||
Run using VCS.
|
||||
|
||||
=item --verbose
|
||||
|
||||
Enable test verbose messages.
|
||||
|
||||
=item --v3
|
||||
|
||||
Run using Verilator.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id:$
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
@@ -83,7 +83,9 @@ module t (/*AUTOARG*/
|
||||
|
||||
always @ (posedge fastclk) begin
|
||||
cyc <= cyc+1;
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("%d %x %x %x %x %x %x\n",cyc,data_a,data_a_a,data_b_a,data_b,data_a_b,data_b_b);
|
||||
`endif
|
||||
if (cyc>=19 && cyc<36) begin
|
||||
if (compare !== check[cyc]) begin
|
||||
$write("[%0t] Mismatch, got=%x, exp=%x\n", $time, compare, check[cyc]);
|
||||
|
||||
@@ -85,7 +85,7 @@ module example (/*AUTOARG*/
|
||||
input [5:0] LowMaskSel_Bot, HighMaskSel_Bot;
|
||||
output [63:0] LogicImm;
|
||||
|
||||
output [63:0] LowLogicImm, HighLogicImm; //FIX
|
||||
output [63:0] LowLogicImm, HighLogicImm;
|
||||
|
||||
|
||||
wire [63:0] LowLogicImm, HighLogicImm;
|
||||
|
||||
Executable → Regular
+3
-3
@@ -7,16 +7,16 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
unlink("obj_dir/t_sys_file_test.log");
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
unlink("obj_dir/t_file_test.log");
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
file_grep ("obj_dir/t_file_test.log",
|
||||
file_grep ("obj_dir/t_sys_file_test.log",
|
||||
qr/\[0\] hello v=12345667
|
||||
\[0\] Hello2
|
||||
/);
|
||||
@@ -16,7 +16,7 @@ module t;
|
||||
$fwrite(file, "Never printed, file closed\n");
|
||||
`endif
|
||||
|
||||
file = $fopen("obj_dir/t_file_test.log","w"); // The "w" is required so we get a FD not a MFD
|
||||
file = $fopen("obj_dir/t_sys_file_test.log","w"); // The "w" is required so we get a FD not a MFD
|
||||
|
||||
$fdisplay(file, "[%0t] hello v=%x", $time, 32'h12345667);
|
||||
$fwrite(file, "[%0t] %s\n", $time, "Hello2");
|
||||
@@ -27,6 +27,11 @@ module t;
|
||||
$fwrite(file, "Never printed, file closed\n");
|
||||
`endif
|
||||
|
||||
begin
|
||||
file = $fopen("obj_dir/DOES_NOT_EXIST","r"); // The "r" is required so we get a FD not a MFD
|
||||
if (|file) $stop; // Should not exist, IE must return 0
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,62 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
|
||||
reg [5:0] binary_nostart [2:15];
|
||||
reg [5:0] binary_start [0:15];
|
||||
reg [175:0] hex [0:15];
|
||||
|
||||
integer i;
|
||||
|
||||
initial begin
|
||||
|
||||
begin
|
||||
$readmemb("t/t_sys_readmem_b.mem", binary_nostart);
|
||||
`ifdef TEST_VERBOSE
|
||||
for (i=0; i<16; i=i+1) $write(" @%x = %x\n", i, binary_nostart[i]);
|
||||
`endif
|
||||
if (binary_nostart['h2] != 6'h02) $stop;
|
||||
if (binary_nostart['h3] != 6'h03) $stop;
|
||||
if (binary_nostart['h4] != 6'h04) $stop;
|
||||
if (binary_nostart['h5] != 6'h05) $stop;
|
||||
if (binary_nostart['h6] != 6'h06) $stop;
|
||||
if (binary_nostart['h7] != 6'h07) $stop;
|
||||
if (binary_nostart['h8] != 6'h10) $stop;
|
||||
if (binary_nostart['hc] != 6'h14) $stop;
|
||||
if (binary_nostart['hd] != 6'h15) $stop;
|
||||
end
|
||||
|
||||
begin
|
||||
$readmemb("t/t_sys_readmem_b_8.mem", binary_start, 4, 4+7);
|
||||
`ifdef TEST_VERBOSE
|
||||
for (i=0; i<16; i=i+1) $write(" @%x = %x\n", i, binary_start[i]);
|
||||
`endif
|
||||
if (binary_start['h04] != 6'h10) $stop;
|
||||
if (binary_start['h05] != 6'h11) $stop;
|
||||
if (binary_start['h06] != 6'h12) $stop;
|
||||
if (binary_start['h07] != 6'h13) $stop;
|
||||
if (binary_start['h08] != 6'h14) $stop;
|
||||
if (binary_start['h09] != 6'h15) $stop;
|
||||
if (binary_start['h0a] != 6'h16) $stop;
|
||||
if (binary_start['h0b] != 6'h17) $stop;
|
||||
end
|
||||
|
||||
begin
|
||||
$readmemh("t/t_sys_readmem_h.mem", hex, 0);
|
||||
`ifdef TEST_VERBOSE
|
||||
for (i=0; i<16; i=i+1) $write(" @%x = %x\n", i, hex[i]);
|
||||
`endif
|
||||
if (hex['h04] != 176'h400437654321276543211765432107654321abcdef10) $stop;
|
||||
if (hex['h0a] != 176'h400a37654321276543211765432107654321abcdef11) $stop;
|
||||
if (hex['h0b] != 176'h400b37654321276543211765432107654321abcdef12) $stop;
|
||||
if (hex['h0c] != 176'h400c37654321276543211765432107654321abcdef13) $stop;
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,18 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test data file
|
||||
//
|
||||
// Copyright 2006 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
|
||||
010
|
||||
0_1_1
|
||||
100/*Space*/101// Space
|
||||
110 111
|
||||
|
||||
@00_0_8
|
||||
10000
|
||||
|
||||
@c
|
||||
10100
|
||||
10101
|
||||
@@ -0,0 +1,19 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test data file
|
||||
//
|
||||
// Copyright 2006 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
|
||||
10000
|
||||
10001
|
||||
10010
|
||||
10011
|
||||
/*
|
||||
multi line
|
||||
ignored
|
||||
*/
|
||||
10100
|
||||
10101
|
||||
10110
|
||||
10111
|
||||
@@ -0,0 +1,9 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test data file
|
||||
//
|
||||
// Copyright 2006 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
|
||||
@121212
|
||||
10
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
fails=>$Last_Self->{v3},
|
||||
expect=>
|
||||
'%Error: t/t_sys_readmem_bad_addr.mem:\d+: \$readmem file address beyond bounds of array',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,15 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
reg [175:0] hex [0:15];
|
||||
|
||||
initial begin
|
||||
$readmemh("t/t_sys_readmem_bad_addr.mem", hex);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,9 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test data file
|
||||
//
|
||||
// Copyright 2006 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
|
||||
a0
|
||||
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
fails=>$Last_Self->{v3},
|
||||
expect=>
|
||||
'%Error: t/t_sys_readmem_bad_digit.mem:\d+: \$readmemb \(binary\) file contains hex characters',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,16 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
|
||||
reg [175:0] hex [0:15];
|
||||
|
||||
initial begin
|
||||
$readmemb("t/t_sys_readmem_bad_digit.mem", hex);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,11 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test data file
|
||||
//
|
||||
// Copyright 2006 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
|
||||
00
|
||||
01
|
||||
10
|
||||
// Missing additional data
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
fails=>$Last_Self->{v3},
|
||||
expect=>
|
||||
'%Error: t/t_sys_readmem_bad_end.mem:\d+: \$readmem file ended before specified ending-address',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,18 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
|
||||
reg [175:0] hex [0:15];
|
||||
|
||||
integer i;
|
||||
|
||||
initial begin
|
||||
$readmemh("t/t_sys_readmem_bad_end.mem", hex, 0, 15);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
fails=>$Last_Self->{v3},
|
||||
expect=>
|
||||
'%Error: t/t_sys_readmem_bad_NOTFOUND.mem:\d+: \$readmem file not found',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,16 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
|
||||
reg [175:0] hex [0:15];
|
||||
|
||||
initial begin
|
||||
$readmemh("t/t_sys_readmem_bad_NOTFOUND.mem", hex);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,13 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test data file
|
||||
//
|
||||
// Copyright 2006 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
|
||||
@4
|
||||
4004_37654321_27654321_17654321_07654321_abcdef10
|
||||
@a
|
||||
400a_37654321_27654321_17654321_07654321_abcdef11
|
||||
400b_37654321_27654321_17654321_07654321_abcdef12
|
||||
400c_37654321_27654321_17654321_07654321_abcdef13
|
||||
+7
-4
@@ -12,18 +12,21 @@
|
||||
#
|
||||
#****************************************************************************/
|
||||
|
||||
default: test_default
|
||||
|
||||
# This must point to the root of the VERILATOR kit
|
||||
VERILATOR_ROOT := $(shell pwd)/..
|
||||
export VERILATOR_ROOT
|
||||
|
||||
PERL = perl
|
||||
# Pick up PERL and other variable settings
|
||||
include $(VERILATOR_ROOT)/include/verilated.mk
|
||||
|
||||
DEBUG_ON = --debug
|
||||
|
||||
######################################################################
|
||||
default: precopy prep preproc compile run
|
||||
debug: precopy prep_dbg preproc compile run
|
||||
nopublic: precopy prep_dbg_np preproc compile run
|
||||
test_default: precopy prep preproc compile run
|
||||
test_debug: precopy prep_dbg preproc compile run
|
||||
test_nopublic: precopy prep_dbg_np preproc compile run
|
||||
|
||||
V_FLAGS = -f $(VERILATOR_ROOT)/test_v/input.vc
|
||||
VERILATOR_FLAGS = --sc $(V_FLAGS) top.v
|
||||
|
||||
+7
-4
@@ -12,18 +12,21 @@
|
||||
#
|
||||
#****************************************************************************/
|
||||
|
||||
default: test_default
|
||||
|
||||
# This must point to the root of the VERILATOR kit
|
||||
VERILATOR_ROOT := $(shell pwd)/..
|
||||
export VERILATOR_ROOT
|
||||
|
||||
PERL = perl
|
||||
# Pick up PERL and other variable settings
|
||||
include $(VERILATOR_ROOT)/include/verilated.mk
|
||||
|
||||
DEBUG_ON = --debug --trace-dups --output-split 100
|
||||
|
||||
######################################################################
|
||||
default: prep preproc compile run coverage
|
||||
debug: prep_dbg preproc compile_dbg run coverage
|
||||
nopublic: prep_dbg_np preproc compile_dbg run coverage
|
||||
test_default: prep preproc compile run coverage
|
||||
test_debug: prep_dbg preproc compile_dbg run coverage
|
||||
test_nopublic: prep_dbg_np preproc compile_dbg run coverage
|
||||
|
||||
V_FLAGS = -f $(VERILATOR_ROOT)/test_v/input.vc
|
||||
VERILATOR_FLAGS = --public --sp --coverage --stats --trace $(V_FLAGS) top.v
|
||||
|
||||
+5
-1
@@ -12,16 +12,20 @@
|
||||
#
|
||||
#****************************************************************************/
|
||||
|
||||
default: test
|
||||
|
||||
# This must point to the root of the VERILATOR kit
|
||||
VERILATOR_ROOT := $(shell pwd)/..
|
||||
export VERILATOR_ROOT
|
||||
|
||||
# Pick up PERL and other variable settings
|
||||
include $(VERILATOR_ROOT)/include/verilated.mk
|
||||
|
||||
######################################################################
|
||||
|
||||
V_FILES := $(wildcard *.v ../test_v/*.v)
|
||||
|
||||
######################################################################
|
||||
default: test
|
||||
|
||||
ifneq ($(VCS_HOME),)
|
||||
test:: vcs
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
#
|
||||
#****************************************************************************/
|
||||
|
||||
default: test
|
||||
|
||||
# This must point to the root of the VERILATOR kit
|
||||
VERILATOR_ROOT := $(shell pwd)/..
|
||||
export VERILATOR_ROOT
|
||||
PERL = perl
|
||||
|
||||
# Pick up PERL and other variable settings
|
||||
include $(VERILATOR_ROOT)/include/verilated.mk
|
||||
|
||||
VERILATOR_SW +=
|
||||
ifeq ($(VERILATOR_NO_DEBUG),)
|
||||
|
||||
Reference in New Issue
Block a user