Fix --savable invalid C++ on packed arrays, bug1465.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Alex Chadwick 2019-06-14 18:42:27 -04:00 committed by Wilson Snyder
parent ea59a39661
commit 5da5e32e86
4 changed files with 40 additions and 21 deletions

View File

@ -34,6 +34,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
**** Fix not reporting some duplicate signals, bug1462. [Peter Gerst]
**** Fix --savable invalid C++ on packed arrays, bug1465. [Alex Chadwick]
* Verilator 4.014 2019-05-08

View File

@ -5,6 +5,7 @@ under the Developer Certificate of Origin
Please see the Verilator manual for additional contributors.
Jeremy Bennett
Alex Chadwick
John Coiner
Kanad Kanhere
Richard Myers

View File

@ -1955,11 +1955,10 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
else if (varp->isStatic() && varp->isConst()) {}
else {
int vects = 0;
// This isn't very robust and may need cleanup for other data types
for (AstUnpackArrayDType* arrayp
= VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType);
AstNodeDType* elementp = varp->dtypeSkipRefp();
for (AstUnpackArrayDType* arrayp = VN_CAST(elementp, UnpackArrayDType);
arrayp;
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
arrayp = VN_CAST(elementp, UnpackArrayDType)) {
int vecnum = vects++;
if (arrayp->msb() < arrayp->lsb()) {
varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
@ -1970,19 +1969,22 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";");
puts(" for (; "+ivar+"<"+cvtToStr(arrayp->elementsConst()));
puts("; ++"+ivar+") {\n");
elementp = arrayp->subDTypep()->skipRefp();
}
if (varp->basicp() && (varp->basicp()->keyword() == AstBasicDTypeKwd::STRING
|| !varp->basicp()->isWide())) {
puts("os"+op+varp->name());
for (int v=0; v<vects; ++v) puts( "[__Vi"+cvtToStr(v)+"]");
puts(";\n");
} else {
puts("os."+writeread+"(&"+varp->name());
for (int v=0; v<vects; ++v) puts( "[__Vi"+cvtToStr(v)+"]");
puts(",sizeof("+varp->name());
for (int v=0; v<vects; ++v) puts( "[__Vi"+cvtToStr(v)+"]");
puts("));\n");
// Want to detect types that are represented as arrays
// (i.e. packed types of more than 64 bits).
AstBasicDType* basicp = elementp->basicp();
if (elementp->isWide()
&& !(basicp && basicp->keyword() == AstBasicDTypeKwd::STRING)) {
int vecnum = vects++;
string ivar = string("__Vi")+cvtToStr(vecnum);
puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";");
puts(" for (; "+ivar+"<"+cvtToStr(elementp->widthWords()));
puts("; ++"+ivar+") {\n");
}
puts("os"+op+varp->name());
for (int v=0; v<vects; ++v) puts( "[__Vi"+cvtToStr(v)+"]");
puts(";\n");
for (int v=0; v<vects; ++v) puts( "}}\n");
}
}

View File

@ -30,8 +30,10 @@ module sub (/*AUTOARG*/
reg [1:0] save2;
reg [255:0] cycdone; // Make sure each cycle executes exactly once
reg [31:0] vec[2:1][2:1];
real r;
string s,s2;
reg [2:1][2:1][31:0] pvec;
real r;
string s,s2;
string sarr[2:1];
string si;
@ -53,8 +55,14 @@ module sub (/*AUTOARG*/
vec[1][2] <= 32'h0102;
vec[2][1] <= 32'h0201;
vec[2][2] <= 32'h0202;
r <= 1.234;
s <= "hello";
pvec[1][1] <= 32'h10101;
pvec[1][2] <= 32'h10102;
pvec[2][1] <= 32'h10201;
pvec[2][2] <= 32'h10202;
r <= 1.234;
s <= "hello";
sarr[1] <= "sarr[1]";
sarr[2] <= "sarr[2]";
end
if (cyc==1) begin
if ($test$plusargs("save_restore")!=0) begin
@ -72,8 +80,14 @@ module sub (/*AUTOARG*/
if (vec[1][2] !== 32'h0102) $stop;
if (vec[2][1] !== 32'h0201) $stop;
if (vec[2][2] !== 32'h0202) $stop;
if (r != 1.234) $stop;
$display("%s",s);
if (pvec[1][1] !== 32'h10101) $stop;
if (pvec[1][2] !== 32'h10102) $stop;
if (pvec[2][1] !== 32'h10201) $stop;
if (pvec[2][2] !== 32'h10202) $stop;
if (r != 1.234) $stop;
$display("%s",s);
$display("%s",sarr[1]);
$display("%s",sarr[2]);
$write("*-* All Finished *-*\n");
$finish;
end