Fix DLYSYNC with for loop variables

This commit is contained in:
Wilson Snyder 2010-12-31 20:18:21 -05:00
parent 4afcb421bd
commit 326cc8fd67
4 changed files with 54 additions and 7 deletions

View File

@ -160,7 +160,9 @@ public:
class ActiveDlyVisitor : public ActiveBaseVisitor {
private:
bool m_combo; // Combo logic
bool m_combo; // Combo logic
AstNode* m_alwaysp; // Always we're under
AstNode* m_assignp; // In assign
// VISITORS
virtual void visit(AstAssignDly* nodep, AstNUser*) {
if (m_combo) {
@ -176,12 +178,30 @@ private:
}
virtual void visit(AstAssign* nodep, AstNUser*) {
if (!m_combo) {
// Convert to a non-delayed assignment
nodep->v3warn(BLKSEQ,"Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).");
AstNode* las = m_assignp;
m_assignp = nodep;
nodep->lhsp()->iterateAndNext(*this);
m_assignp = las;
}
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
AstVar* varp=nodep->varp();
if (!m_combo
&& m_assignp
&& !varp->isUsedLoopIdx() // Ignore loop indicies
&& !varp->isTemp()
) {
// Allow turning off warnings on the always, or the variable also
if (!m_alwaysp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
&& !m_assignp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
&& !varp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
) {
m_alwaysp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Complain just once for the entire always
varp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true);
nodep->v3warn(BLKSEQ,"Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).");
}
}
}
// Empty visitors, speed things up
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
@ -189,7 +209,9 @@ private:
public:
// CONSTUCTORS
ActiveDlyVisitor(AstNode* nodep, bool combo) {
m_alwaysp = nodep;
m_combo = combo;
m_assignp = NULL;
nodep->accept(*this);
}
virtual ~ActiveDlyVisitor() {}

View File

@ -553,6 +553,7 @@ private:
bool m_sigUserRWPublic:1; // User C code accesses this signal, read-write
bool m_usedClock:1; // Signal used as a clock
bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup)
bool m_usedLoopIdx:1; // Variable subject of for unrolling
bool m_funcLocal:1; // Local variable for a function
bool m_funcReturn:1; // Return variable for a function
bool m_attrClockEn:1;// User clock enable attribute
@ -567,7 +568,7 @@ private:
m_input=false; m_output=false; m_tristate=false;
m_primaryIO=false;
m_sc=false; m_scClocked=false; m_scSensitive=false;
m_usedClock=false; m_usedParam=false;
m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false;
m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false;
m_funcLocal=false; m_funcReturn=false;
m_attrClockEn=false; m_attrIsolateAssign=false; m_attrSFormat=false;
@ -635,6 +636,7 @@ public:
void attrSFormat(bool flag) { m_attrSFormat = flag; }
void usedClock(bool flag) { m_usedClock = flag; }
void usedParam(bool flag) { m_usedParam = flag; }
void usedLoopIdx(bool flag) { m_usedLoopIdx = flag; }
void sigPublic(bool flag) { m_sigPublic = flag; }
void sigModPublic(bool flag) { m_sigModPublic = flag; }
void sigUserRdPublic(bool flag) { m_sigUserRdPublic = flag; if (flag) sigPublic(true); }
@ -675,6 +677,7 @@ public:
bool isBitLogic() const { AstBasicDType* bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); }
bool isUsedClock() const { return m_usedClock; }
bool isUsedParam() const { return m_usedParam; }
bool isUsedLoopIdx() const { return m_usedLoopIdx; }
bool isSc() const { return m_sc; }
bool isScQuad() const;
bool isScBv() const;

View File

@ -250,6 +250,9 @@ private:
incp->unlinkFrBackWithNext();
stmtsp = stmtsp->addNextNull(incp); // Maybe null if no body
}
// Mark variable to disable some later warnings
m_forVarp->usedLoopIdx(true);
// If it's a While, then incp is already part of bodysp.
V3Number loopValue(nodep->fileline(), m_forVarp->width()); // May differ in size from numInitp
loopValue.opAssign(numInit);

View File

@ -9,13 +9,19 @@ module t (/*AUTOARG*/
);
input clk;
integer i;
reg sync_blk;
reg sync_blk2;
reg sync_nblk;
reg sync2_ok;
reg sync3_ok;
reg combo_blk;
reg combo_nblk;
always @(posedge clk) begin
sync_blk = 1'b1;
sync_blk2 = 1'b1; // Only warn once per block
sync_nblk <= 1'b1;
end
@ -24,5 +30,18 @@ module t (/*AUTOARG*/
combo_nblk <= 1'b1;
end
endmodule
always @(posedge clk) begin
for (int i=0; i<20; i++) begin
sync2_ok <= 1'b1;
end
end
always @(posedge clk) begin
sync3_ok <= f(sync3_ok);
end
function f (input v);
f = ~v;
endfunction
endmodule