mirror of
https://github.com/verilator/verilator.git
synced 2025-04-05 04:02:37 +00:00
Support wide public task outputs.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@810 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
e471a34323
commit
318a6e348c
2
Changes
2
Changes
@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.62**
|
||||
|
||||
**** Public functions now allow > 64 bit arguments.
|
||||
|
||||
**** Don't core dump on errors when not under --debug. [Allan Cochrane]
|
||||
|
||||
**** Remove .vpp intermediate files when not under --debug.
|
||||
|
@ -1088,9 +1088,9 @@ function. Any output arguments will become C++ reference arguments. Any
|
||||
local registers/integers will become function automatic variables on the
|
||||
stack.
|
||||
|
||||
Wide variables over 64 bits cannot be I/O to the module, to avoid exposing
|
||||
complexities; generally the cleanest technique is to pass a word number to
|
||||
the function, and do appropriate bit selection.
|
||||
Wide variables over 64 bits cannot be function returns, to avoid exposing
|
||||
complexities. However, wide variables can be input/outputs; they will be
|
||||
passed as references to an array of 32 bit numbers.
|
||||
|
||||
This feature is still somewhat experimental. Generally, only the values of
|
||||
stored state (flops) should be written, as the model will NOT notice
|
||||
|
@ -103,6 +103,18 @@ string AstVar::verilogKwd() const {
|
||||
}
|
||||
|
||||
string AstVar::cType() const {
|
||||
if (widthMin() == 1) {
|
||||
return "bool";
|
||||
} else if (widthMin() <= VL_WORDSIZE) {
|
||||
return "uint32_t";
|
||||
} else if (isScWide()) {
|
||||
return "uint32_t"; // []'s added later
|
||||
} else {
|
||||
return "uint64_t";
|
||||
}
|
||||
}
|
||||
|
||||
string AstVar::scType() const {
|
||||
if (widthMin() == 1) {
|
||||
return "bool";
|
||||
} else if (widthMin() <= VL_WORDSIZE) {
|
||||
|
@ -288,7 +288,8 @@ public:
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
AstVarType varType() const { return m_varType; } // * = Type of variable
|
||||
string cType() const; // Return C type: bool, uint32_t, uint64_t, etc.
|
||||
string cType() const; // Return C type for declaration: bool, uint32_t, uint64_t, etc.
|
||||
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
|
||||
void combineType(AstVarType type);
|
||||
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
|
||||
AstRange* arraysp() const { return op2p()->castRange(); } // op2 = Array(s) of variable
|
||||
|
@ -102,9 +102,16 @@ public:
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (portp->isIO() && !portp->isFuncReturn()) {
|
||||
if (args != "") args+= ", ";
|
||||
args += portp->cType();
|
||||
if (portp->isOutput()) args += "&";
|
||||
args += " "+portp->name();
|
||||
if (portp->isWide()) {
|
||||
if (portp->isInOnly()) args += "const ";
|
||||
args += portp->cType();
|
||||
args += " (& "+portp->name();
|
||||
args += ")["+cvtToStr(portp->widthWords())+"]";
|
||||
} else {
|
||||
args += portp->cType();
|
||||
if (portp->isOutput()) args += "&";
|
||||
args += " "+portp->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -707,7 +714,7 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
else if (nodep->isOutput()) puts("sc_out<");
|
||||
else nodep->v3fatalSrc("Unknown type");
|
||||
|
||||
puts(nodep->cType());
|
||||
puts(nodep->scType());
|
||||
puts(">\t");
|
||||
}
|
||||
puts(nodep->name());
|
||||
|
@ -304,7 +304,7 @@ private:
|
||||
AstVar* portp = NULL;
|
||||
if (NULL!=(portp = nodep->castFunc()->fvarp()->castVar())) {
|
||||
if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var");
|
||||
if (portp->isWide()) nodep->v3error("Unsupported: Public functions/tasks with inputs or outputs > 64 bits wide.");
|
||||
if (portp->isWide()) nodep->v3error("Unsupported: Public functions with return > 64 bits wide. (Make it a output instead.)");
|
||||
portp->unlinkFrBack();
|
||||
rtnvarp = portp;
|
||||
rtnvarp->funcLocal(true);
|
||||
@ -339,11 +339,6 @@ private:
|
||||
portp->unlinkFrBack();
|
||||
portp->funcLocal(true);
|
||||
funcp->addArgsp(portp);
|
||||
if (portp->isWide()) {
|
||||
// As we don't want to export our WData arrays to users,
|
||||
// and casting to sc_bv's is ugly, we'll just...
|
||||
nodep->v3error("Unsupported: Public functions/tasks with inputs or outputs > 64 bits wide.");
|
||||
}
|
||||
} else {
|
||||
// "Normal" variable, mark inside function
|
||||
portp->funcLocal(true);
|
||||
|
@ -103,8 +103,8 @@ module tpub (
|
||||
if (24'h11bca != got_long) $stop;
|
||||
$c("{ uint64_t qq; publicGetQuad(qq); got_quad=qq; }");
|
||||
if (60'haaaa_bbbb_cccc != got_quad) $stop;
|
||||
//Unsupported: $c("publicGetWide(got_wide);");
|
||||
//Unsupported: if (72'hac_abca_aaaa_bbbb_1234 != got_wide) $stop;
|
||||
$c("{ WData gw[3]; publicGetWide(gw); VL_ASSIGN_W(72,got_wide,gw); }");
|
||||
if (72'hac_abca_aaaa_bbbb_1234 != got_wide) $stop;
|
||||
//Below doesn't work, because we're calling it inside the loop that sets var_flop
|
||||
// if (12'h321 != var_flop) $stop;
|
||||
end
|
||||
@ -154,7 +154,7 @@ module tpub (
|
||||
endtask
|
||||
|
||||
task publicSetWide;
|
||||
// Can't be public, as no wide return types in C++
|
||||
// verilator public
|
||||
input [71:0] in_wide;
|
||||
var_wide = in_wide;
|
||||
endtask
|
||||
@ -178,7 +178,7 @@ module tpub (
|
||||
endtask
|
||||
|
||||
task publicGetWide;
|
||||
// Can't be public, as no wide return types in C++
|
||||
// verilator public
|
||||
output [71:0] out_wide;
|
||||
out_wide = var_wide;
|
||||
endtask
|
||||
|
Loading…
Reference in New Issue
Block a user