Support disable for loop escapes.
This commit is contained in:
parent
2e9471797d
commit
8137f41fc3
4
Changes
4
Changes
|
|
@ -3,6 +3,10 @@ Revision history for Verilator
|
|||
The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.814****
|
||||
|
||||
*** Support disable for loop escapes.
|
||||
|
||||
* Verilator 3.813 2011/06/28
|
||||
|
||||
*** Support bit vectors > 64 bits wide in DPI import and exports.
|
||||
|
|
|
|||
|
|
@ -2258,6 +2258,13 @@ not arrays nor structs.
|
|||
Treated as a "longint"; does not yet warn about operations that are
|
||||
specified as illegal on chandles.
|
||||
|
||||
=item disable
|
||||
|
||||
Disable statements may be used only if the block being disabled is a block
|
||||
the disable statement itself is inside. This is commonly used to provide
|
||||
loop break and continue functionality before SystemVerilog added the break
|
||||
and continue keywords.
|
||||
|
||||
=item priority if, unique if
|
||||
|
||||
Priority and unique if's are treated as normal ifs and not asserted to be
|
||||
|
|
|
|||
|
|
@ -1973,6 +1973,18 @@ struct AstContinue : public AstNodeStmt {
|
|||
virtual bool isSplittable() const { return false; } // SPECIAL: We don't process code after breaks
|
||||
};
|
||||
|
||||
struct AstDisable : public AstNodeStmt {
|
||||
private:
|
||||
string m_name; // Name of block
|
||||
public:
|
||||
AstDisable(FileLine* fileline, const string& name)
|
||||
: AstNodeStmt(fileline), m_name(name) {}
|
||||
ASTNODE_NODE_FUNCS(Disable, DISABLE)
|
||||
virtual string name() const { return m_name; } // * = Block name
|
||||
void name(const string& flag) { m_name=flag; }
|
||||
virtual bool isSplittable() const { return false; } // SPECIAL: We don't process code after breaks
|
||||
};
|
||||
|
||||
struct AstReturn : public AstNodeStmt {
|
||||
AstReturn(FileLine* fileline, AstNode* lhsp=NULL)
|
||||
: AstNodeStmt (fileline) {
|
||||
|
|
|
|||
|
|
@ -217,6 +217,9 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
}
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstDisable* nodep, AstNUser*) {
|
||||
putbs("disable "+nodep->name()+";\n");
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
visitNodeDisplay(nodep, nodep->filep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,6 +211,27 @@ private:
|
|||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
|
||||
}
|
||||
virtual void visit(AstDisable* nodep, AstNUser*) {
|
||||
UINFO(8," DISABLE "<<nodep<<endl);
|
||||
nodep->iterateChildren(*this);
|
||||
AstBegin* beginp = NULL;
|
||||
for (BeginStack::reverse_iterator it = m_beginStack.rbegin(); it != m_beginStack.rend(); ++it) {
|
||||
UINFO(9," UNDERBLK "<<*it<<endl);
|
||||
if ((*it)->name() == nodep->name()) {
|
||||
beginp = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labeli: "); }
|
||||
if (!beginp) { nodep->v3error("disable isn't underneath a begin with name: "<<nodep->name()); }
|
||||
else {
|
||||
// Jump to the end of the named begin
|
||||
AstJumpLabel* labelp = findAddLabel(beginp, false);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
|
||||
//if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labelo: "); }
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1886,7 +1886,7 @@ statement_item<nodep>: // IEEE: statement_item
|
|||
| statementVerilatorPragmas { $$ = $1; }
|
||||
//
|
||||
// // IEEE: disable_statement
|
||||
//UNSUP yDISABLE idAny/*hierarchical_identifier-task_or_block*/ ';' { UNSUP }
|
||||
| yDISABLE idAny/*hierarchical_identifier-task_or_block*/ ';' { $$ = new AstDisable($1,*$2); }
|
||||
//UNSUP yDISABLE yFORK ';' { UNSUP }
|
||||
// // IEEE: event_trigger
|
||||
//UNSUP yP_MINUSGT hierarchical_identifier/*event*/ ';' { UNSUP }
|
||||
|
|
|
|||
|
|
@ -92,8 +92,17 @@ module t (/*AUTOARG*/
|
|||
input [3:0] loop_continue;
|
||||
integer i;
|
||||
|
||||
// Placeholder
|
||||
return Test0(loop_stop,loop_break,loop_continue);
|
||||
Test1 = 0;
|
||||
begin : outer_block
|
||||
for (i=1; i<20; i=i+1) begin : inner_block
|
||||
Test1 = Test1 + 1;
|
||||
// continue, IE jump to end-of-inner_block. Must be inside inner_block.
|
||||
if (i[3:0] == loop_continue) disable inner_block;
|
||||
// break, IE jump to end-of-outer_block. Must be inside outer_block.
|
||||
if (i[3:0] == loop_break) disable outer_block;
|
||||
Test1 = Test1 + i[15:0];
|
||||
end : inner_block
|
||||
end : outer_block
|
||||
endfunction
|
||||
|
||||
function [15:0] Test2;
|
||||
|
|
|
|||
Loading…
Reference in New Issue