mirror of
https://github.com/verilator/verilator.git
synced 2026-10-04 00:53:42 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
344248cea0 | ||
|
|
2789e3dba5 | ||
|
|
cca759a41e | ||
|
|
4f7b3d8882 | ||
|
|
2b330b78b7 | ||
|
|
d47ca1912b | ||
|
|
cdf18c96f4 | ||
|
|
53acaa05b8 | ||
|
|
fb85679068 | ||
|
|
9558e14479 | ||
|
|
4af0af93bf | ||
|
|
df4bc950fe | ||
|
|
250394f72b | ||
|
|
d5e9e7cd2b | ||
|
|
9a96f621ef | ||
|
|
5d7ce096c6 | ||
|
|
c9f8109c06 |
@@ -3,9 +3,25 @@ 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.813 2011/06/28
|
||||
|
||||
*** Support bit vectors > 64 bits wide in DPI import and exports.
|
||||
|
||||
*** Fix out of memory on slice syntax error, bug354. [Alex Solomatnikov]
|
||||
|
||||
**** Fix error on enum references to other packages, bug339. [Alex Solomatnikov]
|
||||
|
||||
**** Fix DPI undeclared svBitVecVal compile error, bug346. [Chandan Egbert]
|
||||
|
||||
**** Fix DPI bit vector compile errors, bug347, bug359. [Chandan Egbert]
|
||||
|
||||
**** Fix CDCRSTLOGIC report showing endpoint flops without resets.
|
||||
|
||||
**** Fix compiler warnings on SPARC, bug288. [Ahmed El-Mahmoudy]
|
||||
|
||||
* Verilator 3.812 2011/04/06
|
||||
|
||||
*** Add --trace-max-width and --trace-max-array, bug 319. [Alex Solomatnikov]
|
||||
*** Add --trace-max-width and --trace-max-array, bug319. [Alex Solomatnikov]
|
||||
|
||||
*** Add --Wno-fatal to turn off abort on warnings. [by Stefan Wallentowitz]
|
||||
|
||||
@@ -13,7 +29,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
**** Support $bits(data_type), bug327. [Alex Solomatnikov]
|
||||
|
||||
**** Support loop unrolling on width mismatches, bug 333. [Joe Eiler]
|
||||
**** Support loop unrolling on width mismatches, bug333. [Joe Eiler]
|
||||
|
||||
**** Support simple cast operators, bug335. [Alex Solomatnikov]
|
||||
|
||||
|
||||
+23
-18
@@ -3296,25 +3296,30 @@ Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include
|
||||
Jeff Dutton, Ralf Karge, David Hewson, Wim Michiels, and Gene Weber.
|
||||
|
||||
Some of the people who have provided ideas and feedback for Verilator
|
||||
include David Addison, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, J
|
||||
include: David Addison, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, J
|
||||
Baxter, Jeremy Bennett, David Black, Gregg Bouchard, Christopher Boumenot,
|
||||
Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee, Lawrence Butcher,
|
||||
Chris Candler, Lauren Carlson, Donal Casey, Robert A. Clark, Allan
|
||||
Cochrane, Gunter Dannoritzer, Bernard Deadman, John Deroo, John Dickol,
|
||||
Danny Ding, Alex Duller, Jeff Dutton, Robert Farrell, Eugen Fekete, Andrea
|
||||
Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone, Chitlesh Goorah, Thomas
|
||||
Hawkins, David Hewson, Jae Hossell, Ben Jackson, Mike Kagen, Guy-Armand
|
||||
Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman,
|
||||
Jonathan Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, Steve Lang,
|
||||
Stephane Laurent, Charlie Lind, Dan Lussier, Fred Ma, Duraid Madina, Mark
|
||||
Marshall, Wim Michiels, Dennis Muhlestein, John Murphy, Richard Myers,
|
||||
Dimitris Nalbantis, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine,
|
||||
Andreas Olofsson, Niranjan Prabhu, Oleg Rodionov, John Sanguinetti, Mike
|
||||
Shinkarovsky, Rafael Shirakawa, Rodney Sinclair, Brian Small, Art Stamness,
|
||||
John Stroebel, Emerson Suguimoto, Renga Sundararajan, Stefan Thiede, Gary
|
||||
Thomas, Steve Tong, Holger Waechtler, Shawn Wang, Greg Waters, Eugene
|
||||
Weber, Leon Wildman, Gerald Williams, Jeff Winston, Johan Wouters, and Ding
|
||||
Xiaoliang.
|
||||
Nick Bowler, Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee,
|
||||
Lawrence Butcher, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen,
|
||||
Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard
|
||||
Deadman, John Deroo, John Dickol, Danny Ding, Ivan Djordjevic, Alex Duller,
|
||||
Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell,
|
||||
Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone,
|
||||
Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins, David Hewson,
|
||||
Jae Hossell, Ben Jackson, Iztok Jeras, Mike Kagen, Guy-Armand Kamendje,
|
||||
Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan
|
||||
Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, Steve Lang, Stephane
|
||||
Laurent, Christian Leber, Charlie Lind, Paul Liu, Dan Lussier, Fred Ma,
|
||||
Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Dennis
|
||||
Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Paul Nitza,
|
||||
Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, Dominic
|
||||
Plunkett, Niranjan Prabhu, Usha Priyadharshini, Oleg Rodionov, John
|
||||
Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey
|
||||
Short, Rodney Sinclair, Brian Small, Alex Solomatnikov, Art Stamness, John
|
||||
Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Stefan
|
||||
Thiede, Gary Thomas, Steve Tong, Holger Waechtler, Stefan Wallentowitz,
|
||||
Shawn Wang, Greg Waters, Eugene Weber, David Welch, Leon Wildman, Gerald
|
||||
Williams, Trevor Williams, Jeff Winston, Joshua Wise, Johan Wouters, and
|
||||
Ding Xiaoliang.
|
||||
|
||||
Thanks all.
|
||||
|
||||
|
||||
+1
-1
@@ -1633,6 +1633,6 @@ static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
|
||||
|
||||
#undef _END
|
||||
|
||||
// Debugging
|
||||
//======================================================================
|
||||
|
||||
#endif /*_VERILATED_H_*/
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#define _VERILATED_DPI_CPP_
|
||||
#include "verilatedos.h"
|
||||
#include "verilated_dpi.h"
|
||||
#include "verilated_imp.h"
|
||||
|
||||
// On MSVC++ we need svdpi.h to declare exports, not imports
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Common include for all Verilated C files that use DPI
|
||||
///
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all C++ files it generates where DPI is used. It contains
|
||||
/// DPI interface functions required by the Verilated code.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
#ifndef _VERILATED_DPI_H_
|
||||
#define _VERILATED_DPI_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilated.h" // Presumed done by caller
|
||||
#include "svdpi.h"
|
||||
|
||||
//===================================================================
|
||||
// SETTING OPERATORS
|
||||
|
||||
/// Return svBitVecVal from WData
|
||||
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, svBitVecVal* lwp) {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; i++) owp[i]=lwp[i];
|
||||
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; i++) owp[i]=lwp[i];
|
||||
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, svLogicVecVal* lwp) {
|
||||
// Note we ignore X/Z in svLogicVecVal
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; i++) owp[i]=lwp[i].aval;
|
||||
owp[words-1] = lwp[words-1].aval & VL_MASK_I(obits);
|
||||
}
|
||||
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) {
|
||||
// Note we don't create X/Z in svLogicVecVal
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words; i++) owp[i].bval=0;
|
||||
for (int i=0; i<words-1; i++) owp[i].aval=lwp[i];
|
||||
owp[words-1].aval = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
#endif // _VERILATED_DPI_H_
|
||||
+1
-13
@@ -8,21 +8,9 @@ use strict;
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
delete $ENV{MODULE_VERSION};
|
||||
_setup_modules();
|
||||
module('add','axiom-athdl');
|
||||
eval `modulecmd perl add axiom-athdl`;
|
||||
exec('atsim',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
# Modules package
|
||||
|
||||
sub _setup_modules {
|
||||
# Load the 'module' command into the environment
|
||||
my $init = "$ENV{MODULESHOME}/init/perl";
|
||||
(-f $init) or die "%Error: Script not found: $init,";
|
||||
require $init;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
|
||||
+1
-13
@@ -8,21 +8,9 @@ use strict;
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
delete $ENV{MODULE_VERSION};
|
||||
_setup_modules();
|
||||
module('add','cadence-ius');
|
||||
eval `modulecmd perl add cds-ius`;
|
||||
exec('iccr',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
# Modules package
|
||||
|
||||
sub _setup_modules {
|
||||
# Load the 'module' command into the environment
|
||||
my $init = "$ENV{MODULESHOME}/init/perl";
|
||||
(-f $init) or die "%Error: Script not found: $init,";
|
||||
require $init;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
|
||||
+1
-13
@@ -8,21 +8,9 @@ use strict;
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
delete $ENV{MODULE_VERSION};
|
||||
_setup_modules();
|
||||
module('add','cadence-ius');
|
||||
eval `modulecmd perl add cds-ius`;
|
||||
exec('ncverilog',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
# Modules package
|
||||
|
||||
sub _setup_modules {
|
||||
# Load the 'module' command into the environment
|
||||
my $init = "$ENV{MODULESHOME}/init/perl";
|
||||
(-f $init) or die "%Error: Script not found: $init,";
|
||||
require $init;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
|
||||
+1
-13
@@ -8,21 +8,9 @@ use strict;
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
delete $ENV{MODULE_VERSION};
|
||||
_setup_modules();
|
||||
module('add','synopsys-vcs');
|
||||
eval `modulecmd perl add synopsys-vcs`;
|
||||
exec('vcs',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
# Modules package
|
||||
|
||||
sub _setup_modules {
|
||||
# Load the 'module' command into the environment
|
||||
my $init = "$ENV{MODULESHOME}/init/perl";
|
||||
(-f $init) or die "%Error: Script not found: $init,";
|
||||
require $init;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
|
||||
@@ -202,7 +202,6 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
|
||||
if (forReturn) named=false;
|
||||
string arg;
|
||||
if (!basicp()) arg = "UNKNOWN";
|
||||
if (isWide()) v3error("Unsupported: DPI functions with vectored outputs > 32-bits");
|
||||
if (basicp()->isBitLogic()) {
|
||||
if (widthMin() == 1) {
|
||||
arg = "unsigned char";
|
||||
|
||||
+7
-4
@@ -364,9 +364,10 @@ public:
|
||||
struct AstEnumItemRef : public AstNodeMath {
|
||||
private:
|
||||
AstEnumItem* m_itemp; // [AfterLink] Pointer to item
|
||||
AstPackage* m_packagep; // Package hierarchy
|
||||
public:
|
||||
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp)
|
||||
: AstNodeMath(fl), m_itemp(itemp) {
|
||||
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstPackage* packagep)
|
||||
: AstNodeMath(fl), m_itemp(itemp), m_packagep(packagep) {
|
||||
if (m_itemp) widthSignedFrom(m_itemp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(EnumItemRef, ENUMITEMREF)
|
||||
@@ -381,6 +382,8 @@ public:
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
AstPackage* packagep() const { return m_packagep; }
|
||||
void packagep(AstPackage* nodep) { m_packagep=nodep; }
|
||||
};
|
||||
|
||||
struct AstEnumDType : public AstNodeDType {
|
||||
@@ -3181,9 +3184,9 @@ struct AstBufIf1 : public AstNodeBiop {
|
||||
ASTNODE_NODE_FUNCS(BufIf1, BUFIF1)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opBufIf1(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "bufif(%r,%l)"; }
|
||||
virtual string emitC() { V3ERROR_NA; return false;} // Lclean || Rclean
|
||||
virtual string emitC() { V3ERROR_NA; return "";} // Lclean || Rclean
|
||||
virtual string emitSimpleOperator() { V3ERROR_NA; return false;} // Lclean || Rclean
|
||||
virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean || Rclean
|
||||
virtual bool cleanOut() {V3ERROR_NA; return "";} // Lclean || Rclean
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
};
|
||||
|
||||
+19
-5
@@ -46,6 +46,8 @@
|
||||
#include "V3EmitV.h"
|
||||
#include "V3File.h"
|
||||
|
||||
#define CDC_WEIGHT_ASYNC 0x1000 // Weight for edges that feed async logic
|
||||
|
||||
//######################################################################
|
||||
|
||||
class CdcBaseVisitor : public AstNVisitor {
|
||||
@@ -314,7 +316,9 @@ private:
|
||||
UINFO(3,__FUNCTION__<<": "<<endl);
|
||||
//if (debug()>6) m_graph.dump();
|
||||
if (debug()>6) m_graph.dumpDotFilePrefixed("cdc_pre");
|
||||
m_graph.removeRedundantEdgesSum(&V3GraphEdge::followAlwaysTrue);
|
||||
//
|
||||
m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); // This will MAX across edge weights
|
||||
//
|
||||
m_graph.dumpDotFilePrefixed("cdc_simp");
|
||||
//
|
||||
analyzeReset();
|
||||
@@ -411,12 +415,15 @@ private:
|
||||
CdcEitherVertex* eToVertexp = (CdcEitherVertex*)edgep->top();
|
||||
if (!eToVertexp) targetp = eToVertexp;
|
||||
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(eToVertexp)) {
|
||||
if (vvertexp->isFlop()) {
|
||||
if (vvertexp->isFlop() // IE the target flop that is upsetting us
|
||||
&& edgep->weight() >= CDC_WEIGHT_ASYNC) { // And this signal feeds an async reset line
|
||||
targetp = eToVertexp;
|
||||
//UINFO(9," targetasync "<<targetp->name()<<" "<<" from "<<vertexp->name()<<endl);
|
||||
break;
|
||||
}
|
||||
} // else it might be random logic that's not relevant
|
||||
}
|
||||
//UINFO(9," finalflop "<<targetp->name()<<" "<<targetp->nodep()->fileline()<<endl);
|
||||
warnAndFile(markp->nodep(),V3ErrorCode::CDCRSTLOGIC,"Logic in path that feeds async reset, via signal: "+nodep->prettyName());
|
||||
dumpAsyncRecurse(targetp, "", " ",0);
|
||||
}
|
||||
@@ -618,8 +625,9 @@ private:
|
||||
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
|
||||
CdcVarVertex* varvertexp = makeVarVertex(varscp);
|
||||
UINFO(5," VARREF to "<<varscp<<endl);
|
||||
// We use weight of one; if we ref the var more than once, when we simplify,
|
||||
// the weight will increase
|
||||
// We use weight of one for normal edges,
|
||||
// Weight of CDC_WEIGHT_ASYNC to indicate feeds async (for reporting)
|
||||
// When simplify we'll take the MAX weight
|
||||
if (nodep->lvalue()) {
|
||||
new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1);
|
||||
if (m_inDly) {
|
||||
@@ -628,7 +636,13 @@ private:
|
||||
varvertexp->srcDomainSet(true);
|
||||
}
|
||||
} else {
|
||||
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1);
|
||||
if (varvertexp->cntAsyncRst()) {
|
||||
//UINFO(9," edgeasync "<<varvertexp->name()<<" to "<<m_logicVertexp<<endl);
|
||||
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, CDC_WEIGHT_ASYNC);
|
||||
} else {
|
||||
//UINFO(9," edgena "<<varvertexp->name()<<" to "<<m_logicVertexp<<endl);
|
||||
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,12 @@ private:
|
||||
nodep->packagep()->user1Inc();
|
||||
}
|
||||
}
|
||||
virtual void visit(AstEnumItemRef* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->packagep()) {
|
||||
nodep->packagep()->user1Inc();
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
m_vscsp.push_back(nodep);
|
||||
|
||||
+10
-2
@@ -127,6 +127,7 @@ public:
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||
} else if (nodep->isWide()
|
||||
&& nodep->lhsp()->castVarRef()
|
||||
&& !nodep->rhsp()->castCMath()
|
||||
&& !nodep->rhsp()->castVarRef()
|
||||
&& !nodep->rhsp()->castArraySel()) {
|
||||
// Wide functions assign into the array directly, don't need separate assign statement
|
||||
@@ -1619,7 +1620,12 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
||||
if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us
|
||||
puts("#include \""+topClassName()+"__Inlines.h\"\n");
|
||||
}
|
||||
// No __Dpi.h needed, we've shimmed it all into the interface
|
||||
if (v3Global.dpi()) {
|
||||
// do this before including our main .h file so that any references to
|
||||
// types defined in svdpi.h are available
|
||||
puts("#include \""+ topClassName() +"__Dpi.h\"\n");
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
// Declare foreign instances up front to make C++ happy
|
||||
puts("class "+symClassName()+";\n");
|
||||
@@ -1797,8 +1803,10 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
|
||||
|
||||
// Us
|
||||
puts("#include \""+ symClassName() +".h\"\n");
|
||||
|
||||
if (v3Global.dpi()) {
|
||||
puts("#include \""+ topClassName() +"__Dpi.h\"\n");
|
||||
puts("\n");
|
||||
puts("#include \"verilated_dpi.h\"\n");
|
||||
}
|
||||
|
||||
if (optSystemPerl() && (splitFilenum() || !m_fast)) {
|
||||
|
||||
@@ -519,6 +519,8 @@ void EmitCSyms::emitDpiHdr() {
|
||||
puts("// Manually include this file where DPI .c import functions are declared to insure\n");
|
||||
puts("// the C functions match the expectations of the DPI imports.\n");
|
||||
puts("\n");
|
||||
puts("#include \"svdpi.h\"\n");
|
||||
puts("\n");
|
||||
puts("#ifdef __cplusplus\n");
|
||||
puts("extern \"C\" {\n");
|
||||
puts("#endif\n");
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ private:
|
||||
nodep->packagep(packageFor(varp));
|
||||
}
|
||||
else if (AstEnumItem* valuep = foundp->castEnumItem()) {
|
||||
AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep);
|
||||
AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep, packageFor(valuep));
|
||||
nodep->replaceWith(newp);
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
return true; // Edited
|
||||
|
||||
+8
-4
@@ -53,6 +53,7 @@ class SliceCloneVisitor : public AstNVisitor {
|
||||
// Inputs:
|
||||
// AstArraySel::user1p() -> AstVarRef. The VarRef that the final ArraySel points to
|
||||
// AstNodeAssign::user2() -> int. The number of clones needed for this assign
|
||||
// AstArraySel::user3() -> bool. Error detected
|
||||
|
||||
// ENUMS
|
||||
enum RedOp { // The type of unary operation to be expanded
|
||||
@@ -221,6 +222,7 @@ class SliceVisitor : public AstNVisitor {
|
||||
// AstNode::user2() -> int. The number of clones needed for this node
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
|
||||
// TYPEDEFS
|
||||
typedef pair<uint32_t, uint32_t> ArrayDimensions; // Array Dimensions (packed, unpacked)
|
||||
@@ -328,11 +330,11 @@ class SliceVisitor : public AstNVisitor {
|
||||
m_assignp->v3error("Unsupported: Assignment between a constant and an array slice");
|
||||
m_assignError = true;
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
virtual void visit(AstArraySel* nodep, AstNUser*) {
|
||||
if (!m_assignp) return;
|
||||
if (nodep->user3()) return; // Prevent recursion on just created nodes
|
||||
unsigned dim = explicitDimensions(nodep);
|
||||
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
|
||||
pair<uint32_t,uint32_t> arrDim = refp->varp()->dimensions();
|
||||
@@ -340,16 +342,18 @@ class SliceVisitor : public AstNVisitor {
|
||||
if (implicit > 0) {
|
||||
AstArraySel* newp = insertImplicit(nodep->cloneTree(false), dim+1, implicit);
|
||||
nodep->replaceWith(newp); nodep = newp;
|
||||
nodep->user3(true);
|
||||
}
|
||||
int clones = countClones(nodep);
|
||||
if (m_assignp->user2() > 0 && m_assignp->user2() != clones) {
|
||||
m_assignp->v3error("Slices of arrays in assignments must have the same unpacked dimensions");
|
||||
} else if (m_assignp->user2() == 0 && !m_assignError) {
|
||||
if (m_extend && clones > 1) {
|
||||
} else if (!m_assignp->user2()) {
|
||||
if (m_extend && clones > 1 && !m_assignError) {
|
||||
m_assignp->v3error("Unsupported: Assignment between packed arrays of different dimensions");
|
||||
m_assignError = true;
|
||||
}
|
||||
if (clones > 1 && !refp->lvalue() && refp->varp() == m_lhsVarRefp->varp() && !m_assignp->castAssignDly()) {
|
||||
if (clones > 1 && !refp->lvalue() && refp->varp() == m_lhsVarRefp->varp()
|
||||
&& !m_assignp->castAssignDly() && !m_assignError) {
|
||||
// LHS Var != RHS Var for a non-delayed assignment
|
||||
m_assignp->v3error("Unsupported: Slices in a non-delayed assignment with the same Var on both sides");
|
||||
m_assignError = true;
|
||||
|
||||
+12
-5
@@ -587,8 +587,12 @@ private:
|
||||
// Someday we'll have better type support, and this can make variables and casts.
|
||||
// But for now, we'll just text-bash it.
|
||||
if (bitvec) {
|
||||
// We only support quads, so don't need to sweat longer stuff
|
||||
stmt += "VL_SET_WQ("+portp->name()+toSuffix+", "+portp->name()+frSuffix+")";
|
||||
if (portp->isWide()) {
|
||||
stmt += ("VL_SET_SVBV_W("+cvtToStr(portp->width())
|
||||
+", "+portp->name()+toSuffix+", "+portp->name()+frSuffix+")");
|
||||
} else {
|
||||
stmt += "VL_SET_WQ("+portp->name()+toSuffix+", "+portp->name()+frSuffix+")";
|
||||
}
|
||||
} else {
|
||||
if (isPtr) stmt += "*"; // DPI outputs are pointers
|
||||
stmt += portp->name()+toSuffix+" = ";
|
||||
@@ -605,7 +609,7 @@ private:
|
||||
return new AstCStmt(portp->fileline(), stmt);
|
||||
}
|
||||
|
||||
AstNode* createAssignDpiToInternal(AstVarScope* portvscp, const string& frName) {
|
||||
AstNode* createAssignDpiToInternal(AstVarScope* portvscp, const string& frName, bool cvt) {
|
||||
// Create assignment from DPI temporary into internal format
|
||||
AstVar* portp = portvscp->varp();
|
||||
string stmt;
|
||||
@@ -614,6 +618,9 @@ private:
|
||||
stmt += "VL_CVT_VP_Q(";
|
||||
ket += ")";
|
||||
}
|
||||
if (!cvt
|
||||
&& portp->basicp() && portp->basicp()->isBitLogic() && portp->widthMin() != 1 && !portp->isWide())
|
||||
stmt += "*"; // it's a svBitVecVal, which other code won't think is arrayed (as WData aren't), but really is
|
||||
stmt += frName;
|
||||
stmt += ket;
|
||||
// Use a AstCMath, as we want V3Clean to mask off bits that don't make sense.
|
||||
@@ -680,7 +687,7 @@ private:
|
||||
argnodesp = argnodesp->addNextNull(refp);
|
||||
|
||||
if (portp->isInput()) {
|
||||
dpip->addStmtsp(createAssignDpiToInternal(outvscp, portp->name()));
|
||||
dpip->addStmtsp(createAssignDpiToInternal(outvscp, portp->name(), false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -795,7 +802,7 @@ private:
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (portp->isIO() && (portp->isOutput() || portp->isFuncReturn())) {
|
||||
AstVarScope* portvscp = portp->user2p()->castNode()->castVarScope(); // Remembered when we created it earlier
|
||||
cfuncp->addStmtsp(createAssignDpiToInternal(portvscp,portp->name()+"__Vcvt"));
|
||||
cfuncp->addStmtsp(createAssignDpiToInternal(portvscp,portp->name()+"__Vcvt",true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-30
@@ -390,47 +390,20 @@ private:
|
||||
// Just a quick check as after V3Param these nodes instead are AstSel's
|
||||
AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; }
|
||||
nodep->v3fatalSrc("AstSelBit should disappear after widthSel");
|
||||
if (vup->c()->prelim()) {
|
||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); // from
|
||||
nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); // bit
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSelExtract* nodep, AstNUser* vup) {
|
||||
// Just a quick check as after V3Param these nodes instead are AstSel's
|
||||
AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; }
|
||||
nodep->v3fatalSrc("AstSelExtract should disappear after widthSel");
|
||||
if (vup->c()->prelim()) {
|
||||
nodep->fromp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->msbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstSelPlus* nodep, AstNUser* vup) {
|
||||
AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; }
|
||||
nodep->v3fatalSrc("AstSelPlus should disappear after widthSel");
|
||||
if (vup->c()->prelim()) {
|
||||
nodep->fromp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->bitp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->widthp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
if (AstConst* constp = nodep->widthp()->castConst()) {
|
||||
int width = constp->toSInt();
|
||||
nodep->width(width,width);
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSelMinus* nodep, AstNUser* vup) {
|
||||
AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; }
|
||||
nodep->v3fatalSrc("AstSelMinus should disappear after widthSel");
|
||||
if (vup->c()->prelim()) {
|
||||
nodep->fromp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->bitp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->widthp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
if (AstConst* constp = nodep->widthp()->castConst()) {
|
||||
int width = constp->toSInt();
|
||||
nodep->width(width,width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstExtend* nodep, AstNUser* vup) {
|
||||
@@ -616,6 +589,7 @@ private:
|
||||
}
|
||||
|
||||
virtual void visit(AstEnumDType* nodep, AstNUser* vup) {
|
||||
UINFO(5," ENUMDTYPE "<<nodep<<endl);
|
||||
nodep->dtypep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->widthFrom(nodep->dtypep());
|
||||
// Assign widths
|
||||
@@ -646,6 +620,7 @@ private:
|
||||
}
|
||||
}
|
||||
virtual void visit(AstEnumItem* nodep, AstNUser* vup) {
|
||||
UINFO(5," ENUMITEM "<<nodep<<endl);
|
||||
int width = vup->c()->width();
|
||||
int mwidth = vup->c()->widthMin();
|
||||
nodep->width(width, mwidth);
|
||||
@@ -657,12 +632,13 @@ private:
|
||||
virtual void visit(AstEnumItemRef* nodep, AstNUser* vup) {
|
||||
if (nodep->itemp()->width()==0) {
|
||||
// We need to do the whole enum en-mass
|
||||
AstNode* enump = nodep;
|
||||
AstNode* enump = nodep->itemp();
|
||||
if (!enump) nodep->v3fatalSrc("EnumItemRef not linked");
|
||||
for (; enump; enump=enump->backp()) {
|
||||
if (enump->castEnumDType()) break;
|
||||
}
|
||||
if (!enump) nodep->v3fatalSrc("EnumItem not under a Enum");
|
||||
enump->iterate(*this);
|
||||
if (!enump) nodep->v3fatalSrc("EnumItemRef can't deref back to a Enum");
|
||||
enump->iterate(*this,vup);
|
||||
}
|
||||
nodep->widthFrom(nodep->itemp()->valuep());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//**********************************************************************
|
||||
//**** Version and host name
|
||||
|
||||
#define DTVERSION "Verilator 3.812 2011/04/06"
|
||||
#define DTVERSION "Verilator 3.813 2011/06/28"
|
||||
|
||||
//**********************************************************************
|
||||
//**** Functions
|
||||
|
||||
+5
-5
@@ -833,7 +833,7 @@ port<nodep>: // ==IEEE: port
|
||||
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$=$2; /*VARDTYPE-same*/ AstVar* vp=VARDONEP($$,$3,$4); $$->addNextNull(vp); vp->valuep($6); }
|
||||
;
|
||||
|
||||
|
||||
portDirNetE: // IEEE: part of port, optional net type and/or direction
|
||||
/* empty */ { }
|
||||
// // Per spec, if direction given default the nettype.
|
||||
@@ -842,12 +842,12 @@ portDirNetE: // IEEE: part of port, optional net type and/or direction
|
||||
| port_direction net_type { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARNET
|
||||
| net_type { } // net_type calls VARNET
|
||||
;
|
||||
|
||||
|
||||
port_declNetE: // IEEE: part of port_declaration, optional net type
|
||||
/* empty */ { }
|
||||
| net_type { } // net_type calls VARNET
|
||||
;
|
||||
|
||||
|
||||
portSig<nodep>:
|
||||
id/*port*/ { $$ = new AstPort($<fl>1,PINNUMINC(),*$1); }
|
||||
| idSVKwd { $$ = new AstPort($<fl>1,PINNUMINC(),*$1); }
|
||||
@@ -2838,7 +2838,7 @@ junkToSemiList:
|
||||
junkToSemi { } /* ignored */
|
||||
| junkToSemiList junkToSemi { } /* ignored */
|
||||
;
|
||||
|
||||
|
||||
junkToSemi:
|
||||
BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE) { }
|
||||
| error {}
|
||||
@@ -3109,7 +3109,7 @@ vltOffFront<errcodeen>:
|
||||
|
||||
int V3ParseImp::bisonParse() {
|
||||
if (PARSEP->debugBison()>=9) yydebug = 1;
|
||||
return yyparse();
|
||||
return yyparse();
|
||||
}
|
||||
|
||||
const char* V3ParseImp::tokenName(int token) {
|
||||
|
||||
+48
-34
@@ -304,8 +304,9 @@ sub new {
|
||||
ivrun_flags => [],
|
||||
# VCS
|
||||
vcs => 0,
|
||||
vcs_flags => [split(/\s+/,"+cli -I +define+VCS+1 -q -sverilog -CFLAGS '-DVCS' ")],
|
||||
vcs_flags => [split(/\s+/,"+vcs+lic+wait +cli -I +define+VCS+1 -q -sverilog -CFLAGS '-DVCS' ")],
|
||||
vcs_flags2 => [], # Overridden in some sim files
|
||||
vcsrun_flags => [split(/\s+/,"+vcs+lic_wait")],
|
||||
# NC
|
||||
nc => 0,
|
||||
nc_flags => [split(/\s+/,"+licqueue +nowarn+LIBNOU +define+NC=1 -q +assert +sv -c ")],
|
||||
@@ -409,11 +410,10 @@ sub read_status {
|
||||
#----------------------------------------------------------------------
|
||||
# Methods invoked by tests
|
||||
|
||||
sub compile {
|
||||
sub compile_vlt_flags {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
my %param = (%{$self}, @_); # Default arguments are from $self
|
||||
return 1 if $self->errors || $self->skips;
|
||||
$self->oprint("Compile\n");
|
||||
|
||||
my $checkflags = join(' ',@{$param{v_flags}},
|
||||
@{$param{v_flags2}},
|
||||
@@ -424,6 +424,48 @@ sub compile {
|
||||
$self->{trace} = 1 if ($opt_trace || $checkflags =~ /-trace\b/);
|
||||
$self->{coverage} = 1 if ($checkflags =~ /-coverage\b/);
|
||||
|
||||
$opt_gdb="gdbrun" if defined $opt_gdb;
|
||||
my @verilator_flags = @{$param{verilator_flags}};
|
||||
unshift @verilator_flags, "--gdb $opt_gdb" if $opt_gdb;
|
||||
unshift @verilator_flags, "--gdbbt" if $opt_gdbbt;
|
||||
unshift @verilator_flags, @Opt_Driver_Verilator_Flags;
|
||||
unshift @verilator_flags, "--x-assign unique"; # More likely to be buggy
|
||||
unshift @verilator_flags, "--trace" if $opt_trace;
|
||||
if (defined $opt_optimize) {
|
||||
my $letters = "";
|
||||
if ($opt_optimize =~ /[a-zA-Z]/) {
|
||||
$letters = $opt_optimize;
|
||||
} else { # Randomly turn on/off different optimizations
|
||||
foreach my $l ('a'..'z') {
|
||||
$letters .= ((rand() > 0.5) ? $l : uc $l);
|
||||
}
|
||||
unshift @verilator_flags, "--trace" if rand() > 0.5;
|
||||
unshift @verilator_flags, "--coverage" if rand() > 0.5;
|
||||
}
|
||||
unshift @verilator_flags, "--O".$letters;
|
||||
}
|
||||
|
||||
my @cmdargs = ("perl","../bin/verilator",
|
||||
"--prefix ".$param{VM_PREFIX},
|
||||
@verilator_flags,
|
||||
@{$param{verilator_flags2}},
|
||||
@{$param{v_flags}},
|
||||
@{$param{v_flags2}},
|
||||
$param{top_filename},
|
||||
@{$param{v_other_filenames}},
|
||||
($param{stdout_filename}?"> ".$param{stdout_filename}:""),
|
||||
);
|
||||
return @cmdargs;
|
||||
}
|
||||
|
||||
sub compile {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
my %param = (%{$self}, @_); # Default arguments are from $self
|
||||
return 1 if $self->errors || $self->skips;
|
||||
$self->oprint("Compile\n");
|
||||
|
||||
compile_vlt_flags(%param);
|
||||
|
||||
if ($param{atsim}) {
|
||||
$self->_make_top();
|
||||
$self->_run(logfile=>"$self->{obj_dir}/atsim_compile.log",
|
||||
@@ -483,37 +525,8 @@ sub compile {
|
||||
cmd=>\@cmd);
|
||||
}
|
||||
if ($param{vlt}) {
|
||||
$opt_gdb="gdbrun" if defined $opt_gdb;
|
||||
my @verilator_flags = @{$param{verilator_flags}};
|
||||
unshift @verilator_flags, "--gdb $opt_gdb" if $opt_gdb;
|
||||
unshift @verilator_flags, "--gdbbt" if $opt_gdbbt;
|
||||
unshift @verilator_flags, @Opt_Driver_Verilator_Flags;
|
||||
unshift @verilator_flags, "--x-assign unique"; # More likely to be buggy
|
||||
unshift @verilator_flags, "--trace" if $opt_trace;
|
||||
if (defined $opt_optimize) {
|
||||
my $letters = "";
|
||||
if ($opt_optimize =~ /[a-zA-Z]/) {
|
||||
$letters = $opt_optimize;
|
||||
} else { # Randomly turn on/off different optimizations
|
||||
foreach my $l ('a'..'z') {
|
||||
$letters .= ((rand() > 0.5) ? $l : uc $l);
|
||||
}
|
||||
unshift @verilator_flags, "--trace" if rand() > 0.5;
|
||||
unshift @verilator_flags, "--coverage" if rand() > 0.5;
|
||||
}
|
||||
unshift @verilator_flags, "--O".$letters;
|
||||
}
|
||||
my @cmdargs = $self->compile_vlt_flags(%param);
|
||||
|
||||
my @vlargs = ("perl","../bin/verilator",
|
||||
"--prefix ".$self->{VM_PREFIX},
|
||||
@verilator_flags,
|
||||
@{$param{verilator_flags2}},
|
||||
@{$param{v_flags}},
|
||||
@{$param{v_flags2}},
|
||||
$param{top_filename},
|
||||
@{$param{v_other_filenames}},
|
||||
($param{stdout_filename}?"> ".$param{stdout_filename}:""),
|
||||
);
|
||||
if ($self->sc_or_sp && !defined $ENV{SYSTEMC}) {
|
||||
$self->skip("Test requires SystemC; ignore error since not installed\n");
|
||||
return 1;
|
||||
@@ -526,7 +539,7 @@ sub compile {
|
||||
$self->_run(logfile=>"$self->{obj_dir}/vlt_compile.log",
|
||||
fails=>$param{fails},
|
||||
expect=>$param{expect},
|
||||
cmd=>\@vlargs);
|
||||
cmd=>\@cmdargs);
|
||||
return 1 if $self->errors || $self->skips;
|
||||
|
||||
if (!$param{fails} && $param{verilator_make_gcc}) {
|
||||
@@ -591,6 +604,7 @@ sub execute {
|
||||
#$fh->print("quit\n"); $fh->close;
|
||||
$self->_run(logfile=>"$self->{obj_dir}/vcs_sim.log",
|
||||
cmd=>["echo q | ".$run_env."./simv",
|
||||
@{$param{vcsrun_flags}},
|
||||
@{$param{all_run_flags}},
|
||||
],
|
||||
%param,
|
||||
|
||||
@@ -23,6 +23,7 @@ module t;
|
||||
function int dpix_int123(); dpix_int123 = 32'h123; endfunction
|
||||
|
||||
export "DPI-C" function dpix_f_bit;
|
||||
export "DPI-C" function dpix_f_bit15;
|
||||
export "DPI-C" function dpix_f_int;
|
||||
export "DPI-C" function dpix_f_byte;
|
||||
export "DPI-C" function dpix_f_shortint;
|
||||
@@ -30,12 +31,18 @@ module t;
|
||||
export "DPI-C" function dpix_f_chandle;
|
||||
|
||||
function bit dpix_f_bit (bit i); dpix_f_bit = ~i; endfunction
|
||||
function bit [14:0] dpix_f_bit15 (bit [14:0] i); dpix_f_bit15 = ~i; endfunction
|
||||
function int dpix_f_int (int i); dpix_f_int = ~i; endfunction
|
||||
function byte dpix_f_byte (byte i); dpix_f_byte = ~i; endfunction
|
||||
function shortint dpix_f_shortint(shortint i); dpix_f_shortint = ~i; endfunction
|
||||
function longint dpix_f_longint (longint i); dpix_f_longint = ~i; endfunction
|
||||
function chandle dpix_f_chandle (chandle i); dpix_f_chandle = i; endfunction
|
||||
|
||||
export "DPI-C" task dpix_t_bit95;
|
||||
task dpix_t_bit95(input bit [94:0] i, output bit [94:0] o); o = ~i; endtask
|
||||
export "DPI-C" task dpix_t_bit96;
|
||||
task dpix_t_bit96(input bit [95:0] i, output bit [95:0] o); o = ~i; endtask
|
||||
|
||||
int lineno;
|
||||
|
||||
initial begin
|
||||
|
||||
@@ -123,8 +123,11 @@ int dpix_run_tests() {
|
||||
CHECK_RESULT (int, o, 0x458UL);
|
||||
#endif
|
||||
|
||||
svBitVecVal vec10[1] = {0x10};
|
||||
|
||||
CHECK_RESULT (int, dpix_f_bit(1), 0x0);
|
||||
CHECK_RESULT (int, dpix_f_bit(0), 0x1);
|
||||
CHECK_RESULT (int, dpix_f_bit15(vec10) & 0x7fUL, 0x6f);
|
||||
// Simulators disagree over the next three's sign extension unless we mask the upper bits
|
||||
CHECK_RESULT (int, dpix_f_int(1) & 0xffffffffUL, 0xfffffffeUL);
|
||||
CHECK_RESULT (int, dpix_f_byte(1) & 0xffUL, 0xfe);
|
||||
@@ -133,6 +136,23 @@ int dpix_run_tests() {
|
||||
CHECK_RESULT (unsigned long long, dpix_f_longint(1), 0xfffffffffffffffeULL);
|
||||
CHECK_RESULT (void*, dpix_f_chandle((void*)(12345)), (void*)(12345));
|
||||
|
||||
{
|
||||
svBitVecVal i_vec95[3] = {0x72912312,0xab782a12,0x8a413bd9};
|
||||
svBitVecVal o_vec95[3] = {0,0,0};
|
||||
dpix_t_bit95(i_vec95, o_vec95);
|
||||
CHECK_RESULT(int, o_vec95[0], ~i_vec95[0]);
|
||||
CHECK_RESULT(int, o_vec95[1], ~i_vec95[1]);
|
||||
CHECK_RESULT(int, o_vec95[2], (~i_vec95[2])&0x7fffffffUL);
|
||||
}
|
||||
{
|
||||
svBitVecVal i_vec96[3] = {0xf2912312,0xab782a12,0x8a413bd9};
|
||||
svBitVecVal o_vec96[3] = {0,0,0};
|
||||
dpix_t_bit96(i_vec96, o_vec96);
|
||||
CHECK_RESULT(int, o_vec96[0], ~i_vec96[0]);
|
||||
CHECK_RESULT(int, o_vec96[1], ~i_vec96[1]);
|
||||
CHECK_RESULT(int, o_vec96[2], ~i_vec96[2]);
|
||||
}
|
||||
|
||||
if (int bad=check_sub("top.t.a",1)) return bad;
|
||||
if (int bad=check_sub("top.t.b",2)) return bad;
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ module t ();
|
||||
`ifndef NO_SHORTREAL
|
||||
import "DPI-C" pure function void dpii_v_shortreal(input shortreal i, output shortreal o);
|
||||
`endif
|
||||
import "DPI-C" pure function void dpii_v_bit95 (input bit [95-1:0] i, output bit [95-1:0] o);
|
||||
import "DPI-C" pure function void dpii_v_bit96 (input bit [96-1:0] i, output bit [96-1:0] o);
|
||||
|
||||
import "DPI-C" pure function int dpii_f_strlen (input string i);
|
||||
|
||||
@@ -82,6 +84,8 @@ module t ();
|
||||
bit [31:0] i_b32, o_b32;
|
||||
bit [32:0] i_b33, o_b33;
|
||||
bit [63:0] i_b64, o_b64;
|
||||
bit [94:0] i_b95, o_b95;
|
||||
bit [95:0] i_b96, o_b96;
|
||||
|
||||
int i_i, o_i;
|
||||
byte i_y, o_y;
|
||||
@@ -111,6 +115,8 @@ module t ();
|
||||
i_b32 = {1'b1,wide[32-2:0]};
|
||||
i_b33 = {1'b1,wide[33-2:0]};
|
||||
i_b64 = {1'b1,wide[64-2:0]};
|
||||
i_b95 = {1'b1,wide[95-2:0]};
|
||||
i_b96 = {1'b1,wide[96-2:0]};
|
||||
|
||||
i_i = {1'b1,wide[32-2:0]};
|
||||
i_y = {1'b1,wide[8-2:0]};
|
||||
@@ -159,6 +165,8 @@ module t ();
|
||||
`ifndef NO_SHORTREAL
|
||||
dpii_v_shortreal(i_f,o_f); if (o_f != i_f+1.5) $stop;
|
||||
`endif
|
||||
dpii_v_bit95 (i_b95,o_b95); if (o_b95 !== ~i_b95) $stop;
|
||||
dpii_v_bit96 (i_b96,o_b96); if (o_b96 !== ~i_b96) $stop;
|
||||
|
||||
if (dpii_f_strlen ("")!=0) $stop;
|
||||
if (dpii_f_strlen ("s")!=1) $stop;
|
||||
|
||||
@@ -33,13 +33,14 @@
|
||||
extern "C" {
|
||||
|
||||
extern unsigned char dpii_f_bit (unsigned char i);
|
||||
extern svBitVecVal dpii_f_bit8 (const svBitVecVal *i);
|
||||
extern svBitVecVal dpii_f_bit9 (const svBitVecVal *i);
|
||||
extern svBitVecVal dpii_f_bit16 (const svBitVecVal *i);
|
||||
extern svBitVecVal dpii_f_bit17 (const svBitVecVal *i);
|
||||
extern svBitVecVal dpii_f_bit32 (const svBitVecVal *i);
|
||||
extern long long dpii_f_bit33 (const svBitVecVal *i);
|
||||
extern long long dpii_f_bit64 (const svBitVecVal *i);
|
||||
extern svBitVecVal dpii_f_bit8 (const svBitVecVal* i);
|
||||
extern svBitVecVal dpii_f_bit9 (const svBitVecVal* i);
|
||||
extern svBitVecVal dpii_f_bit16 (const svBitVecVal* i);
|
||||
extern svBitVecVal dpii_f_bit17 (const svBitVecVal* i);
|
||||
extern svBitVecVal dpii_f_bit32 (const svBitVecVal* i);
|
||||
extern long long dpii_f_bit33 (const svBitVecVal* i);
|
||||
extern long long dpii_f_bit64 (const svBitVecVal* i);
|
||||
extern long long dpii_f_bit95 (const svBitVecVal* i, svBitVecVal* o);
|
||||
extern int dpii_f_int (int i);
|
||||
extern char dpii_f_byte (char i);
|
||||
extern short int dpii_f_shortint(short int i);
|
||||
@@ -49,7 +50,7 @@ extern "C" {
|
||||
extern double dpii_f_real (double i);
|
||||
extern float dpii_f_shortreal(float i);
|
||||
|
||||
extern void dpii_v_bit (unsigned char i, unsigned char *o);
|
||||
extern void dpii_v_bit (unsigned char i, unsigned char* o);
|
||||
extern void dpii_v_int (int i, int *o);
|
||||
extern void dpii_v_byte (char i, char *o);
|
||||
extern void dpii_v_shortint (short int i, short int *o);
|
||||
@@ -100,6 +101,17 @@ void dpii_v_string (const char* i, const char** o) { *o = i; }
|
||||
void dpii_v_real (double i, double* o) { *o = i + 1.5; }
|
||||
void dpii_v_shortreal(float i, float* o) { *o = i + 1.5; }
|
||||
|
||||
void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o) {
|
||||
o[0] = ~i[0];
|
||||
o[1] = ~i[1];
|
||||
o[2] = SV_MASK(95-64) & ~i[2];
|
||||
}
|
||||
void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o) {
|
||||
o[0] = ~i[0];
|
||||
o[1] = ~i[1];
|
||||
o[2] = ~i[2];
|
||||
}
|
||||
|
||||
int dpii_f_strlen (const char* i) { return strlen(i); }
|
||||
|
||||
//======================================================================
|
||||
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
use File::Spec;
|
||||
|
||||
my $self = $Self;
|
||||
my $child_dir = "$Self->{obj_dir}_child";
|
||||
mkdir $child_dir;
|
||||
|
||||
# Compile the child
|
||||
{
|
||||
my @cmdargs = $Self->compile_vlt_flags
|
||||
(VM_PREFIX => "$Self->{VM_PREFIX}_child",
|
||||
top_filename => "$Self->{name}_child.v",
|
||||
verilator_flags => ["-cc", "-Mdir", "${child_dir}", "--debug-check"],
|
||||
);
|
||||
|
||||
$Self->_run(logfile=>"${child_dir}/vlt_compile.log",
|
||||
cmd=>\@cmdargs);
|
||||
|
||||
$Self->_run(logfile=>"${child_dir}/vlt_gcc.log",
|
||||
cmd=>["cd ${child_dir} && ",
|
||||
"make", "-f".getcwd()."/Makefile_obj",
|
||||
"CPPFLAGS_DRIVER=-D".uc($self->{name}),
|
||||
($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""),
|
||||
"MAKE_MAIN=0",
|
||||
"VM_PREFIX=$self->{VM_PREFIX}_child",
|
||||
"V$self->{name}_child__ALL.a", # bypass default rule, make archive
|
||||
($param{make_flags}||""),
|
||||
]);
|
||||
}
|
||||
|
||||
# Compile the parent (might be with other than verilator)
|
||||
compile (
|
||||
v_flags2 => [File::Spec->rel2abs("${child_dir}/V$self->{name}_child__ALL.a"),
|
||||
# TODO would be nice to have this in embedded archive
|
||||
"t/t_embed1_c.cpp"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,109 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
|
||||
// Take CRC data and apply to testblock inputs
|
||||
wire bit_in = crc[0];
|
||||
wire [30:0] vec_in = crc[31:1];
|
||||
wire [123:0] wide_in = {crc[59:0],~crc[63:0]};
|
||||
|
||||
/*AUTOWIRE*/
|
||||
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
||||
wire exp_bit_out; // From reference of t_embed1_child.v
|
||||
wire exp_did_init_out; // From reference of t_embed1_child.v
|
||||
wire [30:0] exp_vec_out; // From reference of t_embed1_child.v
|
||||
wire [123:0] exp_wide_out; // From reference of t_embed1_child.v
|
||||
wire got_bit_out; // From test of t_embed1_wrap.v
|
||||
wire got_did_init_out; // From test of t_embed1_wrap.v
|
||||
wire [30:0] got_vec_out; // From test of t_embed1_wrap.v
|
||||
wire [123:0] got_wide_out; // From test of t_embed1_wrap.v
|
||||
// End of automatics
|
||||
|
||||
// A non-embedded master
|
||||
|
||||
/* t_embed1_child AUTO_TEMPLATE(
|
||||
.\(.*_out\) (exp_\1[]),
|
||||
.is_ref (1'b1));
|
||||
*/
|
||||
t_embed1_child reference
|
||||
(/*AUTOINST*/
|
||||
// Outputs
|
||||
.bit_out (exp_bit_out), // Templated
|
||||
.vec_out (exp_vec_out[30:0]), // Templated
|
||||
.wide_out (exp_wide_out[123:0]), // Templated
|
||||
.did_init_out (exp_did_init_out), // Templated
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.bit_in (bit_in),
|
||||
.vec_in (vec_in[30:0]),
|
||||
.wide_in (wide_in[123:0]),
|
||||
.is_ref (1'b1)); // Templated
|
||||
|
||||
// The embeded comparison
|
||||
|
||||
/* t_embed1_wrap AUTO_TEMPLATE(
|
||||
.\(.*_out\) (got_\1[]),
|
||||
.is_ref (1'b0));
|
||||
*/
|
||||
|
||||
t_embed1_wrap test
|
||||
(/*AUTOINST*/
|
||||
// Outputs
|
||||
.bit_out (got_bit_out), // Templated
|
||||
.vec_out (got_vec_out[30:0]), // Templated
|
||||
.wide_out (got_wide_out[123:0]), // Templated
|
||||
.did_init_out (got_did_init_out), // Templated
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.bit_in (bit_in),
|
||||
.vec_in (vec_in[30:0]),
|
||||
.wide_in (wide_in[123:0]),
|
||||
.is_ref (1'b0)); // Templated
|
||||
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {60'h0,
|
||||
got_wide_out !== exp_wide_out,
|
||||
got_vec_out !== exp_vec_out,
|
||||
got_bit_out !== exp_bit_out,
|
||||
got_did_init_out !== exp_did_init_out};
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d crc=%x result=%x gv=%x ev=%x\n",$time, cyc, crc, result,
|
||||
got_vec_out, exp_vec_out);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
if (result != 64'h0) begin
|
||||
$display("Bit mismatch, result=%x\n", result);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||
//Child prints this: $write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,123 @@
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2011-2011 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include <cstdio>
|
||||
#include "svdpi.h"
|
||||
|
||||
#include "../t_embed1_child/Vt_embed1_child.h"
|
||||
|
||||
//======================================================================
|
||||
|
||||
#if defined(VERILATOR)
|
||||
# include "Vt_embed1__Dpi.h"
|
||||
#elif defined(VCS)
|
||||
# include "../vc_hdrs.h"
|
||||
#elif defined(CADENCE)
|
||||
# define NEED_EXTERNS
|
||||
#else
|
||||
# error "Unknown simulator for DPI test"
|
||||
#endif
|
||||
|
||||
#include "verilated.h"
|
||||
|
||||
#ifdef NEED_EXTERNS
|
||||
extern "C" {
|
||||
|
||||
extern void t_embed_child_initial();
|
||||
extern void t_embed_child_final();
|
||||
extern void t_embed_child_eval();
|
||||
extern void t_embed_child_io_eval(); // TODO real function params here
|
||||
}
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
|
||||
extern int T_Embed_Child_Unique;
|
||||
int T_Embed_Child_Unique = 0; // Address used for uniqueness
|
||||
|
||||
Vt_embed1_child* __get_modelp() {
|
||||
svScope scope = svGetScope();
|
||||
if (!scope) {
|
||||
vl_fatal(__FILE__,__LINE__,__FILE__,"svGetScope failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* __modelp = svGetUserData(scope, &T_Embed_Child_Unique);
|
||||
if (!__modelp) {
|
||||
// Create the model
|
||||
const char* scopenamep = svGetNameFromScope(scope);
|
||||
if (!scopenamep) vl_fatal(__FILE__,__LINE__,__FILE__,"svGetNameFromScope failed");
|
||||
__modelp = new Vt_embed1_child(scopenamep);
|
||||
if (svPutUserData(scope, &T_Embed_Child_Unique, __modelp)) {
|
||||
vl_fatal(__FILE__,__LINE__,__FILE__,"svPutUserData failed");
|
||||
}
|
||||
}
|
||||
return (Vt_embed1_child*)(__modelp);
|
||||
}
|
||||
|
||||
void t_embed_child_initial() {
|
||||
VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_initial\n"); );
|
||||
Vt_embed1_child* __modelp = __get_modelp();
|
||||
__modelp->eval();
|
||||
}
|
||||
|
||||
void t_embed_child_final() {
|
||||
VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_final\n"); );
|
||||
Vt_embed1_child* __modelp = __get_modelp();
|
||||
__modelp->final();
|
||||
}
|
||||
|
||||
void t_embed_child_eval() {
|
||||
VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_eval\n"); );
|
||||
Vt_embed1_child* __modelp = __get_modelp();
|
||||
__modelp->eval();
|
||||
}
|
||||
|
||||
void t_embed_child_io_eval (unsigned char clk,
|
||||
unsigned char bit_in,
|
||||
const svBitVecVal* vec_in,
|
||||
const svBitVecVal* wide_in,
|
||||
unsigned char is_ref,
|
||||
unsigned char* bit_out,
|
||||
svBitVecVal* vec_out,
|
||||
svBitVecVal* wide_out,
|
||||
unsigned char* did_init_out) {
|
||||
VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_io_eval\n"); );
|
||||
Vt_embed1_child* __modelp = __get_modelp();
|
||||
VL_DEBUG_IF(VL_PRINTF("[%0ld] in clk=%x b=%x V=%x R=%x\n",
|
||||
VL_TIME_Q(), clk, bit_in, vec_in[0], is_ref););
|
||||
__modelp->clk = clk;
|
||||
__modelp->bit_in = bit_in;
|
||||
__modelp->vec_in = vec_in[0];
|
||||
__modelp->wide_in[0] = wide_in[0];
|
||||
__modelp->wide_in[1] = wide_in[1];
|
||||
__modelp->wide_in[2] = wide_in[2];
|
||||
__modelp->wide_in[3] = wide_in[3];
|
||||
__modelp->is_ref = is_ref;
|
||||
//
|
||||
__modelp->eval();
|
||||
// TODO maybe we should look at a "change detect" to know if we need to copy
|
||||
// out the variables; can return this value to the caller verilog code too
|
||||
//
|
||||
*bit_out = __modelp->bit_out;
|
||||
vec_out[0] = __modelp->vec_out;
|
||||
wide_out[0] = __modelp->wide_out[0];
|
||||
wide_out[1] = __modelp->wide_out[1];
|
||||
wide_out[2] = __modelp->wide_out[2];
|
||||
wide_out[3] = __modelp->wide_out[3];
|
||||
*did_init_out = __modelp->did_init_out;
|
||||
VL_DEBUG_IF(VL_PRINTF("[%0ld] out b=%x V=%x DI=%x\n",
|
||||
VL_TIME_Q(), *bit_out, *vec_out, *did_init_out););
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
|
||||
module t_embed1_child (/*AUTOARG*/
|
||||
// Outputs
|
||||
bit_out, vec_out, wide_out, did_init_out,
|
||||
// Inputs
|
||||
clk, bit_in, vec_in, wide_in, is_ref
|
||||
);
|
||||
|
||||
input clk;
|
||||
input bit_in;
|
||||
output bit_out;
|
||||
input [30:0] vec_in;
|
||||
output [30:0] vec_out;
|
||||
input [123:0] wide_in;
|
||||
output [123:0] wide_out;
|
||||
output did_init_out;
|
||||
|
||||
input is_ref;
|
||||
|
||||
reg did_init; initial did_init = 0;
|
||||
initial begin
|
||||
did_init = 1;
|
||||
end
|
||||
|
||||
reg did_final; initial did_final = 0;
|
||||
final begin
|
||||
did_final = 1;
|
||||
if (!is_ref) $write("*-* All Finished *-*\n");
|
||||
//$finish is in parent
|
||||
end
|
||||
|
||||
// Note async use!
|
||||
wire bit_out = bit_in;
|
||||
wire did_init_out = did_init;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
vec_out <= vec_in;
|
||||
wide_out <= wide_in;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,90 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
|
||||
module t_embed1_wrap (/*AUTOARG*/
|
||||
// Outputs
|
||||
bit_out, vec_out, wide_out, did_init_out,
|
||||
// Inputs
|
||||
clk, bit_in, vec_in, wide_in, is_ref
|
||||
);
|
||||
|
||||
/*AUTOINOUTMODULE("t_embed1_child")*/
|
||||
// Beginning of automatic in/out/inouts (from specific module)
|
||||
output bit_out;
|
||||
output [30:0] vec_out;
|
||||
output [123:0] wide_out;
|
||||
output did_init_out;
|
||||
input clk;
|
||||
input bit_in;
|
||||
input [30:0] vec_in;
|
||||
input [123:0] wide_in;
|
||||
input is_ref;
|
||||
// End of automatics
|
||||
|
||||
`ifdef verilator
|
||||
// Import $t_embed_child__initial etc as a DPI function
|
||||
`endif
|
||||
|
||||
//TODO would like __'s as in {PREFIX}__initial but presently illegal for users to do this
|
||||
import "DPI-C" context function void t_embed_child_initial();
|
||||
import "DPI-C" context function void t_embed_child_final();
|
||||
import "DPI-C" context function void t_embed_child_eval();
|
||||
import "DPI-C" context function void t_embed_child_io_eval
|
||||
(
|
||||
//TODO we support bit, but not logic
|
||||
input bit clk,
|
||||
input bit bit_in,
|
||||
input bit [30:0] vec_in,
|
||||
input bit [123:0] wide_in,
|
||||
input bit is_ref,
|
||||
output bit bit_out,
|
||||
output bit [30:0] vec_out,
|
||||
output bit [123:0] wide_out,
|
||||
output bit did_init_out);
|
||||
|
||||
initial begin
|
||||
// Load all values
|
||||
t_embed_child_initial();
|
||||
end
|
||||
|
||||
// Only if system verilog, and if a "final" block in the code
|
||||
final begin
|
||||
t_embed_child_final();
|
||||
end
|
||||
|
||||
bit _temp_bit_out;
|
||||
bit _temp_did_init_out;
|
||||
bit [30:0] _temp_vec_out;
|
||||
bit [123:0] _temp_wide_out;
|
||||
always @* begin
|
||||
t_embed_child_io_eval(
|
||||
clk,
|
||||
bit_in,
|
||||
vec_in,
|
||||
wide_in,
|
||||
is_ref,
|
||||
_temp_bit_out,
|
||||
_temp_vec_out,
|
||||
_temp_wide_out,
|
||||
_temp_did_init_out
|
||||
);
|
||||
// TODO might eliminate these temporaries
|
||||
bit_out = _temp_bit_out;
|
||||
did_init_out = _temp_did_init_out;
|
||||
end
|
||||
|
||||
|
||||
// Send all variables every cycle,
|
||||
// or have a sensitivity routine for each?
|
||||
// How to make sure we call eval at end of variable changes?
|
||||
// #0 (though not verilator compatible!)
|
||||
|
||||
// TODO for now, we know what changes when
|
||||
always @ (posedge clk) begin
|
||||
vec_out <= _temp_vec_out;
|
||||
wide_out <= _temp_wide_out;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -3,6 +3,13 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2009 by Wilson Snyder.
|
||||
|
||||
typedef enum logic [4:0]
|
||||
{
|
||||
BIT0 = 5'd0,
|
||||
BIT1 = 5'd1,
|
||||
BIT2 = 5'd2
|
||||
} three_t;
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
localparam FIVE = 5;
|
||||
@@ -50,6 +57,10 @@ module t (/*AUTOARG*/);
|
||||
if ($bits(sized_based_on_enum) != 8) $stop;
|
||||
if ($bits(three_t) != 3) $stop;
|
||||
|
||||
if (FIVE[BIT0] != 1'b1) $stop;
|
||||
if (FIVE[BIT1] != 1'b0) $stop;
|
||||
if (FIVE[BIT2] != 1'b1) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
fails=>1,
|
||||
) if $Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,118 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
//
|
||||
// bug354
|
||||
|
||||
typedef logic [5:0] data_t;
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
|
||||
// Take CRC data and apply to testblock inputs
|
||||
wire rst;
|
||||
data_t iii_in = crc[5:0];
|
||||
data_t jjj_in = crc[11:6];
|
||||
data_t iii_out;
|
||||
data_t jjj_out;
|
||||
logic [1:0] ctl0 = crc[63:62];
|
||||
|
||||
aaa aaa (.*);
|
||||
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {64'h0};
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
sum <= 64'h0;
|
||||
rst <= 1'b0;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
sum <= 64'h0;
|
||||
rst <= 1'b1;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
rst <= 1'b0;
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||
// What checksum will we end up with (above print should match)
|
||||
`define EXPECTED_SUM 64'h4afe43fb79d7b71e
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module bbb
|
||||
(
|
||||
output data_t ggg_out[1:0],
|
||||
input data_t ggg_in [1:0],
|
||||
input [1:0] [1:0] ctl,
|
||||
|
||||
input logic clk,
|
||||
input logic rst
|
||||
);
|
||||
|
||||
genvar i;
|
||||
|
||||
generate
|
||||
for (i=0; i<2; i++) begin: PPP
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
ggg_out[i] <= 6'b0;
|
||||
end
|
||||
else begin
|
||||
if (ctl[i][0]) begin
|
||||
if (ctl[i][1]) begin
|
||||
ggg_out[i] <= ~ggg_in[i];
|
||||
end else begin
|
||||
ggg_out[i] <= ggg_in[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
module aaa
|
||||
(
|
||||
input data_t iii_in,
|
||||
input data_t jjj_in,
|
||||
input [1:0] ctl0,
|
||||
output data_t iii_out,
|
||||
output data_t jjj_out,
|
||||
input logic clk,
|
||||
input logic rst
|
||||
);
|
||||
|
||||
// Below is a bug; {} concat isn't used to make arrays
|
||||
bbb bbb (
|
||||
.ggg_in ({jjj_in, iii_in}),
|
||||
.ggg_out ({jjj_out, iii_out}),
|
||||
.ctl ({{1'b1,ctl0[1]}, {1'b0,ctl0[0]}}),
|
||||
.*);
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user