Add verilator no_inline_task
git-svn-id: file://localhost/svn/verilator/trunk/verilator@816 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
ea6bb21cdc
commit
3ad5872d30
2
Changes
2
Changes
|
|
@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
* Verilator 3.62**
|
* Verilator 3.62**
|
||||||
|
|
||||||
|
** Add /*verilator no_inline_task*/ to prevent over-expansion. [Eugene Weber]
|
||||||
|
|
||||||
*** Public functions now allow > 64 bit arguments.
|
*** Public functions now allow > 64 bit arguments.
|
||||||
|
|
||||||
**** Remove .vpp intermediate files when not under --debug.
|
**** Remove .vpp intermediate files when not under --debug.
|
||||||
|
|
|
||||||
|
|
@ -1056,6 +1056,14 @@ Disable the specified warning message for any warnings following the comment.
|
||||||
|
|
||||||
Re-enable the specified warning message for any warnings following the comment.
|
Re-enable the specified warning message for any warnings following the comment.
|
||||||
|
|
||||||
|
=item /*verilator no_inline_task*/
|
||||||
|
|
||||||
|
Used in a function or task variable definition section to specify the
|
||||||
|
function or task should not be inlined into where it is used. This may
|
||||||
|
reduce the size of the final executable when a task is used a very large
|
||||||
|
number of times. For this flag to work, the task and tasks below it must
|
||||||
|
be pure; they cannot reference any variables outside the task itself.
|
||||||
|
|
||||||
=item /*verilator sc_clock*/
|
=item /*verilator sc_clock*/
|
||||||
|
|
||||||
Used after a input declaration to indicate the signal should be declared in
|
Used after a input declaration to indicate the signal should be declared in
|
||||||
|
|
@ -1344,6 +1352,12 @@ signal before it is implicitly declared by a cell, and can lead to dangling
|
||||||
nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for
|
nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for
|
||||||
Emacs, available from L<http://www.veripool.com/>
|
Emacs, available from L<http://www.veripool.com/>
|
||||||
|
|
||||||
|
=item IMPURE
|
||||||
|
|
||||||
|
Warns that a task or function that has been marked with /*verilator
|
||||||
|
no_inline_task*/ references variables that are not local to the task.
|
||||||
|
Verilator cannot schedule these variables correctly.
|
||||||
|
|
||||||
=item MULTIDRIVEN
|
=item MULTIDRIVEN
|
||||||
|
|
||||||
Warns that the specified signal comes from multiple always blocks. This is
|
Warns that the specified signal comes from multiple always blocks. This is
|
||||||
|
|
|
||||||
|
|
@ -1328,6 +1328,38 @@ static inline WDataOutP VL_CONST_W_16X(int obits, WDataOutP o,
|
||||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
_END(obits,16); }
|
_END(obits,16); }
|
||||||
|
static inline WDataOutP VL_CONST_W_17X(int obits, WDataOutP o,
|
||||||
|
I d16,
|
||||||
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||||
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
|
o[16]=d16;
|
||||||
|
_END(obits,17); }
|
||||||
|
static inline WDataOutP VL_CONST_W_18X(int obits, WDataOutP o,
|
||||||
|
I d17,I d16,
|
||||||
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||||
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
|
o[16]=d16; o[17]=d17;
|
||||||
|
_END(obits,18); }
|
||||||
|
static inline WDataOutP VL_CONST_W_19X(int obits, WDataOutP o,
|
||||||
|
I d18,I d17,I d16,
|
||||||
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||||
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
|
o[16]=d16; o[17]=d17; o[18]=d18;
|
||||||
|
_END(obits,19); }
|
||||||
|
static inline WDataOutP VL_CONST_W_20X(int obits, WDataOutP o,
|
||||||
|
I d19,I d18,I d17,I d16,
|
||||||
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||||
|
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||||
|
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
|
||||||
|
o[16]=d16; o[17]=d17; o[18]=d18; o[19]=d19;
|
||||||
|
_END(obits,20); }
|
||||||
static inline WDataOutP VL_CONST_W_24X(int obits, WDataOutP o,
|
static inline WDataOutP VL_CONST_W_24X(int obits, WDataOutP o,
|
||||||
I d23,I d22,I d21,I d20,I d19,I d18,I d17,I d16,
|
I d23,I d22,I d21,I d20,I d19,I d18,I d17,I d16,
|
||||||
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ public:
|
||||||
COVERAGE_BLOCK_OFF,
|
COVERAGE_BLOCK_OFF,
|
||||||
INLINE_MODULE,
|
INLINE_MODULE,
|
||||||
NO_INLINE_MODULE,
|
NO_INLINE_MODULE,
|
||||||
|
NO_INLINE_TASK,
|
||||||
PUBLIC_MODULE,
|
PUBLIC_MODULE,
|
||||||
PUBLIC_TASK
|
PUBLIC_TASK
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,8 @@ void AstVar::dump(ostream& str) {
|
||||||
if (isSigPublic()) str<<" [P]";
|
if (isSigPublic()) str<<" [P]";
|
||||||
if (attrClockEn()) str<<" [aCLKEN]";
|
if (attrClockEn()) str<<" [aCLKEN]";
|
||||||
if (attrFileDescr()) str<<" [aFD]";
|
if (attrFileDescr()) str<<" [aFD]";
|
||||||
if (isFuncLocal() || isFuncReturn()) str<<" [FUNC]";
|
if (isFuncReturn()) str<<" [FUNCRTN]";
|
||||||
|
else if (isFuncLocal()) str<<" [FUNC]";
|
||||||
str<<" "<<varType();
|
str<<" "<<varType();
|
||||||
}
|
}
|
||||||
void AstSenTree::dump(ostream& str) {
|
void AstSenTree::dump(ostream& str) {
|
||||||
|
|
@ -375,6 +376,7 @@ void AstNodeFTaskRef::dump(ostream& str) {
|
||||||
}
|
}
|
||||||
void AstNodeFTask::dump(ostream& str) {
|
void AstNodeFTask::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
|
if (taskPublic()) str<<" [PUBLIC]";
|
||||||
}
|
}
|
||||||
void AstCoverDecl::dump(ostream& str) {
|
void AstCoverDecl::dump(ostream& str) {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,10 @@ private:
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
insureCleanAndNext (nodep->bodysp());
|
insureCleanAndNext (nodep->bodysp());
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstCCall* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
insureCleanAndNext (nodep->argsp());
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------
|
//--------------------
|
||||||
// Default: Just iterate
|
// Default: Just iterate
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,6 @@ public:
|
||||||
string cFuncArgs(AstCFunc* nodep) {
|
string cFuncArgs(AstCFunc* nodep) {
|
||||||
// Return argument list for given C function
|
// Return argument list for given C function
|
||||||
string args = nodep->argTypes();
|
string args = nodep->argTypes();
|
||||||
if (args=="") {
|
|
||||||
// Might be a user function with argument list.
|
// Might be a user function with argument list.
|
||||||
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||||
if (AstVar* portp = stmtp->castVar()) {
|
if (AstVar* portp = stmtp->castVar()) {
|
||||||
|
|
@ -115,7 +114,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -168,9 +168,8 @@ void FileLine::v3errorEnd(ostringstream& str) {
|
||||||
void V3Error::init() {
|
void V3Error::init() {
|
||||||
for (int i=0; i<V3ErrorCode::MAX; i++) {
|
for (int i=0; i<V3ErrorCode::MAX; i++) {
|
||||||
s_describedEachWarn[i] = false;
|
s_describedEachWarn[i] = false;
|
||||||
s_pretendError[i] = false;
|
s_pretendError[i] = V3ErrorCode(i).pretendError();
|
||||||
}
|
}
|
||||||
pretendError(V3ErrorCode::BLKANDNBLK, true);
|
|
||||||
|
|
||||||
if (string(V3ErrorCode(V3ErrorCode::MAX).ascii()) != " MAX") {
|
if (string(V3ErrorCode(V3ErrorCode::MAX).ascii()) != " MAX") {
|
||||||
v3fatalSrc("Enum table in V3ErrorCode::ascii() is munged");
|
v3fatalSrc("Enum table in V3ErrorCode::ascii() is munged");
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ public:
|
||||||
COMBDLY, // Combinatorial delayed assignment
|
COMBDLY, // Combinatorial delayed assignment
|
||||||
GENCLK, // Generated Clock
|
GENCLK, // Generated Clock
|
||||||
IMPLICIT, // Implicit wire
|
IMPLICIT, // Implicit wire
|
||||||
|
IMPURE, // Impure function not being inlined
|
||||||
MULTIDRIVEN, // Driven from multiple blocks
|
MULTIDRIVEN, // Driven from multiple blocks
|
||||||
UNDRIVEN, // No drivers
|
UNDRIVEN, // No drivers
|
||||||
UNOPT, // Unoptimizable block
|
UNOPT, // Unoptimizable block
|
||||||
|
|
@ -69,7 +70,7 @@ public:
|
||||||
" FIRST_WARN",
|
" FIRST_WARN",
|
||||||
"BLKANDNBLK",
|
"BLKANDNBLK",
|
||||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
|
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
|
||||||
"COMBDLY", "GENCLK", "IMPLICIT",
|
"COMBDLY", "GENCLK", "IMPLICIT", "IMPURE",
|
||||||
"MULTIDRIVEN",
|
"MULTIDRIVEN",
|
||||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
||||||
"VARHIDDEN", "WIDTH",
|
"VARHIDDEN", "WIDTH",
|
||||||
|
|
@ -79,6 +80,9 @@ public:
|
||||||
};
|
};
|
||||||
// Warnings that warn about nasty side effects
|
// Warnings that warn about nasty side effects
|
||||||
bool dangerous() const { return ( m_e==COMBDLY );};
|
bool dangerous() const { return ( m_e==COMBDLY );};
|
||||||
|
// Warnings we'll present to the user as errors
|
||||||
|
// Later -Werror- options may make more of these.
|
||||||
|
bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE );};
|
||||||
};
|
};
|
||||||
inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
|
|
||||||
|
|
@ -374,8 +374,10 @@ private:
|
||||||
//UINFO(4," CCALL "<<nodep<<endl);
|
//UINFO(4," CCALL "<<nodep<<endl);
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
// Enter the function and trace it
|
// Enter the function and trace it
|
||||||
|
if (!nodep->funcp()->entryPoint()) { // else is non-inline or public function we optimize separately
|
||||||
nodep->funcp()->accept(*this);
|
nodep->funcp()->accept(*this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
virtual void visit(AstUCFunc* nodep, AstNUser*) {
|
virtual void visit(AstUCFunc* nodep, AstNUser*) {
|
||||||
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
|
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
|
|
|
||||||
268
src/V3Task.cpp
268
src/V3Task.cpp
|
|
@ -39,6 +39,54 @@
|
||||||
#include "V3Inst.h"
|
#include "V3Inst.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
#include "V3EmitCBase.h"
|
#include "V3EmitCBase.h"
|
||||||
|
#include "V3Graph.h"
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
// Graph subclasses
|
||||||
|
|
||||||
|
class TaskBaseVertex : public V3GraphVertex {
|
||||||
|
AstNode* m_impurep; // Node causing impure function w/ outside references
|
||||||
|
bool m_noInline; // Marked with pragma
|
||||||
|
public:
|
||||||
|
TaskBaseVertex(V3Graph* graphp)
|
||||||
|
: V3GraphVertex(graphp), m_impurep(NULL), m_noInline(false) {}
|
||||||
|
virtual ~TaskBaseVertex() {}
|
||||||
|
bool pure() const { return m_impurep==NULL; }
|
||||||
|
AstNode* impureNode() const { return m_impurep; }
|
||||||
|
void impure(AstNode* nodep) { m_impurep = nodep; }
|
||||||
|
bool noInline() const { return m_noInline; }
|
||||||
|
void noInline(bool flag) { m_noInline = flag; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class TaskFTaskVertex : public TaskBaseVertex {
|
||||||
|
// Every task gets a vertex, and we link tasks together based on funcrefs.
|
||||||
|
AstNodeFTask* m_nodep;
|
||||||
|
public:
|
||||||
|
TaskFTaskVertex(V3Graph* graphp, AstNodeFTask* nodep)
|
||||||
|
: TaskBaseVertex(graphp), m_nodep(nodep) {}
|
||||||
|
virtual ~TaskFTaskVertex() {}
|
||||||
|
AstNodeFTask* nodep() const { return m_nodep; }
|
||||||
|
virtual string name() const { return nodep()->name(); }
|
||||||
|
virtual string dotColor() const { return pure() ? "black" : "red"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class TaskCodeVertex : public TaskBaseVertex {
|
||||||
|
// Top vertex for all calls not under another task
|
||||||
|
public:
|
||||||
|
TaskCodeVertex(V3Graph* graphp)
|
||||||
|
: TaskBaseVertex(graphp) {}
|
||||||
|
virtual ~TaskCodeVertex() {}
|
||||||
|
virtual string name() const { return "*CODE*"; }
|
||||||
|
virtual string dotColor() const { return "green"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class TaskEdge : public V3GraphEdge {
|
||||||
|
public:
|
||||||
|
TaskEdge(V3Graph* graphp, TaskBaseVertex* fromp, TaskBaseVertex* top)
|
||||||
|
: V3GraphEdge(graphp, fromp, top, 1, false) {}
|
||||||
|
virtual ~TaskEdge() {}
|
||||||
|
virtual string dotLabel() const { return "w"+cvtToStr(weight()); }
|
||||||
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
|
|
@ -47,12 +95,17 @@ private:
|
||||||
// NODE STATE
|
// NODE STATE
|
||||||
// Output:
|
// Output:
|
||||||
// AstNodeFTask::user3p // AstScope* this FTask is under
|
// AstNodeFTask::user3p // AstScope* this FTask is under
|
||||||
|
// AstNodeFTask::user4p // GraphFTaskVertex* this FTask is under
|
||||||
|
// AstVar::user4p // GraphFTaskVertex* this variable is declared in
|
||||||
|
|
||||||
// TYPES
|
// TYPES
|
||||||
typedef std::map<pair<AstScope*,AstVar*>,AstVarScope*> VarToScopeMap;
|
typedef std::map<pair<AstScope*,AstVar*>,AstVarScope*> VarToScopeMap;
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
VarToScopeMap m_varToScopeMap; // Map for Var -> VarScope mappings
|
VarToScopeMap m_varToScopeMap; // Map for Var -> VarScope mappings
|
||||||
AstAssignW* m_assignwp; // Current assignment
|
AstAssignW* m_assignwp; // Current assignment
|
||||||
|
V3Graph m_callGraph; // Task call graph
|
||||||
|
TaskBaseVertex* m_curVxp; // Current vertex we're adding to
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// METHODS
|
// METHODS
|
||||||
AstScope* getScope(AstNodeFTask* nodep) {
|
AstScope* getScope(AstNodeFTask* nodep) {
|
||||||
|
|
@ -65,7 +118,30 @@ public:
|
||||||
if (iter == m_varToScopeMap.end()) nodep->v3fatalSrc("No scope for var");
|
if (iter == m_varToScopeMap.end()) nodep->v3fatalSrc("No scope for var");
|
||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
bool ftaskNoInline(AstNodeFTask* nodep) {
|
||||||
|
return (getFTaskVertex(nodep)->noInline());
|
||||||
|
}
|
||||||
|
void checkPurity(AstNodeFTask* nodep) {
|
||||||
|
checkPurity(nodep, getFTaskVertex(nodep));
|
||||||
|
}
|
||||||
|
void checkPurity(AstNodeFTask* nodep, TaskBaseVertex* vxp) {
|
||||||
|
if (!vxp->pure()) {
|
||||||
|
nodep->v3warn(IMPURE,"Unsupported: External variable referenced by non-inlined function/task: "<<nodep->prettyName());
|
||||||
|
vxp->impureNode()->v3warn(IMPURE,"... Location of the external reference: "<<vxp->impureNode()->prettyName());
|
||||||
|
}
|
||||||
|
// And, we need to check all tasks this task calls
|
||||||
|
for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
||||||
|
checkPurity(nodep, static_cast<TaskBaseVertex*>(edgep->top()));
|
||||||
|
}
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
|
TaskBaseVertex* getFTaskVertex(AstNodeFTask* nodep) {
|
||||||
|
if (!nodep->user4p()) {
|
||||||
|
nodep->user4p(new TaskFTaskVertex(&m_callGraph, nodep));
|
||||||
|
}
|
||||||
|
return static_cast<TaskBaseVertex*>(nodep->user4p()->castGraphVertex());
|
||||||
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||||
// Each FTask is unique per-scope, so AstNodeFTaskRefs do not need
|
// Each FTask is unique per-scope, so AstNodeFTaskRefs do not need
|
||||||
|
|
@ -90,7 +166,7 @@ private:
|
||||||
}
|
}
|
||||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||||
m_assignwp = nodep;
|
m_assignwp = nodep;
|
||||||
nodep->iterateChildren(*this); // May delete nodep.
|
nodep->iterateChildren(*this); nodep=NULL; // May delete nodep.
|
||||||
m_assignwp = NULL;
|
m_assignwp = NULL;
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
||||||
|
|
@ -104,6 +180,37 @@ private:
|
||||||
AstNode* alwaysp = new AstAlways (m_assignwp->fileline(), NULL, assignp);
|
AstNode* alwaysp = new AstAlways (m_assignwp->fileline(), NULL, assignp);
|
||||||
m_assignwp->replaceWith(alwaysp); pushDeletep(m_assignwp); m_assignwp=NULL;
|
m_assignwp->replaceWith(alwaysp); pushDeletep(m_assignwp); m_assignwp=NULL;
|
||||||
}
|
}
|
||||||
|
// We make multiple edges if a task is called multiple times from another task.
|
||||||
|
new TaskEdge (&m_callGraph, m_curVxp, getFTaskVertex(nodep->taskp()));
|
||||||
|
}
|
||||||
|
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
||||||
|
UINFO(9," TASK "<<nodep<<endl);
|
||||||
|
TaskBaseVertex* lastVxp = m_curVxp;
|
||||||
|
m_curVxp = getFTaskVertex(nodep);
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
m_curVxp = lastVxp;
|
||||||
|
}
|
||||||
|
virtual void visit(AstPragma* nodep, AstNUser*) {
|
||||||
|
if (nodep->pragType() == AstPragmaType::NO_INLINE_TASK) {
|
||||||
|
// Just mark for the next steps, and we're done with it.
|
||||||
|
m_curVxp->noInline(true);
|
||||||
|
nodep->unlinkFrBack()->deleteTree();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
nodep->user4p(m_curVxp); // Remember what task it's under
|
||||||
|
}
|
||||||
|
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
if (nodep->varp()->user4p() != m_curVxp) {
|
||||||
|
if (m_curVxp->pure()) {
|
||||||
|
m_curVxp->impure(nodep);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//--------------------
|
//--------------------
|
||||||
// Default: Just iterate
|
// Default: Just iterate
|
||||||
|
|
@ -112,10 +219,16 @@ private:
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
TaskStateVisitor(AstNode* nodep) {
|
TaskStateVisitor(AstNetlist* nodep) {
|
||||||
m_assignwp = NULL;
|
m_assignwp = NULL;
|
||||||
|
m_curVxp = new TaskCodeVertex(&m_callGraph);
|
||||||
AstNode::user3ClearTree();
|
AstNode::user3ClearTree();
|
||||||
|
AstNode::user4ClearTree();
|
||||||
|
//
|
||||||
nodep->iterateAndNext(*this, NULL);
|
nodep->iterateAndNext(*this, NULL);
|
||||||
|
//
|
||||||
|
m_callGraph.removeRedundantEdgesSum(&TaskEdge::followAlwaysTrue);
|
||||||
|
m_callGraph.dumpDotFilePrefixed("task_call");
|
||||||
}
|
}
|
||||||
virtual ~TaskStateVisitor() {}
|
virtual ~TaskStateVisitor() {}
|
||||||
};
|
};
|
||||||
|
|
@ -165,6 +278,7 @@ private:
|
||||||
// AstNodeFTask::user // True if its been expanded
|
// AstNodeFTask::user // True if its been expanded
|
||||||
// Each funccall
|
// Each funccall
|
||||||
// AstVar::user2p // AstVarScope* to replace varref with
|
// AstVar::user2p // AstVarScope* to replace varref with
|
||||||
|
// AstNodeFTask::user5p // AstCFunc* created for non-inlined tasks
|
||||||
|
|
||||||
// TYPES
|
// TYPES
|
||||||
enum InsertMode {
|
enum InsertMode {
|
||||||
|
|
@ -207,6 +321,7 @@ private:
|
||||||
//
|
//
|
||||||
// Create input variables
|
// Create input variables
|
||||||
AstNode::user2ClearTree();
|
AstNode::user2ClearTree();
|
||||||
|
{
|
||||||
AstNode* pinp = refp->pinsp();
|
AstNode* pinp = refp->pinsp();
|
||||||
AstNode* nextpinp = pinp;
|
AstNode* nextpinp = pinp;
|
||||||
AstNode* nextstmtp;
|
AstNode* nextstmtp;
|
||||||
|
|
@ -280,6 +395,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pinp!=NULL) refp->v3error("Too many arguments in function call");
|
if (pinp!=NULL) refp->v3error("Too many arguments in function call");
|
||||||
|
}
|
||||||
// Create function output variables
|
// Create function output variables
|
||||||
if (outvscp) {
|
if (outvscp) {
|
||||||
//UINFO(0, "setflag on "<<funcp->fvarp()<<" to "<<outvscp<<endl);
|
//UINFO(0, "setflag on "<<funcp->fvarp()<<" to "<<outvscp<<endl);
|
||||||
|
|
@ -292,9 +408,71 @@ private:
|
||||||
return beginp;
|
return beginp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, string namePrefix, AstVarScope* outvscp) {
|
||||||
|
// outvscp is the variable for functions only, if NULL, it's a task
|
||||||
|
if (!refp->taskp()) refp->v3fatalSrc("Unlinked?");
|
||||||
|
AstCFunc* cfuncp = refp->taskp()->user5p()->castNode()->castCFunc();
|
||||||
|
|
||||||
AstCFunc* makeUserFunc(AstNodeFTask* nodep) {
|
if (!cfuncp) refp->v3fatalSrc("No non-inline task associated with this task call?");
|
||||||
// Given a already cloned node, make a public C function.
|
//
|
||||||
|
AstNode* beginp = new AstComment(refp->fileline(), (string)("Function: ")+refp->name());
|
||||||
|
AstCCall* ccallp = new AstCCall(refp->fileline(), cfuncp, NULL);
|
||||||
|
beginp->addNext(ccallp);
|
||||||
|
// Convert complicated outputs to temp signals
|
||||||
|
{
|
||||||
|
AstNode* pinp = refp->pinsp();
|
||||||
|
AstNode* nextpinp = pinp;
|
||||||
|
AstNode* nextstmtp;
|
||||||
|
for (AstNode* stmtp = refp->taskp()->stmtsp(); stmtp; pinp=nextpinp, stmtp=nextstmtp) {
|
||||||
|
nextstmtp = stmtp->nextp();
|
||||||
|
if (AstVar* portp = stmtp->castVar()) {
|
||||||
|
if (portp->isIO()) {
|
||||||
|
UINFO(9, " Port "<<portp<<endl);
|
||||||
|
UINFO(9, " pin "<<pinp<<endl);
|
||||||
|
//
|
||||||
|
nextpinp = pinp->nextp();
|
||||||
|
//
|
||||||
|
if (portp->isInout()) {
|
||||||
|
if (pinp->castVarRef()) {
|
||||||
|
// Connect to this exact variable
|
||||||
|
} else {
|
||||||
|
pinp->v3error("Unsupported: Function/task input argument is not simple variable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (portp->isOutput()) {
|
||||||
|
// Make output variables
|
||||||
|
// Correct lvalue; we didn't know when we linked
|
||||||
|
if (AstVarRef* varrefp = pinp->castVarRef()) {
|
||||||
|
varrefp->lvalue(true);
|
||||||
|
} else {
|
||||||
|
pinp->v3error("Unsupported: Task output pin connected to non-variable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pinp!=NULL) refp->v3error("Too many arguments in function call");
|
||||||
|
}
|
||||||
|
// First argument is symbol table, then output if a function
|
||||||
|
ccallp->argTypes("vlSymsp");
|
||||||
|
if (outvscp) {
|
||||||
|
ccallp->addArgsp(new AstVarRef(refp->fileline(), outvscp, true));
|
||||||
|
}
|
||||||
|
// Create connections
|
||||||
|
AstNode* nextpinp;
|
||||||
|
for (AstNode* pinp = refp->pinsp(); pinp; pinp=nextpinp) {
|
||||||
|
nextpinp = pinp->nextp();
|
||||||
|
// Move pin to the CCall
|
||||||
|
pinp->unlinkFrBack();
|
||||||
|
ccallp->addArgsp(pinp);
|
||||||
|
}
|
||||||
|
if (debug()>=9) { beginp->dumpTree(cout,"-nitask: "); }
|
||||||
|
return beginp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AstCFunc* makeUserFunc(AstNodeFTask* nodep, bool forUser) {
|
||||||
|
// Given a already cloned node, make a public C function, or a non-inline C function
|
||||||
// Probably some of this work should be done later, but...
|
// Probably some of this work should be done later, but...
|
||||||
// should the type of the function be bool/uint32/64 etc (based on lookup) or IData?
|
// should the type of the function be bool/uint32/64 etc (based on lookup) or IData?
|
||||||
AstNode::user2ClearTree();
|
AstNode::user2ClearTree();
|
||||||
|
|
@ -305,6 +483,7 @@ private:
|
||||||
if (NULL!=(portp = nodep->castFunc()->fvarp()->castVar())) {
|
if (NULL!=(portp = nodep->castFunc()->fvarp()->castVar())) {
|
||||||
if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var");
|
if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var");
|
||||||
if (portp->isWide()) nodep->v3error("Unsupported: Public functions with return > 64 bits wide. (Make it a output instead.)");
|
if (portp->isWide()) nodep->v3error("Unsupported: Public functions with return > 64 bits wide. (Make it a output instead.)");
|
||||||
|
if (!forUser) portp->funcReturn(false); // Converting return to 'outputs'
|
||||||
portp->unlinkFrBack();
|
portp->unlinkFrBack();
|
||||||
rtnvarp = portp;
|
rtnvarp = portp;
|
||||||
rtnvarp->funcLocal(true);
|
rtnvarp->funcLocal(true);
|
||||||
|
|
@ -315,20 +494,28 @@ private:
|
||||||
nodep->v3fatalSrc("function without function output variable");
|
nodep->v3fatalSrc("function without function output variable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AstCFunc* funcp = new AstCFunc(nodep->fileline(), nodep->name(),
|
AstCFunc* cfuncp = new AstCFunc(nodep->fileline(),
|
||||||
|
string(forUser?"":"__VnoInFunc_") + nodep->name(),
|
||||||
m_scopep,
|
m_scopep,
|
||||||
(rtnvarp?rtnvarp->cType():""));
|
((forUser && rtnvarp)?rtnvarp->cType():""));
|
||||||
if (rtnvarp) funcp->addArgsp(rtnvarp);
|
cfuncp->dontCombine(true);
|
||||||
funcp->dontCombine(true);
|
cfuncp->entryPoint(true);
|
||||||
funcp->funcPublic(true);
|
cfuncp->funcPublic(forUser);
|
||||||
funcp->entryPoint(true);
|
cfuncp->isStatic(!forUser);
|
||||||
funcp->isStatic(false);
|
|
||||||
|
|
||||||
|
if (forUser) {
|
||||||
// We need to get a pointer to all of our variables (may have eval'ed something else earlier)
|
// We need to get a pointer to all of our variables (may have eval'ed something else earlier)
|
||||||
funcp->addInitsp(
|
cfuncp->addInitsp(
|
||||||
new AstCStmt(nodep->fileline(),
|
new AstCStmt(nodep->fileline(),
|
||||||
" "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n"));
|
" "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n"));
|
||||||
funcp->addInitsp(new AstCStmt(nodep->fileline()," "+EmitCBaseVisitor::symTopAssign()+"\n"));
|
} else {
|
||||||
|
// Need symbol table
|
||||||
|
cfuncp->argTypes(EmitCBaseVisitor::symClassVar());
|
||||||
|
}
|
||||||
|
// Fake output variable if was a function
|
||||||
|
if (rtnvarp) cfuncp->addArgsp(rtnvarp);
|
||||||
|
|
||||||
|
cfuncp->addInitsp(new AstCStmt(nodep->fileline()," "+EmitCBaseVisitor::symTopAssign()+"\n"));
|
||||||
|
|
||||||
// Create list of arguments and move to function
|
// Create list of arguments and move to function
|
||||||
for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) {
|
for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) {
|
||||||
|
|
@ -338,7 +525,7 @@ private:
|
||||||
// Move it to new function
|
// Move it to new function
|
||||||
portp->unlinkFrBack();
|
portp->unlinkFrBack();
|
||||||
portp->funcLocal(true);
|
portp->funcLocal(true);
|
||||||
funcp->addArgsp(portp);
|
cfuncp->addArgsp(portp);
|
||||||
} else {
|
} else {
|
||||||
// "Normal" variable, mark inside function
|
// "Normal" variable, mark inside function
|
||||||
portp->funcLocal(true);
|
portp->funcLocal(true);
|
||||||
|
|
@ -350,18 +537,19 @@ private:
|
||||||
}
|
}
|
||||||
// Move body
|
// Move body
|
||||||
AstNode* bodysp = nodep->stmtsp();
|
AstNode* bodysp = nodep->stmtsp();
|
||||||
if (bodysp) { bodysp->unlinkFrBackWithNext(); funcp->addStmtsp(bodysp); }
|
if (bodysp) { bodysp->unlinkFrBackWithNext(); cfuncp->addStmtsp(bodysp); }
|
||||||
// Return statement
|
// Return statement
|
||||||
if (rtnvscp) {
|
if (rtnvscp && forUser) {
|
||||||
funcp->addFinalsp(new AstCReturn(rtnvscp->fileline(),
|
cfuncp->addFinalsp(new AstCReturn(rtnvscp->fileline(),
|
||||||
new AstVarRef(rtnvscp->fileline(), rtnvscp, false)));
|
new AstVarRef(rtnvscp->fileline(), rtnvscp, false)));
|
||||||
}
|
}
|
||||||
// Replace variable refs
|
// Replace variable refs
|
||||||
TaskRelinkVisitor visit (funcp);
|
TaskRelinkVisitor visit (cfuncp);
|
||||||
// Delete rest of cloned task and return new func
|
// Delete rest of cloned task and return new func
|
||||||
pushDeletep(nodep); nodep=NULL;
|
pushDeletep(nodep); nodep=NULL;
|
||||||
if (debug()>=9) { funcp->dumpTree(cout,"-userFunc: "); }
|
if (debug()>=9 && forUser) { cfuncp->dumpTree(cout,"-userFunc: "); }
|
||||||
return funcp;
|
if (debug()>=9 && !forUser) { cfuncp->dumpTree(cout,"-noInFunc: "); }
|
||||||
|
return cfuncp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iterateIntoFTask(AstNodeFTask* nodep) {
|
void iterateIntoFTask(AstNodeFTask* nodep) {
|
||||||
|
|
@ -421,7 +609,12 @@ private:
|
||||||
if (debug()>=9) { nodep->dumpTree(cout,"-inltask:"); }
|
if (debug()>=9) { nodep->dumpTree(cout,"-inltask:"); }
|
||||||
// Create cloned statements
|
// Create cloned statements
|
||||||
string namePrefix = "__Vtask_"+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++);
|
string namePrefix = "__Vtask_"+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++);
|
||||||
AstNode* beginp = createInlinedFTask(nodep, namePrefix, NULL);
|
AstNode* beginp;
|
||||||
|
if (m_statep->ftaskNoInline(nodep->taskp())) {
|
||||||
|
beginp = createNonInlinedFTask(nodep, namePrefix, NULL);
|
||||||
|
} else {
|
||||||
|
beginp = createInlinedFTask(nodep, namePrefix, NULL);
|
||||||
|
}
|
||||||
// Replace the ref
|
// Replace the ref
|
||||||
nodep->replaceWith(beginp);
|
nodep->replaceWith(beginp);
|
||||||
nodep->deleteTree(); nodep=NULL;
|
nodep->deleteTree(); nodep=NULL;
|
||||||
|
|
@ -442,7 +635,13 @@ private:
|
||||||
if (debug()>=9) { nodep->taskp()->dumpTree(cout,"-oldfunc:"); }
|
if (debug()>=9) { nodep->taskp()->dumpTree(cout,"-oldfunc:"); }
|
||||||
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked?");
|
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked?");
|
||||||
|
|
||||||
AstNode* beginp = createInlinedFTask(nodep, namePrefix, outvscp);
|
AstNode* beginp;
|
||||||
|
if (m_statep->ftaskNoInline(nodep->taskp())) {
|
||||||
|
// This may share VarScope's with a public task, if any. Yuk.
|
||||||
|
beginp = createNonInlinedFTask(nodep, namePrefix, outvscp);
|
||||||
|
} else {
|
||||||
|
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
|
||||||
|
}
|
||||||
// Replace the ref
|
// Replace the ref
|
||||||
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
|
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
|
||||||
nodep->replaceWith(outrefp);
|
nodep->replaceWith(outrefp);
|
||||||
|
|
@ -450,27 +649,34 @@ private:
|
||||||
insertBeforeStmt(nodep, beginp);
|
insertBeforeStmt(nodep, beginp);
|
||||||
// Cleanup
|
// Cleanup
|
||||||
nodep->deleteTree(); nodep=NULL;
|
nodep->deleteTree(); nodep=NULL;
|
||||||
UINFO(4," Done.\n");
|
UINFO(4," Func REF Done.\n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
||||||
|
UINFO(4," Inline "<<nodep<<endl);
|
||||||
InsertMode prevInsMode = m_insMode;
|
InsertMode prevInsMode = m_insMode;
|
||||||
AstNode* prevInsStmtp = m_insStmtp;
|
AstNode* prevInsStmtp = m_insStmtp;
|
||||||
m_insMode = IM_BEFORE;
|
m_insMode = IM_BEFORE;
|
||||||
m_insStmtp = nodep->stmtsp(); // Might be null if no statements, but we won't use it
|
m_insStmtp = nodep->stmtsp(); // Might be null if no statements, but we won't use it
|
||||||
if (!nodep->user()) {
|
if (!nodep->user()) {
|
||||||
// Expand functions in it & Mark for later delete
|
// Expand functions in it
|
||||||
nodep->user(true);
|
nodep->user(true);
|
||||||
if (!nodep->taskPublic()) {
|
if (nodep->taskPublic()) {
|
||||||
nodep->unlinkFrBack();
|
|
||||||
} else {
|
|
||||||
// Clone it first, because we may have later FTaskRef's that still need
|
// Clone it first, because we may have later FTaskRef's that still need
|
||||||
// the original version.
|
// the original version.
|
||||||
AstNodeFTask* clonedFuncp = nodep->cloneTree(false)->castNodeFTask();
|
AstNodeFTask* clonedFuncp = nodep->cloneTree(false)->castNodeFTask();
|
||||||
AstCFunc* cfuncp = makeUserFunc(clonedFuncp);
|
AstCFunc* cfuncp = makeUserFunc(clonedFuncp, true);
|
||||||
// Replace it
|
nodep->addNextHere(cfuncp);
|
||||||
nodep->replaceWith(cfuncp);
|
|
||||||
iterateIntoFTask(clonedFuncp); // Do the clone too
|
iterateIntoFTask(clonedFuncp); // Do the clone too
|
||||||
}
|
}
|
||||||
|
if (m_statep->ftaskNoInline(nodep)) {
|
||||||
|
m_statep->checkPurity(nodep);
|
||||||
|
AstNodeFTask* clonedFuncp = nodep->cloneTree(false)->castNodeFTask();
|
||||||
|
AstCFunc* cfuncp = makeUserFunc(clonedFuncp, false);
|
||||||
|
nodep->user5p(cfuncp);
|
||||||
|
nodep->addNextHere(cfuncp);
|
||||||
|
iterateIntoFTask(clonedFuncp); // Do the clone too
|
||||||
|
}
|
||||||
|
|
||||||
// Any variables inside the function still have varscopes pointing to them.
|
// Any variables inside the function still have varscopes pointing to them.
|
||||||
// We're going to delete the vars, so delete the varscopes.
|
// We're going to delete the vars, so delete the varscopes.
|
||||||
if (nodep->castFunc()) {
|
if (nodep->castFunc()) {
|
||||||
|
|
@ -489,6 +695,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Just push, as other references to func may remain until visitor exits
|
// Just push, as other references to func may remain until visitor exits
|
||||||
|
nodep->unlinkFrBack();
|
||||||
pushDeletep(nodep); nodep=NULL;
|
pushDeletep(nodep); nodep=NULL;
|
||||||
}
|
}
|
||||||
m_insMode = prevInsMode;
|
m_insMode = prevInsMode;
|
||||||
|
|
@ -532,6 +739,7 @@ public:
|
||||||
m_scopep = NULL;
|
m_scopep = NULL;
|
||||||
m_insStmtp = NULL;
|
m_insStmtp = NULL;
|
||||||
AstNode::userClearTree();
|
AstNode::userClearTree();
|
||||||
|
AstNode::user5ClearTree();
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
}
|
}
|
||||||
virtual ~TaskVisitor() {}
|
virtual ~TaskVisitor() {}
|
||||||
|
|
|
||||||
|
|
@ -429,6 +429,7 @@ escid \\[^ \t\f\r\n]+
|
||||||
<VLG,PSL>"/*verilator full_case*/" {yylval.fileline = CRELINE(); return yVL_FULL_CASE;}
|
<VLG,PSL>"/*verilator full_case*/" {yylval.fileline = CRELINE(); return yVL_FULL_CASE;}
|
||||||
<VLG,PSL>"/*verilator inline_module*/" {yylval.fileline = CRELINE(); return yVL_INLINE_MODULE;}
|
<VLG,PSL>"/*verilator inline_module*/" {yylval.fileline = CRELINE(); return yVL_INLINE_MODULE;}
|
||||||
<VLG,PSL>"/*verilator no_inline_module*/" {yylval.fileline = CRELINE(); return yVL_NO_INLINE_MODULE;}
|
<VLG,PSL>"/*verilator no_inline_module*/" {yylval.fileline = CRELINE(); return yVL_NO_INLINE_MODULE;}
|
||||||
|
<VLG,PSL>"/*verilator no_inline_task*/" {yylval.fileline = CRELINE(); return yVL_NO_INLINE_TASK;}
|
||||||
<VLG,PSL>"/*verilator one_cold*/" {yylval.fileline = CRELINE(); return yVL_ONE_COLD;}
|
<VLG,PSL>"/*verilator one_cold*/" {yylval.fileline = CRELINE(); return yVL_ONE_COLD;}
|
||||||
<VLG,PSL>"/*verilator one_hot*/" {yylval.fileline = CRELINE(); return yVL_ONE_HOT;}
|
<VLG,PSL>"/*verilator one_hot*/" {yylval.fileline = CRELINE(); return yVL_ONE_HOT;}
|
||||||
<VLG,PSL>"/*verilator parallel_case*/" {yylval.fileline = CRELINE(); return yVL_PARALLEL_CASE;}
|
<VLG,PSL>"/*verilator parallel_case*/" {yylval.fileline = CRELINE(); return yVL_PARALLEL_CASE;}
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@ class AstSenTree;
|
||||||
%token<fileline> yVL_FULL_CASE "/*verilator full_case*/"
|
%token<fileline> yVL_FULL_CASE "/*verilator full_case*/"
|
||||||
%token<fileline> yVL_INLINE_MODULE "/*verilator inline_module*/"
|
%token<fileline> yVL_INLINE_MODULE "/*verilator inline_module*/"
|
||||||
%token<fileline> yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/"
|
%token<fileline> yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/"
|
||||||
|
%token<fileline> yVL_NO_INLINE_TASK "/*verilator no_inline_task*/"
|
||||||
%token<fileline> yVL_ONE_COLD "/*verilator one_cold*/"
|
%token<fileline> yVL_ONE_COLD "/*verilator one_cold*/"
|
||||||
%token<fileline> yVL_ONE_HOT "/*verilator one_hot*/"
|
%token<fileline> yVL_ONE_HOT "/*verilator one_hot*/"
|
||||||
%token<fileline> yVL_PARALLEL_CASE "/*verilator parallel_case*/"
|
%token<fileline> yVL_PARALLEL_CASE "/*verilator parallel_case*/"
|
||||||
|
|
@ -730,6 +731,7 @@ funcVarList: funcVar { $$ = $1; }
|
||||||
funcVar: ioDecl { $$ = $1; }
|
funcVar: ioDecl { $$ = $1; }
|
||||||
| varDecl { $$ = $1; }
|
| varDecl { $$ = $1; }
|
||||||
| yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); }
|
| yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); }
|
||||||
|
| yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); }
|
||||||
;
|
;
|
||||||
|
|
||||||
constExpr: expr { $$ = $1; }
|
constExpr: expr { $$ = $1; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
[2] crc=0000000000000097 1410
|
||||||
|
[3] crc=000000000000012e 1410
|
||||||
|
[4] crc=000000000000025d 1410
|
||||||
|
[5] crc=00000000000004ba 1410
|
||||||
|
[6] crc=0000000000000974 1410
|
||||||
|
[7] crc=00000000000012e9 1410
|
||||||
|
[8] crc=00000000000025d3 1410
|
||||||
|
[9] crc=0000000000004ba7 1410
|
||||||
|
[10] crc=000000000000974e 1410
|
||||||
|
[11] crc=0000000000012e9d 1410
|
||||||
|
[12] crc=0000000000025d3a 1410
|
||||||
|
[13] crc=000000000004ba74 1410
|
||||||
|
[14] crc=00000000000974e9 1410
|
||||||
|
[15] crc=000000000012e9d3 1410
|
||||||
|
[16] crc=000000000025d3a7 1410
|
||||||
|
[17] crc=00000000004ba74e 1410
|
||||||
|
[18] crc=0000000000974e9d 1410
|
||||||
|
[19] crc=00000000012e9d3a 1410
|
||||||
|
[20] crc=00000000025d3a74 1410
|
||||||
|
[21] crc=0000000004ba74e9 1410
|
||||||
|
[22] crc=000000000974e9d3 1304a:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002031303039;17 1304b:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002031303039203233 1304c:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020313030392032332031333033;4 1304d:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002031303039203233203133303320313338 1304e:203130303920323320313330332031333820202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020 1304: 1009 23 1303 138
|
||||||
|
[23] crc=0000000012e9d3a7 1313: 1009 46 1309 1311 143 1312
|
||||||
|
[24] crc=0000000025d3a74e 1129: 1009 172 407 175 408 409 410 1106
|
||||||
|
[25] crc=000000004ba74e9d 1017: 1009 223 1014 880 885 1015 1016 1007
|
||||||
|
[26] crc=00000000974e9d3a 1231: 1229 967 1230 718
|
||||||
|
[27] crc=000000012e9d3a74 1410
|
||||||
|
[28] crc=000000025d3a74e9 1370: 1009 58 1369 19
|
||||||
|
[29] crc=00000004ba74e9d3 1036: 1009 194 1033 1034 1008 1035 880
|
||||||
|
[30] crc=0000000974e9d3a7 1409:i
|
||||||
|
[31] crc=00000012e9d3a74e 1321: 1009 29 1320 137 144 141 138 148
|
||||||
|
[32] crc=00000025d3a74e9d 1383:§
|
||||||
|
[33] crc=0000004ba74e9d3a 1021: 1009 216 1018 882 884 1019 1020 1007
|
||||||
|
[34] crc=000000974e9d3a74 1017: 1009 197 1014 882 883 1015 1016 1008
|
||||||
|
[35] crc=0000012e9d3a74e9 1231: 1228 979 1230 713
|
||||||
|
[36] crc=0000025d3a74e9d3 1013: 1009 194 1011 1006 1008 1012 880
|
||||||
|
[37] crc=000004ba74e9d3a7 1409:i
|
||||||
|
[38] crc=00000974e9d3a74e 1321: 1009 29 1320 137 144 141 138 148
|
||||||
|
[39] crc=000012e9d3a74e9d 1383:§
|
||||||
|
[40] crc=000025d3a74e9d3a 1021: 1009 216 1018 882 884 1019 1020 1007
|
||||||
|
[41] crc=00004ba74e9d3a74 1017: 1009 197 1014 882 883 1015 1016 1008
|
||||||
|
[42] crc=0000974e9d3a74e9 1231: 1228 979 1230 713
|
||||||
|
[43] crc=00012e9d3a74e9d3 1013: 1009 194 1011 1006 1008 1012 880
|
||||||
|
[44] crc=00025d3a74e9d3a7 1409:i
|
||||||
|
[45] crc=0004ba74e9d3a74e 1321: 1009 29 1320 137 144 141 138 148
|
||||||
|
[46] crc=000974e9d3a74e9d 1383:§
|
||||||
|
[47] crc=0012e9d3a74e9d3a 1021: 1009 216 1018 882 884 1019 1020 1007
|
||||||
|
[48] crc=0025d3a74e9d3a74 1017: 1009 197 1014 882 883 1015 1016 1008
|
||||||
|
[49] crc=004ba74e9d3a74e9 1231: 1228 979 1230 713
|
||||||
|
[50] crc=00974e9d3a74e9d3 1013: 1009 194 1011 1006 1008 1012 880
|
||||||
|
[51] crc=012e9d3a74e9d3a7 1409:i
|
||||||
|
[52] crc=025d3a74e9d3a74e 1321: 1009 29 1320 137 144 141 138 148
|
||||||
|
[53] crc=04ba74e9d3a74e9d 1383:§
|
||||||
|
[54] crc=0974e9d3a74e9d3a 1021: 1009 216 1018 882 884 1019 1020 1007
|
||||||
|
[55] crc=12e9d3a74e9d3a74 1017: 1009 197 1014 882 883 1015 1016 1008
|
||||||
|
[56] crc=25d3a74e9d3a74e9 1231: 1228 979 1230 713
|
||||||
|
[57] crc=4ba74e9d3a74e9d3 1013: 1009 194 1011 1006 1008 1012 880
|
||||||
|
[58] crc=974e9d3a74e9d3a7 1409:i
|
||||||
|
[59] crc=2e9d3a74e9d3a74f 1321: 1009 29 1320 137 144 141 138 149
|
||||||
|
[60] crc=5d3a74e9d3a74e9e 1383:§
|
||||||
|
[61] crc=ba74e9d3a74e9d3d 1021: 1009 216 1018 882 884 1019 1020 1007
|
||||||
|
[62] crc=74e9d3a74e9d3a7b 1017: 1009 197 1014 882 883 1015 1016 1008
|
||||||
|
[63] crc=e9d3a74e9d3a74f7 1231: 1228 979 1230 713
|
||||||
|
[64] crc=d3a74e9d3a74e9ef 1013: 1009 194 1011 1006 1008 1012 880
|
||||||
|
[65] crc=a74e9d3a74e9d3df 1409:i
|
||||||
|
[66] crc=4e9d3a74e9d3a7bf 1321: 1009 29 1320 137 144 141 145 149
|
||||||
|
[67] crc=9d3a74e9d3a74f7e 1383:§
|
||||||
|
[68] crc=3a74e9d3a74e9efc 1021: 1009 216 1018 882 884 1019 1020 1007
|
||||||
|
[69] crc=74e9d3a74e9d3df9 1017: 1009 197 1014 882 883 1015 1016 1008
|
||||||
|
[70] crc=e9d3a74e9d3a7bf3 1231: 1228 979 1230 713
|
||||||
|
[71] crc=d3a74e9d3a74f7e6 1013: 1009 194 1011 1006 1008 1012 880
|
||||||
|
[72] crc=a74e9d3a74e9efcc 1409:i
|
||||||
|
[73] crc=4e9d3a74e9d3df98 1321: 1009 29 1320 137 147 149 143 142
|
||||||
|
[74] crc=9d3a74e9d3a7bf30 1383:§
|
||||||
|
[75] crc=3a74e9d3a74f7e61 1021: 1009 216 1018 882 885 1019 1020 1007
|
||||||
|
[76] crc=74e9d3a74e9efcc3 1017: 1009 197 1014 882 884 1015 1016 1008
|
||||||
|
[77] crc=e9d3a74e9d3df987 1231: 1228 982 1230 713
|
||||||
|
[78] crc=d3a74e9d3a7bf30f 1013: 1009 194 1011 1006 1008 1012 881 885
|
||||||
|
[79] crc=a74e9d3a74f7e61f 1409:w
|
||||||
|
[80] crc=4e9d3a74e9efcc3f 1321: 1009 30 1320 149 146 146 137 149
|
||||||
|
[81] crc=9d3a74e9d3df987e 1383:ß
|
||||||
|
[82] crc=3a74e9d3a7bf30fc 1021: 1009 225 1018 882 885 1019 1020 1008
|
||||||
|
[83] crc=74e9d3a74f7e61f9 1017: 1009 218 1014 882 884 1015 1016 1008
|
||||||
|
[84] crc=e9d3a74e9efcc3f3 1231: 1228 981 1230 708
|
||||||
|
[85] crc=d3a74e9d3df987e6 1013: 1009 232 1011 1005 1008 1012 881 883
|
||||||
|
[86] crc=a74e9d3a7bf30fcc 1409:s
|
||||||
|
[87] crc=4e9d3a74f7e61f98 1262: 1009 1006 1258 846 1259 1006 1260 833 1261
|
||||||
|
[88] crc=9d3a74e9efcc3f30 1321: 1009 124 1320 146 137 149 137 134
|
||||||
|
[89] crc=3a74e9d3df987e61 1383:˜
|
||||||
|
[90] crc=74e9d3a7bf30fcc3 1036: 1009 215 1033 1034 1008 1035 879
|
||||||
|
|
@ -16,12 +16,12 @@ module t (/*AUTOARG*/
|
||||||
reg [63:0] crc;
|
reg [63:0] crc;
|
||||||
`verilator_file_descriptor fd;
|
`verilator_file_descriptor fd;
|
||||||
|
|
||||||
t_case_write_tasks tasks ();
|
t_case_write1_tasks tasks ();
|
||||||
|
|
||||||
integer cyc; initial cyc=0;
|
integer cyc; initial cyc=0;
|
||||||
|
|
||||||
always @ (posedge clk) begin
|
always @ (posedge clk) begin
|
||||||
$fwrite(fd, "[%03d] ", cyc);
|
$fwrite(fd, "[%0d] crc=%x ", cyc, crc);
|
||||||
tasks.big_case(fd, crc[31:0]);
|
tasks.big_case(fd, crc[31:0]);
|
||||||
$fwrite(fd, "\n");
|
$fwrite(fd, "\n");
|
||||||
end
|
end
|
||||||
|
|
@ -32,8 +32,8 @@ module t (/*AUTOARG*/
|
||||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||||
if (cyc==1) begin
|
if (cyc==1) begin
|
||||||
crc <= 64'h00000000_00000097;
|
crc <= 64'h00000000_00000097;
|
||||||
$write("Open obj_dir/t_case_write_logger.log\n");
|
$write("Open obj_dir/t_case_write1_logger.log\n");
|
||||||
fd = $fopen("obj_dir/t_case_write_logger.log", "w");
|
fd = $fopen("obj_dir/t_case_write1_logger.log", "w");
|
||||||
end
|
end
|
||||||
if (cyc==90) begin
|
if (cyc==90) begin
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
`include "verilated.v"
|
`include "verilated.v"
|
||||||
|
|
||||||
module t_case_write_tasks ();
|
module t_case_write1_tasks ();
|
||||||
|
|
||||||
// verilator lint_off WIDTH
|
// verilator lint_off WIDTH
|
||||||
// verilator lint_off CASEINCOMPLETE
|
// verilator lint_off CASEINCOMPLETE
|
||||||
|
|
@ -15,6 +15,7 @@ module t_case_write_tasks ();
|
||||||
task ozonerab;
|
task ozonerab;
|
||||||
input [6:0] rab;
|
input [6:0] rab;
|
||||||
inout [STRLEN*8:1] foobar;
|
inout [STRLEN*8:1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (rab[6:0])
|
case (rab[6:0])
|
||||||
7'h00 : foobar = {foobar, " 0"};
|
7'h00 : foobar = {foobar, " 0"};
|
||||||
|
|
@ -153,6 +154,7 @@ module t_case_write_tasks ();
|
||||||
task ozonerb;
|
task ozonerb;
|
||||||
input [5:0] rb;
|
input [5:0] rb;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (rb[5:0])
|
case (rb[5:0])
|
||||||
6'h10,
|
6'h10,
|
||||||
|
|
@ -168,6 +170,7 @@ module t_case_write_tasks ();
|
||||||
input [1:0] foo;
|
input [1:0] foo;
|
||||||
input [15:0] im16;
|
input [15:0] im16;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo)
|
case (foo)
|
||||||
2'h0 :
|
2'h0 :
|
||||||
|
|
@ -213,6 +216,7 @@ module t_case_write_tasks ();
|
||||||
task skyway;
|
task skyway;
|
||||||
input [ 3:0] hex;
|
input [ 3:0] hex;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (hex)
|
case (hex)
|
||||||
4'h0 : foobar = {foobar, " 134"};
|
4'h0 : foobar = {foobar, " 134"};
|
||||||
|
|
@ -238,6 +242,7 @@ module t_case_write_tasks ();
|
||||||
task ozonesr;
|
task ozonesr;
|
||||||
input [ 15:0] foo;
|
input [ 15:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[11: 9])
|
case (foo[11: 9])
|
||||||
3'h0 : foobar = {foobar, " 158"};
|
3'h0 : foobar = {foobar, " 158"};
|
||||||
|
|
@ -255,6 +260,7 @@ module t_case_write_tasks ();
|
||||||
task ozonejk;
|
task ozonejk;
|
||||||
input k;
|
input k;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
if (k)
|
if (k)
|
||||||
foobar = {foobar, " 166"};
|
foobar = {foobar, " 166"};
|
||||||
|
|
@ -266,6 +272,7 @@ module t_case_write_tasks ();
|
||||||
task ozoneae;
|
task ozoneae;
|
||||||
input [ 2:0] ae;
|
input [ 2:0] ae;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (ae)
|
case (ae)
|
||||||
3'b000 : foobar = {foobar, " 168"};
|
3'b000 : foobar = {foobar, " 168"};
|
||||||
|
|
@ -283,6 +290,7 @@ module t_case_write_tasks ();
|
||||||
task ozoneaee;
|
task ozoneaee;
|
||||||
input [ 2:0] aee;
|
input [ 2:0] aee;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (aee)
|
case (aee)
|
||||||
3'b001,
|
3'b001,
|
||||||
|
|
@ -300,6 +308,7 @@ module t_case_write_tasks ();
|
||||||
task ozoneape;
|
task ozoneape;
|
||||||
input [ 2:0] ape;
|
input [ 2:0] ape;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (ape)
|
case (ape)
|
||||||
3'b001,
|
3'b001,
|
||||||
|
|
@ -317,6 +326,7 @@ module t_case_write_tasks ();
|
||||||
task ozonef1;
|
task ozonef1;
|
||||||
input [ 31:0] foo;
|
input [ 31:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[24:21])
|
case (foo[24:21])
|
||||||
4'h0 :
|
4'h0 :
|
||||||
|
|
@ -416,6 +426,7 @@ module t_case_write_tasks ();
|
||||||
task ozonef1e;
|
task ozonef1e;
|
||||||
input [ 31:0] foo;
|
input [ 31:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[27:21])
|
case (foo[27:21])
|
||||||
7'h00:
|
7'h00:
|
||||||
|
|
@ -1548,6 +1559,7 @@ module t_case_write_tasks ();
|
||||||
task ozonef2;
|
task ozonef2;
|
||||||
input [ 31:0] foo;
|
input [ 31:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[24:21])
|
case (foo[24:21])
|
||||||
4'h0 :
|
4'h0 :
|
||||||
|
|
@ -1665,6 +1677,7 @@ module t_case_write_tasks ();
|
||||||
task ozonef2e;
|
task ozonef2e;
|
||||||
input [ 31:0] foo;
|
input [ 31:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
casez (foo[25:21])
|
casez (foo[25:21])
|
||||||
5'h00 :
|
5'h00 :
|
||||||
|
|
@ -1864,6 +1877,7 @@ module t_case_write_tasks ();
|
||||||
task ozonef3e;
|
task ozonef3e;
|
||||||
input [ 31:0] foo;
|
input [ 31:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[25:21])
|
case (foo[25:21])
|
||||||
5'h00,
|
5'h00,
|
||||||
|
|
@ -1982,6 +1996,7 @@ module t_case_write_tasks ();
|
||||||
task ozonef3e_te;
|
task ozonef3e_te;
|
||||||
input [ 2:0] te;
|
input [ 2:0] te;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (te)
|
case (te)
|
||||||
3'b100 : foobar = {foobar, " 823"};
|
3'b100 : foobar = {foobar, " 823"};
|
||||||
|
|
@ -1994,6 +2009,7 @@ module t_case_write_tasks ();
|
||||||
task ozonearm;
|
task ozonearm;
|
||||||
input [ 2:0] ate;
|
input [ 2:0] ate;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (ate)
|
case (ate)
|
||||||
3'b000 : foobar = {foobar, " 827"};
|
3'b000 : foobar = {foobar, " 827"};
|
||||||
|
|
@ -2010,6 +2026,7 @@ module t_case_write_tasks ();
|
||||||
task ozonebmuop;
|
task ozonebmuop;
|
||||||
input [ 4:0] f4;
|
input [ 4:0] f4;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (f4[ 4:0])
|
case (f4[ 4:0])
|
||||||
5'h00,
|
5'h00,
|
||||||
|
|
@ -2052,6 +2069,7 @@ module t_case_write_tasks ();
|
||||||
input [ 31:0] foo;
|
input [ 31:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
reg nacho;
|
reg nacho;
|
||||||
|
// verilator no_inline_task
|
||||||
begin : f3_body
|
begin : f3_body
|
||||||
nacho = 1'b0;
|
nacho = 1'b0;
|
||||||
case (foo[24:21])
|
case (foo[24:21])
|
||||||
|
|
@ -2145,6 +2163,7 @@ module t_case_write_tasks ();
|
||||||
task ozonerx;
|
task ozonerx;
|
||||||
input [ 31:0] foo;
|
input [ 31:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[19:18])
|
case (foo[19:18])
|
||||||
2'h0 : foobar = {foobar, " 879"};
|
2'h0 : foobar = {foobar, " 879"};
|
||||||
|
|
@ -2162,6 +2181,7 @@ module t_case_write_tasks ();
|
||||||
task ozonerme;
|
task ozonerme;
|
||||||
input [ 2:0] rme;
|
input [ 2:0] rme;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (rme)
|
case (rme)
|
||||||
3'h0 : foobar = {foobar, " 886"};
|
3'h0 : foobar = {foobar, " 886"};
|
||||||
|
|
@ -2179,6 +2199,7 @@ module t_case_write_tasks ();
|
||||||
input [5:0] ye;
|
input [5:0] ye;
|
||||||
input l;
|
input l;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
foobar = {foobar, " 894"};
|
foobar = {foobar, " 894"};
|
||||||
ozonerme(ye[5:3],foobar);
|
ozonerme(ye[5:3],foobar);
|
||||||
|
|
@ -2198,6 +2219,7 @@ module t_case_write_tasks ();
|
||||||
input [5:0] ye;
|
input [5:0] ye;
|
||||||
input l;
|
input l;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
foobar = {foobar, " 899"};
|
foobar = {foobar, " 899"};
|
||||||
ozonerme(ye[5:3],foobar);
|
ozonerme(ye[5:3],foobar);
|
||||||
|
|
@ -2207,6 +2229,7 @@ module t_case_write_tasks ();
|
||||||
task ozonef1e_h;
|
task ozonef1e_h;
|
||||||
input [ 2:0] e;
|
input [ 2:0] e;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
if (e[ 2:0] <= 3'h4)
|
if (e[ 2:0] <= 3'h4)
|
||||||
foobar = {foobar, " 900"};
|
foobar = {foobar, " 900"};
|
||||||
|
|
@ -2216,6 +2239,7 @@ module t_case_write_tasks ();
|
||||||
input [5:0] ye;
|
input [5:0] ye;
|
||||||
input l;
|
input l;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case ({ye[ 2:0], l})
|
case ({ye[ 2:0], l})
|
||||||
4'h2,
|
4'h2,
|
||||||
|
|
@ -2238,6 +2262,7 @@ module t_case_write_tasks ();
|
||||||
input [ 2:0] e;
|
input [ 2:0] e;
|
||||||
input l;
|
input l;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case ({e[ 2:0], l})
|
case ({e[ 2:0], l})
|
||||||
4'h0,
|
4'h0,
|
||||||
|
|
@ -2256,6 +2281,7 @@ module t_case_write_tasks ();
|
||||||
task ozonexe;
|
task ozonexe;
|
||||||
input [ 3:0] xe;
|
input [ 3:0] xe;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (xe[3])
|
case (xe[3])
|
||||||
1'b0 : foobar = {foobar, " 908"};
|
1'b0 : foobar = {foobar, " 908"};
|
||||||
|
|
@ -2275,6 +2301,7 @@ module t_case_write_tasks ();
|
||||||
task ozonerp;
|
task ozonerp;
|
||||||
input [ 2:0] rp;
|
input [ 2:0] rp;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (rp)
|
case (rp)
|
||||||
3'h0 : foobar = {foobar, " 914"};
|
3'h0 : foobar = {foobar, " 914"};
|
||||||
|
|
@ -2291,6 +2318,7 @@ module t_case_write_tasks ();
|
||||||
task ozonery;
|
task ozonery;
|
||||||
input [ 3:0] ry;
|
input [ 3:0] ry;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (ry)
|
case (ry)
|
||||||
4'h0 : foobar = {foobar, " 922"};
|
4'h0 : foobar = {foobar, " 922"};
|
||||||
|
|
@ -2315,6 +2343,7 @@ module t_case_write_tasks ();
|
||||||
task ozonearx;
|
task ozonearx;
|
||||||
input [ 15:0] foo;
|
input [ 15:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[1:0])
|
case (foo[1:0])
|
||||||
2'h0 : foobar = {foobar, " 938"};
|
2'h0 : foobar = {foobar, " 938"};
|
||||||
|
|
@ -2327,6 +2356,7 @@ module t_case_write_tasks ();
|
||||||
task ozonef3f4imop;
|
task ozonef3f4imop;
|
||||||
input [ 4:0] f3f4iml;
|
input [ 4:0] f3f4iml;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
casez (f3f4iml)
|
casez (f3f4iml)
|
||||||
5'b000??: foobar = {foobar, " 942"};
|
5'b000??: foobar = {foobar, " 942"};
|
||||||
|
|
@ -2346,6 +2376,7 @@ module t_case_write_tasks ();
|
||||||
task ozonecon;
|
task ozonecon;
|
||||||
input [ 4:0] con;
|
input [ 4:0] con;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (con)
|
case (con)
|
||||||
5'h00 : foobar = {foobar, " 953"};
|
5'h00 : foobar = {foobar, " 953"};
|
||||||
|
|
@ -2386,6 +2417,7 @@ module t_case_write_tasks ();
|
||||||
task ozonedr;
|
task ozonedr;
|
||||||
input [ 15:0] foo;
|
input [ 15:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[ 9: 6])
|
case (foo[ 9: 6])
|
||||||
4'h0 : foobar = {foobar, " 985"};
|
4'h0 : foobar = {foobar, " 985"};
|
||||||
|
|
@ -2410,6 +2442,7 @@ module t_case_write_tasks ();
|
||||||
task ozoneshift;
|
task ozoneshift;
|
||||||
input [ 15:0] foo;
|
input [ 15:0] foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo[ 4: 3])
|
case (foo[ 4: 3])
|
||||||
2'h0 : foobar = {foobar, " 1001"};
|
2'h0 : foobar = {foobar, " 1001"};
|
||||||
|
|
@ -2422,6 +2455,7 @@ module t_case_write_tasks ();
|
||||||
task ozoneacc;
|
task ozoneacc;
|
||||||
input foo;
|
input foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo)
|
case (foo)
|
||||||
2'h0 : foobar = {foobar, " 1005"};
|
2'h0 : foobar = {foobar, " 1005"};
|
||||||
|
|
@ -2432,6 +2466,7 @@ module t_case_write_tasks ();
|
||||||
task ozonehl;
|
task ozonehl;
|
||||||
input foo;
|
input foo;
|
||||||
inout [STRLEN*8: 1] foobar;
|
inout [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
case (foo)
|
case (foo)
|
||||||
2'h0 : foobar = {foobar, " 1007"};
|
2'h0 : foobar = {foobar, " 1007"};
|
||||||
|
|
@ -2444,6 +2479,7 @@ module t_case_write_tasks ();
|
||||||
reg [ 7:0] temp;
|
reg [ 7:0] temp;
|
||||||
integer i;
|
integer i;
|
||||||
reg nacho;
|
reg nacho;
|
||||||
|
// verilator no_inline_task
|
||||||
begin : justify_block
|
begin : justify_block
|
||||||
nacho = 1'b0;
|
nacho = 1'b0;
|
||||||
for (i=STRLEN-1; i>1; i=i-1)
|
for (i=STRLEN-1; i>1; i=i-1)
|
||||||
|
|
@ -2468,6 +2504,7 @@ module t_case_write_tasks ();
|
||||||
`endif
|
`endif
|
||||||
input [ 31:0] foo;
|
input [ 31:0] foo;
|
||||||
reg [STRLEN*8: 1] foobar;
|
reg [STRLEN*8: 1] foobar;
|
||||||
|
// verilator no_inline_task
|
||||||
begin
|
begin
|
||||||
foobar = " 1009";
|
foobar = " 1009";
|
||||||
if (&foo === 1'bx)
|
if (&foo === 1'bx)
|
||||||
|
|
@ -3378,10 +3415,15 @@ module t_case_write_tasks ();
|
||||||
end
|
end
|
||||||
17'b00_0010_?_????_??_???? :
|
17'b00_0010_?_????_??_???? :
|
||||||
begin
|
begin
|
||||||
|
$fwrite(fd, " 1304a:%x;%x", foobar, foo[25:20]);
|
||||||
ozonerab({1'b0, foo[25:20]}, foobar);
|
ozonerab({1'b0, foo[25:20]}, foobar);
|
||||||
|
$fwrite(fd, " 1304b:%x", foobar);
|
||||||
foobar = {foobar, " 1303"};
|
foobar = {foobar, " 1303"};
|
||||||
|
$fwrite(fd, " 1304c:%x;%x", foobar, foo[19:16]);
|
||||||
skyway(foo[19:16], foobar);
|
skyway(foo[19:16], foobar);
|
||||||
|
$fwrite(fd, " 1304d:%x", foobar);
|
||||||
dude(foobar);
|
dude(foobar);
|
||||||
|
$fwrite(fd, " 1304e:%x", foobar);
|
||||||
$fwrite(fd, " 1304:%s", foobar);
|
$fwrite(fd, " 1304:%s", foobar);
|
||||||
end
|
end
|
||||||
17'b00_01??_?_????_??_???? :
|
17'b00_01??_?_????_??_???? :
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
[2] crc=0000000000000097 1009 1410
|
||||||
|
[3] crc=000000000000012e 1009 1410
|
||||||
|
[4] crc=000000000000025d 1009 1410
|
||||||
|
[5] crc=00000000000004ba 1009 1410
|
||||||
|
[6] crc=0000000000000974 1009 1410
|
||||||
|
[7] crc=00000000000012e9 1009 1410
|
||||||
|
[8] crc=00000000000025d3 1009 1410
|
||||||
|
[9] crc=0000000000004ba7 1009 1410
|
||||||
|
[10] crc=000000000000974e 1009 1410
|
||||||
|
[11] crc=0000000000012e9d 1009 1410
|
||||||
|
[12] crc=0000000000025d3a 1009 1410
|
||||||
|
[13] crc=000000000004ba74 1009 1410
|
||||||
|
[14] crc=00000000000974e9 1009 1410
|
||||||
|
[15] crc=000000000012e9d3 1009 1410
|
||||||
|
[16] crc=000000000025d3a7 1009 1410
|
||||||
|
[17] crc=00000000004ba74e 1009 1410
|
||||||
|
[18] crc=0000000000974e9d 1009 1410
|
||||||
|
[19] crc=00000000012e9d3a 1009 1410
|
||||||
|
[20] crc=00000000025d3a74 1009 1410
|
||||||
|
[21] crc=0000000004ba74e9 1009 1410
|
||||||
|
[22] crc=000000000974e9d3 1009 23 1303 138 dude 1304
|
||||||
|
[23] crc=0000000012e9d3a7 1009 46 1309 1311 143 1312 dude 1313
|
||||||
|
[24] crc=0000000025d3a74e 1009 172 407 175 408 409 410 1106 dude 1129
|
||||||
|
[25] crc=000000004ba74e9d 1009 223 1014 880 885 1015 1016:0 1007 dude 1017
|
||||||
|
[26] crc=00000000974e9d3a 1009 1229 967 1230 718 dude 1231
|
||||||
|
[27] crc=000000012e9d3a74 1009 1410
|
||||||
|
[28] crc=000000025d3a74e9 1009 58 1369 19 dude 1370
|
||||||
|
[29] crc=00000004ba74e9d3 1009 194 1033 1034 1008 1035 880 dude 1036
|
||||||
|
[30] crc=0000000974e9d3a7 1009 1409:69
|
||||||
|
[31] crc=00000012e9d3a74e 1009 29 1320 137 144 141 138 148 dude 1321
|
||||||
|
[32] crc=00000025d3a74e9d 1009 1383:3a7
|
||||||
|
[33] crc=0000004ba74e9d3a 1009 216 1018 882 884 1019 1020 1007 dude 1021
|
||||||
|
[34] crc=000000974e9d3a74 1009 197 1014 882 883 1015 1016:1 1008 dude 1017
|
||||||
|
[35] crc=0000012e9d3a74e9 1009 1228 979 1230 713 dude 1231
|
||||||
|
[36] crc=0000025d3a74e9d3 1009 194 1011 1006 1008 1012 880 dude 1013
|
||||||
|
[37] crc=000004ba74e9d3a7 1009 1409:69
|
||||||
|
[38] crc=00000974e9d3a74e 1009 29 1320 137 144 141 138 148 dude 1321
|
||||||
|
[39] crc=000012e9d3a74e9d 1009 1383:3a7
|
||||||
|
[40] crc=000025d3a74e9d3a 1009 216 1018 882 884 1019 1020 1007 dude 1021
|
||||||
|
[41] crc=00004ba74e9d3a74 1009 197 1014 882 883 1015 1016:1 1008 dude 1017
|
||||||
|
[42] crc=0000974e9d3a74e9 1009 1228 979 1230 713 dude 1231
|
||||||
|
[43] crc=00012e9d3a74e9d3 1009 194 1011 1006 1008 1012 880 dude 1013
|
||||||
|
[44] crc=00025d3a74e9d3a7 1009 1409:69
|
||||||
|
[45] crc=0004ba74e9d3a74e 1009 29 1320 137 144 141 138 148 dude 1321
|
||||||
|
[46] crc=000974e9d3a74e9d 1009 1383:3a7
|
||||||
|
[47] crc=0012e9d3a74e9d3a 1009 216 1018 882 884 1019 1020 1007 dude 1021
|
||||||
|
[48] crc=0025d3a74e9d3a74 1009 197 1014 882 883 1015 1016:1 1008 dude 1017
|
||||||
|
[49] crc=004ba74e9d3a74e9 1009 1228 979 1230 713 dude 1231
|
||||||
|
[50] crc=00974e9d3a74e9d3 1009 194 1011 1006 1008 1012 880 dude 1013
|
||||||
|
[51] crc=012e9d3a74e9d3a7 1009 1409:69
|
||||||
|
[52] crc=025d3a74e9d3a74e 1009 29 1320 137 144 141 138 148 dude 1321
|
||||||
|
[53] crc=04ba74e9d3a74e9d 1009 1383:3a7
|
||||||
|
[54] crc=0974e9d3a74e9d3a 1009 216 1018 882 884 1019 1020 1007 dude 1021
|
||||||
|
[55] crc=12e9d3a74e9d3a74 1009 197 1014 882 883 1015 1016:1 1008 dude 1017
|
||||||
|
[56] crc=25d3a74e9d3a74e9 1009 1228 979 1230 713 dude 1231
|
||||||
|
[57] crc=4ba74e9d3a74e9d3 1009 194 1011 1006 1008 1012 880 dude 1013
|
||||||
|
[58] crc=974e9d3a74e9d3a7 1009 1409:69
|
||||||
|
[59] crc=2e9d3a74e9d3a74f 1009 29 1320 137 144 141 138 149 dude 1321
|
||||||
|
[60] crc=5d3a74e9d3a74e9e 1009 1383:3a7
|
||||||
|
[61] crc=ba74e9d3a74e9d3d 1009 216 1018 882 884 1019 1020 1007 dude 1021
|
||||||
|
[62] crc=74e9d3a74e9d3a7b 1009 197 1014 882 883 1015 1016:1 1008 dude 1017
|
||||||
|
[63] crc=e9d3a74e9d3a74f7 1009 1228 979 1230 713 dude 1231
|
||||||
|
[64] crc=d3a74e9d3a74e9ef 1009 194 1011 1006 1008 1012 880 dude 1013
|
||||||
|
[65] crc=a74e9d3a74e9d3df 1009 1409:69
|
||||||
|
[66] crc=4e9d3a74e9d3a7bf 1009 29 1320 137 144 141 145 149 dude 1321
|
||||||
|
[67] crc=9d3a74e9d3a74f7e 1009 1383:3a7
|
||||||
|
[68] crc=3a74e9d3a74e9efc 1009 216 1018 882 884 1019 1020 1007 dude 1021
|
||||||
|
[69] crc=74e9d3a74e9d3df9 1009 197 1014 882 883 1015 1016:1 1008 dude 1017
|
||||||
|
[70] crc=e9d3a74e9d3a7bf3 1009 1228 979 1230 713 dude 1231
|
||||||
|
[71] crc=d3a74e9d3a74f7e6 1009 194 1011 1006 1008 1012 880 dude 1013
|
||||||
|
[72] crc=a74e9d3a74e9efcc 1009 1409:69
|
||||||
|
[73] crc=4e9d3a74e9d3df98 1009 29 1320 137 147 149 143 142 dude 1321
|
||||||
|
[74] crc=9d3a74e9d3a7bf30 1009 1383:3a7
|
||||||
|
[75] crc=3a74e9d3a74f7e61 1009 216 1018 882 885 1019 1020 1007 dude 1021
|
||||||
|
[76] crc=74e9d3a74e9efcc3 1009 197 1014 882 884 1015 1016:1 1008 dude 1017
|
||||||
|
[77] crc=e9d3a74e9d3df987 1009 1228 982 1230 713 dude 1231
|
||||||
|
[78] crc=d3a74e9d3a7bf30f 1009 194 1011 1006 1008 1012 881 885 dude 1013
|
||||||
|
[79] crc=a74e9d3a74f7e61f 1009 1409:77
|
||||||
|
[80] crc=4e9d3a74e9efcc3f 1009 30 1320 149 146 146 137 149 dude 1321
|
||||||
|
[81] crc=9d3a74e9d3df987e 1009 1383:3df
|
||||||
|
[82] crc=3a74e9d3a7bf30fc 1009 225 1018 882 885 1019 1020 1008 dude 1021
|
||||||
|
[83] crc=74e9d3a74f7e61f9 1009 218 1014 882 884 1015 1016:1 1008 dude 1017
|
||||||
|
[84] crc=e9d3a74e9efcc3f3 1009 1228 981 1230 708 dude 1231
|
||||||
|
[85] crc=d3a74e9d3df987e6 1009 232 1011 1005 1008 1012 881 883 dude 1013
|
||||||
|
[86] crc=a74e9d3a7bf30fcc 1009 1409:73
|
||||||
|
[87] crc=4e9d3a74f7e61f98 1009 1006 1258 846 1259 1006 1260 833 1261 dude 1262
|
||||||
|
[88] crc=9d3a74e9efcc3f30 1009 124 1320 146 137 149 137 134 dude 1321
|
||||||
|
[89] crc=3a74e9d3df987e61 1009 1383:f98
|
||||||
|
[90] crc=74e9d3a7bf30fcc3 1009 215 1033 1034 1008 1035 879 dude 1036
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||||
|
# $Id$
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# General Public License or the Perl Artistic License.
|
||||||
|
|
||||||
|
$golden_out ||= "t/$Last_Self->{name}.out";
|
||||||
|
|
||||||
|
compile (
|
||||||
|
v_flags2 => [$Last_Self->{v3}?"--stats --O3 -x-assign 0":""],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(files_identical("obj_dir/$Last_Self->{name}_logger.log", $golden_out));
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// $Id$
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2006 by Wilson Snyder.
|
||||||
|
|
||||||
|
`include "verilated.v"
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/
|
||||||
|
// Inputs
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
|
||||||
|
reg [63:0] crc;
|
||||||
|
`verilator_file_descriptor fd;
|
||||||
|
|
||||||
|
t_case_write2_tasks tasks ();
|
||||||
|
|
||||||
|
integer cyc; initial cyc=0;
|
||||||
|
|
||||||
|
always @ (posedge clk) begin
|
||||||
|
$fwrite(fd, "[%0d] crc=%x ", cyc, crc);
|
||||||
|
tasks.big_case(fd, crc[31:0]);
|
||||||
|
$fwrite(fd, "\n");
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clk) begin
|
||||||
|
//$write("[%0t] cyc==%0d crc=%x\n",$time, cyc, crc);
|
||||||
|
cyc <= cyc + 1;
|
||||||
|
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||||
|
if (cyc==1) begin
|
||||||
|
crc <= 64'h00000000_00000097;
|
||||||
|
$write("Open obj_dir/t_case_write2_logger.log\n");
|
||||||
|
fd = $fopen("obj_dir/t_case_write2_logger.log", "w");
|
||||||
|
end
|
||||||
|
if (cyc==90) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -27,6 +27,10 @@ module t;
|
||||||
flipupperbit(global,4'd12);
|
flipupperbit(global,4'd12);
|
||||||
if (global !== 32'h10100001) $stop;
|
if (global !== 32'h10100001) $stop;
|
||||||
|
|
||||||
|
if (nil_func(32'h12,32'h12) != 32'h24) $stop;
|
||||||
|
nil_task(32'h012,32'h112,global);
|
||||||
|
if (global !== 32'h124) $stop;
|
||||||
|
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
@ -85,4 +89,19 @@ module t;
|
||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
|
task nil_task;
|
||||||
|
input [31:0] a;
|
||||||
|
input [31:0] b;
|
||||||
|
output [31:0] q;
|
||||||
|
// verilator no_inline_task
|
||||||
|
q = nil_func(a, b);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
function [31:0] nil_func;
|
||||||
|
input [31:0] fa;
|
||||||
|
input [31:0] fb;
|
||||||
|
// verilator no_inline_task
|
||||||
|
nil_func = fa + fb;
|
||||||
|
endfunction
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue