Support to packed array

This commit is contained in:
Wilson Snyder 2023-02-05 10:18:03 -05:00
parent 2d89c458f6
commit eb5aad94f1
9 changed files with 61 additions and 24 deletions

View File

@ -1411,6 +1411,12 @@ IData VL_FERROR_IN(IData, std::string& outputr) VL_MT_SAFE {
outputr = std::string{::std::strerror(ret)};
return ret;
}
IData VL_FERROR_IW(IData fpi, int obits, WDataOutP outwp) VL_MT_SAFE {
std::string output;
const IData ret = VL_FERROR_IN(fpi, output /*ref*/);
_vl_string_to_vint(obits, outwp, output.length(), output.c_str());
return ret;
}
IData VL_FOPEN_NN(const std::string& filename, const std::string& mode) {
return Verilated::threadContextp()->impp()->fdNew(filename.c_str(), mode.c_str());

View File

@ -2212,6 +2212,7 @@ extern std::string VL_TOLOWER_NN(const std::string& ld) VL_PURE;
extern std::string VL_TOUPPER_NN(const std::string& ld) VL_PURE;
extern IData VL_FERROR_IN(IData fpi, std::string& outputr) VL_MT_SAFE;
extern IData VL_FERROR_IW(IData fpi, int obits, WDataOutP outwp) VL_MT_SAFE;
extern IData VL_FOPEN_NN(const std::string& filename, const std::string& mode) VL_MT_SAFE;
extern IData VL_FOPEN_MCD_N(const std::string& filename) VL_MT_SAFE;
extern void VL_READMEM_N(bool hex, int bits, QData depth, int array_lsb,

View File

@ -4607,6 +4607,7 @@ public:
bool cleanLhs() const override { return true; }
bool sizeMattersLhs() const override { return false; }
int instrCount() const override { return widthInstrs() * 16; }
bool isPredictOptimizable() const override { return false; }
bool isPure() const override { return false; } // SPECIAL: $display has 'visual' ordering
AstNode* filep() const { return lhsp(); }
};
@ -4623,6 +4624,7 @@ public:
bool cleanLhs() const override { return true; }
bool sizeMattersLhs() const override { return false; }
int instrCount() const override { return widthInstrs() * 64; }
bool isPredictOptimizable() const override { return false; }
bool isPure() const override { return false; } // SPECIAL: $display has 'visual' ordering
AstNode* filep() const { return lhsp(); }
};

View File

@ -624,9 +624,14 @@ public:
puts(")");
}
void visit(AstFError* nodep) override {
puts("VL_FERROR_IN(");
puts("VL_FERROR_I");
puts(nodep->strp()->isString() ? "N(" : "W(");
iterateAndNextNull(nodep->filep());
putbs(", ");
if (nodep->strp()->isWide()) {
puts(cvtToStr(nodep->strp()->widthWords()));
putbs(", ");
}
iterateAndNextNull(nodep->strp());
puts(")");
}

View File

@ -4777,8 +4777,8 @@ private:
void visit(AstFError* nodep) override {
if (m_vup->prelim()) {
iterateCheckFileDesc(nodep, nodep->filep(), BOTH);
// We only support string types, not packed array
iterateCheckString(nodep, "$ferror string result", nodep->strp(), BOTH);
// Could be string or packed array
userIterateAndNext(nodep->strp(), WidthVP{SELF, BOTH}.p());
nodep->dtypeSetLogicUnsized(32, 1, VSigning::SIGNED); // Spec says integer return
}
}

View File

@ -4037,10 +4037,12 @@ system_t_call<nodeStmtp>: // IEEE: system_tf_call (as task)
| yD_FMONITORB '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, $3, $5, 'b'}; }
| yD_FMONITORH '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, $3, $5, 'h'}; }
| yD_FMONITORO '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_MONITOR, $3, $5, 'o'}; }
| yD_FSTROBE '(' expr ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, nullptr}; }
| yD_FSTROBE '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, $5}; }
| yD_FSTROBEB '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, $5, 'b'}; }
| yD_FSTROBEH '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, $5, 'h'}; }
| yD_FSTROBEO '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_STROBE, $3, $5, 'o'}; }
| yD_FWRITE '(' expr ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, nullptr}; }
| yD_FWRITE '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, $5}; }
| yD_FWRITEB '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, $5, 'b'}; }
| yD_FWRITEH '(' expr ',' exprDispList ')' { $$ = new AstDisplay{$1, VDisplayType::DT_WRITE, $3, $5, 'h'}; }
@ -4153,17 +4155,17 @@ system_f_call_or_t<nodeExprp>: // IEEE: part of system_tf_call (can be task
| yD_FELL '(' expr ',' expr ')' { $$ = new AstFell{$1, $3, GRAMMARP->createClockSenTree($1, $5)}; }
| yD_FELL_GCLK '(' expr ')' { $$ = new AstFell{$1, $3, GRAMMARP->createGlobalClockSenTree($1)}; }
| yD_FEOF '(' expr ')' { $$ = new AstFEof{$1, $3}; }
| yD_FERROR '(' idClassSel ',' idClassSel ')' { $$ = new AstFError{$1, $3, $5}; }
| yD_FERROR '(' expr ',' idClassSel ')' { $$ = new AstFError{$1, $3, $5}; }
| yD_FGETC '(' expr ')' { $$ = new AstFGetC{$1, $3}; }
| yD_FGETS '(' idClassSel ',' expr ')' { $$ = new AstFGetS{$1, $3, $5}; }
| yD_FREAD '(' idClassSel ',' expr ')' { $$ = new AstFRead{$1, $3, $5, nullptr, nullptr}; }
| yD_FREAD '(' idClassSel ',' expr ',' expr ')' { $$ = new AstFRead{$1, $3, $5, $7, nullptr}; }
| yD_FREAD '(' idClassSel ',' expr ',' expr ',' expr ')' { $$ = new AstFRead{$1, $3, $5, $7, $9}; }
| yD_FREWIND '(' idClassSel ')' { $$ = new AstFRewind{$1, $3}; }
| yD_FGETS '(' expr ',' expr ')' { $$ = new AstFGetS{$1, $3, $5}; }
| yD_FREAD '(' expr ',' expr ')' { $$ = new AstFRead{$1, $3, $5, nullptr, nullptr}; }
| yD_FREAD '(' expr ',' expr ',' expr ')' { $$ = new AstFRead{$1, $3, $5, $7, nullptr}; }
| yD_FREAD '(' expr ',' expr ',' expr ',' expr ')' { $$ = new AstFRead{$1, $3, $5, $7, $9}; }
| yD_FREWIND '(' expr ')' { $$ = new AstFRewind{$1, $3}; }
| yD_FLOOR '(' expr ')' { $$ = new AstFloorD{$1, $3}; }
| yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF{$1, *$5, $3, $6}; }
| yD_FSEEK '(' idClassSel ',' expr ',' expr ')' { $$ = new AstFSeek{$1, $3, $5, $7}; }
| yD_FTELL '(' idClassSel ')' { $$ = new AstFTell{$1, $3}; }
| yD_FSEEK '(' expr ',' expr ',' expr ')' { $$ = new AstFSeek{$1, $3, $5, $7}; }
| yD_FTELL '(' expr ')' { $$ = new AstFTell{$1, $3}; }
| yD_GLOBAL_CLOCK parenE { $$ = GRAMMARP->createGlobalClockParseRef($1); }
| yD_HIGH '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_HIGH, $3, nullptr}; }
| yD_HIGH '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_HIGH, $3, $5}; }
@ -4192,7 +4194,7 @@ system_f_call_or_t<nodeExprp>: // IEEE: part of system_tf_call (can be task
| yD_RANDOM parenE { $$ = new AstRand{$1, nullptr, false}; }
| yD_REALTIME parenE { $$ = new AstTimeD{$1, VTimescale{VTimescale::NONE}}; }
| yD_REALTOBITS '(' expr ')' { $$ = new AstRealToBits{$1, $3}; }
| yD_REWIND '(' idClassSel ')' { $$ = new AstFSeek{$1, $3, new AstConst{$1, 0}, new AstConst{$1, 0}}; }
| yD_REWIND '(' expr ')' { $$ = new AstFSeek{$1, $3, new AstConst{$1, 0}, new AstConst{$1, 0}}; }
| yD_RIGHT '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_RIGHT, $3, nullptr}; }
| yD_RIGHT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_RIGHT, $3, $5}; }
| yD_ROSE '(' expr ')' { $$ = new AstRose{$1, $3, nullptr}; }

View File

@ -24,6 +24,7 @@ module t;
reg [16*8:1] letterz;
real r;
string s;
reg [16*8:1] si;
integer i;
reg [7:0] v_a,v_b,v_c,v_d;
@ -88,6 +89,9 @@ module t;
i = $ferror(file, s);
`checkh(i, 2);
`checks(s, "No such file or directory");
si = "xx";
i = $ferror(file, si);
`checkh(i, 2);
end
begin

View File

@ -1,3 +1,4 @@
Sean Connery was the best Bond.
To file and to stdout
*-* All Finished *-*

View File

@ -4,16 +4,17 @@
// any use, without warranty, 2020 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
module t;
`define STR(__s) `"__s`"
task automatic fail(string s); begin
task automatic fail(string s);
$display({"FAIL! Reason: ", s});
$stop;
end endtask
endtask
task automatic test1; begin
task automatic test1;
int fd[30], fd_fail, fd_success, fd_close, tmp;
for (int i = 0; i < 30; i++) begin
// Attempt to allocate 30 MCD descriptors; returned descriptors
@ -45,9 +46,9 @@ module t;
fd_close = fd[i];
$fclose(fd_close);
end
end endtask
endtask
task automatic test2; begin
task automatic test2;
// Validate basic MCD functionality.
integer fd[3], fd_all, tmp;
@ -65,14 +66,29 @@ module t;
$fwrite(fd_all, "All other countries are inferior.\n");
$fwrite(fd_all, "Woe betide those to stand against the mighty Scottish nation.\n");
$fclose(fd_all);
end endtask
endtask
task automatic test3; begin
task automatic test3;
int result;
// Write some things to standard output.
$fwrite(32'h8000_0001, "Sean Connery was the best Bond.\n");
end endtask
$fwrite(32'h8000_0001);
$fstrobe(32'h8000_0001);
task automatic test4; begin
result = $fseek(32'hffffffff, 0, 0);
`checkd(result, -1);
result = $ftell(32'hffffffff);
`checkd(result, -1);
result = $rewind(32'hffffffff);
`checkd(result, -1);
result = $feof(0);
`checkd(result, 1);
endtask
task automatic test4;
int fd;
// Wide filename
fd = $fopen({`STR(`TEST_OBJ_DIR),
@ -80,16 +96,16 @@ module t;
"except_to_purposefully_break_my_beautiful_code.dat"});
if (fd == 0) fail("Long filename could not be opened.");
$fclose(fd);
end endtask
endtask
task automatic test5; begin
task automatic test5;
int fd_all;
fd_all = $fopen({`STR(`TEST_OBJ_DIR), "/t_sys_file_basic_mcd_test5.dat"});
if (fd_all == 0) fail("could not be opened.");
fd_all |= 1;
$fdisplay(fd_all, "To file and to stdout");
$fclose(fd_all);
end endtask
endtask
initial begin