Add support.

git-svn-id: file://localhost/svn/verilator/trunk/verilator@846 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
Wilson Snyder 2006-12-19 14:09:57 +00:00
parent a599fbea18
commit 699563c9bd
30 changed files with 603 additions and 49 deletions

View File

@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.62***
** 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.

View File

@ -996,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.
@ -1316,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

View File

@ -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

View File

@ -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?)

View File

@ -1251,6 +1251,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)

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;}

View File

@ -156,6 +156,8 @@ class AstSenTree;
%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"
@ -679,6 +681,12 @@ stmt: ';' { $$ = NULL; }
| 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_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); }

View File

@ -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,
"<>" => \&parameter,
)) {
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.

View File

@ -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]);

View File

@ -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
/);

View File

@ -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

18
test_regress/t/t_sys_readmem.pl Executable file
View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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