forked from github/verilator
Support to packed array
This commit is contained in:
parent
2d89c458f6
commit
eb5aad94f1
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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(); }
|
||||
};
|
||||
|
@ -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(")");
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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}; }
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,4 @@
|
||||
Sean Connery was the best Bond.
|
||||
To file and to stdout
|
||||
*-* All Finished *-*
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user