Support SV strings to readmemh, bug1040.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Stefan Wallentowitz 2016-03-01 18:57:15 -05:00 committed by Wilson Snyder
parent 90ecf14a0a
commit c5332de86d
4 changed files with 93 additions and 73 deletions

View File

@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Support inlining interfaces, bug1018. [Johan Bjork]
**** Support SV strings to readmemh, bug1040. [Stefan Wallentowitz]
**** Fix unrolling complicated for-loop bounds, bug677. [Johan Bjork]
**** Fix stats file containing multiple unroll entries, bug1020. [Johan Bjork]

View File

@ -956,10 +956,16 @@ 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");
string ofilenames(ofilenamez);
return VL_READMEM_N(hex,width,depth,array_lsb,fnwords,ofilenames,memp,start,end);
}
void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
const string& ofilenamep, void* memp, IData start, IData end) {
FILE* fp = fopen(ofilenamep.c_str(), "r");
if (VL_UNLIKELY(!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");
vl_fatal (ofilenamep.c_str(), 0, "", "$readmem file not found");
return;
}
// Prep for reading
@ -1004,7 +1010,7 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
needinc = true;
//printf(" Value width=%d @%x = %c\n", width, addr, c);
if (VL_UNLIKELY(addr >= (IData)(depth+array_lsb) || addr < (IData)(array_lsb))) {
vl_fatal (ofilenamez, linenum, "", "$readmem file address beyond bounds of array");
vl_fatal (ofilenamep.c_str(), linenum, "", "$readmem file address beyond bounds of array");
} else {
int entry = addr - array_lsb;
QData shift = hex ? VL_ULL(4) : VL_ULL(1);
@ -1032,14 +1038,14 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
datap[0] |= value;
}
if (VL_UNLIKELY(value>=(1<<shift))) {
vl_fatal (ofilenamez, linenum, "", "$readmemb (binary) file contains hex characters");
vl_fatal (ofilenamep.c_str(), linenum, "", "$readmemb (binary) file contains hex characters");
}
}
}
innum = true;
}
else {
vl_fatal (ofilenamez, linenum, "", "$readmem file syntax error");
vl_fatal (ofilenamep.c_str(), linenum, "", "$readmem file syntax error");
}
}
lastc = c;
@ -1049,7 +1055,7 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
// Final checks
fclose(fp);
if (VL_UNLIKELY(end != VL_UL(0xffffffff) && addr != (end+1))) {
vl_fatal (ofilenamez, linenum, "", "$readmem file ended before specified ending-address");
vl_fatal (ofilenamep.c_str(), linenum, "", "$readmem file ended before specified ending-address");
}
}

View File

@ -61,6 +61,8 @@ inline string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const string& lhs
}
extern IData VL_FOPEN_NI(const string& filename, IData mode);
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
const string& ofilename, void* memp, IData start, IData end);
extern IData VL_SSCANF_INX(int lbits, const string& ld, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
extern string VL_SFORMATF_NX(const char* formatp, ...);

View File

@ -6,6 +6,7 @@
module t;
// verilator lint_off LITENDIAN
reg [5:0] binary_string [2:15];
reg [5:0] binary_nostart [2:15];
reg [5:0] binary_start [0:15];
reg [175:0] hex [0:15];
@ -57,6 +58,15 @@ module t;
if (hex['h0c] != 176'h400c37654321276543211765432107654321abcdef13) $stop;
end
begin
string fns = "t/t_sys_readmem_b.mem";
$readmemb(fns, binary_string);
`ifdef TEST_VERBOSE
for (i=0; i<16; i=i+1) $write(" @%x = %x\n", i, binary_string[i]);
`endif
if (binary_string['h2] != 6'h02) $stop;
end
$write("*-* All Finished *-*\n");
$finish;
end