mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Support $ungetc.
This commit is contained in:
parent
8c5aa21a11
commit
c36d9a68f5
2
Changes
2
Changes
@ -4,7 +4,7 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
* Verilator 4.023 devel
|
||||
|
||||
**** Support $rewind.
|
||||
**** Support $rewind and $ungetc.
|
||||
|
||||
**** Add -Wpedantic for compliance testing.
|
||||
|
||||
|
@ -3562,8 +3562,7 @@ MCDs, which includes the mode parameter to $fopen being mandatory.
|
||||
|
||||
=item $fscanf, $sscanf
|
||||
|
||||
Only integer formats are supported; %e, %f, %m, %r, %v, and %z are not
|
||||
supported.
|
||||
The formats %r, %v, and %z are not supported.
|
||||
|
||||
=item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal,
|
||||
$setup, $setuphold, $skew, $timeskew, $width
|
||||
|
@ -4335,6 +4335,28 @@ public:
|
||||
AstNode* filep() const { return lhsp(); }
|
||||
};
|
||||
|
||||
class AstFUngetC : public AstNodeBiop {
|
||||
public:
|
||||
AstFUngetC(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
||||
: AstNodeBiop(fl, lhsp, rhsp) {}
|
||||
ASTNODE_NODE_FUNCS(FUngetC)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) {
|
||||
return new AstFUngetC(this->fileline(), lhsp, rhsp); }
|
||||
virtual string emitVerilog() { return "%f$ungetc(%r, %l)"; }
|
||||
// Non-existent filehandle returns EOF
|
||||
virtual string emitC() { return "(%li ? (ungetc(%ri, VL_CVT_I_FP(%li)) >= 0 ? 0 : -1) : -1)"; }
|
||||
virtual bool cleanOut() const { return false; }
|
||||
virtual bool cleanLhs() const { return true; }
|
||||
virtual bool cleanRhs() const { return true; }
|
||||
virtual bool sizeMattersLhs() const { return false; }
|
||||
virtual bool sizeMattersRhs() const { return false; }
|
||||
virtual int instrCount() const { return widthInstrs() * 64; }
|
||||
virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering
|
||||
AstNode* filep() const { return lhsp(); }
|
||||
AstNode* charp() const { return rhsp(); }
|
||||
};
|
||||
|
||||
class AstNodeSystemUniop : public AstNodeUniop {
|
||||
public:
|
||||
AstNodeSystemUniop(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
|
@ -149,6 +149,14 @@ private:
|
||||
}
|
||||
m_setRefLvalue = last_setRefLvalue;
|
||||
}
|
||||
virtual void visit(AstFUngetC* nodep) {
|
||||
bool last_setRefLvalue = m_setRefLvalue;
|
||||
{
|
||||
m_setRefLvalue = true;
|
||||
iterateAndNextNull(nodep->filep());
|
||||
}
|
||||
m_setRefLvalue = last_setRefLvalue;
|
||||
}
|
||||
virtual void visit(AstSScanF* nodep) {
|
||||
bool last_setRefLvalue = m_setRefLvalue;
|
||||
{
|
||||
|
@ -2380,6 +2380,13 @@ private:
|
||||
userIterateAndNext(nodep->strgp(), WidthVP(SELF, BOTH).p());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFUngetC* nodep) {
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckFileDesc(nodep, nodep->filep(), BOTH);
|
||||
iterateCheckSigned32(nodep, "$fungetc character", nodep->charp(), BOTH);
|
||||
nodep->dtypeSetLogicUnsized(32, 8, AstNumeric::SIGNED); // Spec says integer return
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFRead* nodep) {
|
||||
if (m_vup->prelim()) {
|
||||
nodep->dtypeSetSigned32(); // Spec says integer return
|
||||
|
@ -220,6 +220,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||
"$test$plusargs" { FL; return yD_TESTPLUSARGS; }
|
||||
"$time" { FL; return yD_TIME; }
|
||||
"$timeskew" { FL; return yaTIMINGSPEC; }
|
||||
"$ungetc" { FL; return yD_UNGETC; }
|
||||
"$value$plusargs" { FL; return yD_VALUEPLUSARGS; }
|
||||
"$width" { FL; return yaTIMINGSPEC; }
|
||||
"$write" { FL; return yD_WRITE; }
|
||||
|
@ -557,6 +557,7 @@ class AstSenTree;
|
||||
%token<fl> yD_TANH "$tanh"
|
||||
%token<fl> yD_TESTPLUSARGS "$test$plusargs"
|
||||
%token<fl> yD_TIME "$time"
|
||||
%token<fl> yD_UNGETC "$ungetc"
|
||||
%token<fl> yD_UNIT "$unit"
|
||||
%token<fl> yD_UNPACKED_DIMENSIONS "$unpacked_dimensions"
|
||||
%token<fl> yD_UNSIGNED "$unsigned"
|
||||
@ -2970,6 +2971,7 @@ system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
|
||||
| yD_TANH '(' expr ')' { $$ = new AstTanhD($1,$3); }
|
||||
| yD_TESTPLUSARGS '(' str ')' { $$ = new AstTestPlusArgs($1,*$3); }
|
||||
| yD_TIME parenE { $$ = new AstTime($1); }
|
||||
| yD_UNGETC '(' expr ',' expr ')' { $$ = new AstFUngetC($1, $5, $3); } // Arg swap to file first
|
||||
| yD_UNPACKED_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_UNPK_DIMENSIONS,$3); }
|
||||
| yD_UNSIGNED '(' expr ')' { $$ = new AstUnsigned($1,$3); }
|
||||
| yD_VALUEPLUSARGS '(' expr ',' expr ')' { $$ = new AstValuePlusArgs($1,$3,$5); }
|
||||
|
@ -90,6 +90,10 @@ module t;
|
||||
if ($fgetc(file) != "i") $stop;
|
||||
if ($fgetc(file) != "\n") $stop;
|
||||
|
||||
// $ungetc
|
||||
if ($ungetc("x", file) != 0) $stop;
|
||||
if ($fgetc(file) != "x") $stop;
|
||||
|
||||
// $fgets
|
||||
chars = $fgets(letterl, file);
|
||||
if (`verbose) $write("c=%0d l=%s\n", chars, letterl);
|
||||
|
Loading…
Reference in New Issue
Block a user