Fix various round-trip Verilog output, including packed arrays
This commit is contained in:
parent
432d5f851d
commit
929e15fa4c
190
src/V3EmitV.cpp
190
src/V3EmitV.cpp
|
|
@ -28,13 +28,17 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
||||||
// Emit statements and expressions
|
// Emit statements and expressions
|
||||||
|
|
||||||
class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
// MEMBERS
|
// STATE - across all visitors
|
||||||
bool m_suppressSemi = false;
|
|
||||||
const bool m_suppressUnknown = false;
|
const bool m_suppressUnknown = false;
|
||||||
|
|
||||||
|
// STATE - for current visit position (use VL_RESTORER)
|
||||||
AstSenTree* m_sensesp; // Domain for printing one a ALWAYS under a ACTIVE
|
AstSenTree* m_sensesp; // Domain for printing one a ALWAYS under a ACTIVE
|
||||||
|
bool m_suppressSemi = false; // Non-statement, don't print ;
|
||||||
|
bool m_suppressVarSemi = false; // Suppress emitting semicolon for AstVars
|
||||||
|
bool m_arrayPost = false; // Print array information that goes after identifier (vs after)
|
||||||
|
std::deque<AstNodeArrayDType*> m_packedps; // Packed arrays to print with BasicDType
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
|
|
||||||
virtual void puts(const string& str) = 0;
|
virtual void puts(const string& str) = 0;
|
||||||
virtual void putbs(const string& str) = 0;
|
virtual void putbs(const string& str) = 0;
|
||||||
virtual void putfs(AstNode* nodep, const string& str) = 0; // Fileline and node %% mark
|
virtual void putfs(AstNode* nodep, const string& str) = 0; // Fileline and node %% mark
|
||||||
|
|
@ -49,6 +53,20 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
putsNoTracking("\"");
|
putsNoTracking("\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iterateAndCommaConstNull(AstNode* nodep) {
|
||||||
|
for (; nodep; nodep = nodep->nextp()) {
|
||||||
|
iterateConst(nodep);
|
||||||
|
if (nodep->nextp()) puts(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void emitPacked() {
|
||||||
|
for (AstNodeArrayDType* packedp : m_packedps) {
|
||||||
|
puts(" ");
|
||||||
|
iterateConstNull(packedp->rangep());
|
||||||
|
}
|
||||||
|
m_packedps.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
void visit(AstNetlist* nodep) override { iterateAndNextConstNull(nodep->modulesp()); }
|
void visit(AstNetlist* nodep) override { iterateAndNextConstNull(nodep->modulesp()); }
|
||||||
void visit(AstNodeModule* nodep) override {
|
void visit(AstNodeModule* nodep) override {
|
||||||
|
|
@ -58,13 +76,14 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
}
|
}
|
||||||
void visit(AstPort* nodep) override {}
|
void visit(AstPort* nodep) override {}
|
||||||
void visit(AstNodeFTask* nodep) override {
|
void visit(AstNodeFTask* nodep) override {
|
||||||
putfs(nodep, nodep->isFunction() ? "function" : "task");
|
const bool func = nodep->isFunction() || nodep->name() == "new";
|
||||||
|
putfs(nodep, func ? "function" : "task");
|
||||||
puts(" ");
|
puts(" ");
|
||||||
puts(nodep->prettyName());
|
puts(nodep->prettyName());
|
||||||
puts(";\n");
|
puts(";\n");
|
||||||
// Only putfs the first time for each visitor; later for same node is putqs
|
// Only putfs the first time for each visitor; later for same node is putqs
|
||||||
iterateAndNextConstNull(nodep->stmtsp());
|
iterateAndNextConstNull(nodep->stmtsp());
|
||||||
putfs(nodep, nodep->isFunction() ? "endfunction\n" : "endtask\n");
|
putfs(nodep, func ? "endfunction\n" : "endtask\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(AstBegin* nodep) override {
|
void visit(AstBegin* nodep) override {
|
||||||
|
|
@ -169,7 +188,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
}
|
}
|
||||||
void visit(AstSenItem* nodep) override {
|
void visit(AstSenItem* nodep) override {
|
||||||
putfs(nodep, "");
|
putfs(nodep, "");
|
||||||
puts(nodep->edgeType().verilogKwd());
|
if (nodep->edgeType() != VEdgeType::ET_CHANGED) puts(nodep->edgeType().verilogKwd());
|
||||||
if (nodep->sensp()) puts(" ");
|
if (nodep->sensp()) puts(" ");
|
||||||
iterateChildrenConst(nodep);
|
iterateChildrenConst(nodep);
|
||||||
}
|
}
|
||||||
|
|
@ -221,13 +240,13 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
putfs(nodep, nodep->verilogKwd());
|
putfs(nodep, nodep->verilogKwd());
|
||||||
putbs("(");
|
putbs("(");
|
||||||
if (fileOrStrgp) {
|
if (fileOrStrgp) {
|
||||||
iterateAndNextConstNull(fileOrStrgp);
|
iterateConstNull(fileOrStrgp);
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
}
|
}
|
||||||
putsQuoted(text);
|
putsQuoted(text);
|
||||||
for (AstNode* expp = exprsp; expp; expp = expp->nextp()) {
|
for (AstNode* expp = exprsp; expp; expp = expp->nextp()) {
|
||||||
puts(", ");
|
puts(", ");
|
||||||
iterateAndNextConstNull(expp);
|
iterateConstNull(expp);
|
||||||
}
|
}
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
|
|
@ -393,7 +412,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
}
|
}
|
||||||
void visit(AstTextBlock* nodep) override {
|
void visit(AstTextBlock* nodep) override {
|
||||||
visit(static_cast<AstNodeSimpleText*>(nodep));
|
visit(static_cast<AstNodeSimpleText*>(nodep));
|
||||||
VL_RESTORER(m_suppressSemi);
|
VL_RESTORER(m_suppressVarSemi);
|
||||||
m_suppressVarSemi = nodep->commas();
|
m_suppressVarSemi = nodep->commas();
|
||||||
for (AstNode* childp = nodep->nodesp(); childp; childp = childp->nextp()) {
|
for (AstNode* childp = nodep->nodesp(); childp; childp = childp->nextp()) {
|
||||||
iterateConst(childp);
|
iterateConst(childp);
|
||||||
|
|
@ -403,17 +422,17 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
void visit(AstScopeName* nodep) override {}
|
void visit(AstScopeName* nodep) override {}
|
||||||
void visit(AstCStmt* nodep) override {
|
void visit(AstCStmt* nodep) override {
|
||||||
putfs(nodep, "$_CSTMT(");
|
putfs(nodep, "$_CSTMT(");
|
||||||
iterateAndNextConstNull(nodep->exprsp());
|
iterateAndCommaConstNull(nodep->exprsp());
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
void visit(AstCExpr* nodep) override {
|
void visit(AstCExpr* nodep) override {
|
||||||
putfs(nodep, "$_CEXPR(");
|
putfs(nodep, "$_CEXPR(");
|
||||||
iterateAndNextConstNull(nodep->exprsp());
|
iterateAndCommaConstNull(nodep->exprsp());
|
||||||
puts(")");
|
puts(")");
|
||||||
}
|
}
|
||||||
void visit(AstUCStmt* nodep) override {
|
void visit(AstUCStmt* nodep) override {
|
||||||
putfs(nodep, "$c(");
|
putfs(nodep, "$c(");
|
||||||
iterateAndNextConstNull(nodep->exprsp());
|
iterateAndCommaConstNull(nodep->exprsp());
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
void visit(AstUCFunc* nodep) override {
|
void visit(AstUCFunc* nodep) override {
|
||||||
|
|
@ -431,19 +450,13 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
void visit(AstCMethodHard* nodep) override {
|
void visit(AstCMethodHard* nodep) override {
|
||||||
iterateConst(nodep->fromp());
|
iterateConst(nodep->fromp());
|
||||||
puts("." + nodep->name() + "(");
|
puts("." + nodep->name() + "(");
|
||||||
for (AstNode* pinp = nodep->pinsp(); pinp; pinp = pinp->nextp()) {
|
iterateAndCommaConstNull(nodep->pinsp());
|
||||||
if (pinp != nodep->pinsp()) puts(", ");
|
|
||||||
iterateConst(pinp);
|
|
||||||
}
|
|
||||||
puts(")");
|
puts(")");
|
||||||
}
|
}
|
||||||
void visit(AstCMethodCall* nodep) override {
|
void visit(AstCMethodCall* nodep) override {
|
||||||
iterateConst(nodep->fromp());
|
iterateConst(nodep->fromp());
|
||||||
puts("." + nodep->name() + "(");
|
puts("." + nodep->name() + "(");
|
||||||
for (AstNode* pinp = nodep->argsp(); pinp; pinp = pinp->nextp()) {
|
iterateAndCommaConstNull(nodep->argsp());
|
||||||
if (pinp != nodep->argsp()) puts(", ");
|
|
||||||
iterateConst(pinp);
|
|
||||||
}
|
|
||||||
puts(")");
|
puts(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -565,13 +578,15 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
puts(cvtToStr(nodep->leftConst()));
|
puts(cvtToStr(nodep->leftConst()));
|
||||||
puts(":");
|
puts(":");
|
||||||
puts(cvtToStr(nodep->rightConst()));
|
puts(cvtToStr(nodep->rightConst()));
|
||||||
puts("]");
|
|
||||||
} else {
|
} else {
|
||||||
iterateAndNextConstNull(nodep->leftp());
|
iterateAndNextConstNull(nodep->leftp());
|
||||||
puts(":");
|
puts(":");
|
||||||
iterateAndNextConstNull(nodep->rightp());
|
iterateAndNextConstNull(nodep->rightp());
|
||||||
puts("]");
|
|
||||||
}
|
}
|
||||||
|
puts("]");
|
||||||
|
}
|
||||||
|
void visit(AstRand* nodep) override {
|
||||||
|
emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->seedp());
|
||||||
}
|
}
|
||||||
void visit(AstSel* nodep) override {
|
void visit(AstSel* nodep) override {
|
||||||
iterateAndNextConstNull(nodep->fromp());
|
iterateAndNextConstNull(nodep->fromp());
|
||||||
|
|
@ -603,17 +618,31 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
}
|
}
|
||||||
void visit(AstTypedef* nodep) override {
|
void visit(AstTypedef* nodep) override {
|
||||||
putfs(nodep, "typedef ");
|
putfs(nodep, "typedef ");
|
||||||
iterateAndNextConstNull(nodep->subDTypep());
|
iterateConstNull(nodep->subDTypep());
|
||||||
puts(" ");
|
puts(" ");
|
||||||
puts(nodep->prettyName());
|
puts(nodep->prettyName());
|
||||||
puts(";\n");
|
puts(";\n");
|
||||||
}
|
}
|
||||||
|
void visit(AstAssocArrayDType* nodep) override {
|
||||||
|
if (!m_arrayPost) {
|
||||||
|
iterateConst(nodep->subDTypep());
|
||||||
|
} else {
|
||||||
|
VL_RESTORER(m_arrayPost);
|
||||||
|
m_arrayPost = false;
|
||||||
|
puts("[");
|
||||||
|
iterateConst(nodep->keyDTypep());
|
||||||
|
puts("]");
|
||||||
|
m_arrayPost = true;
|
||||||
|
iterateConst(nodep->subDTypep()); // For post's key
|
||||||
|
}
|
||||||
|
}
|
||||||
void visit(AstBasicDType* nodep) override {
|
void visit(AstBasicDType* nodep) override {
|
||||||
|
if (m_arrayPost) return;
|
||||||
putfs(nodep, nodep->prettyName());
|
putfs(nodep, nodep->prettyName());
|
||||||
if (nodep->isSigned()) putfs(nodep, " signed");
|
if (nodep->isSigned() && !nodep->keyword().isDouble()) putfs(nodep, " signed");
|
||||||
// Do not emit ranges for integer atoms.
|
// Do not emit ranges for integer atoms.
|
||||||
if (nodep->keyword().isIntNumeric() && !nodep->keyword().isBitLogic()) return;
|
if (nodep->keyword().isIntNumeric() && !nodep->keyword().isBitLogic()) return;
|
||||||
|
emitPacked();
|
||||||
if (nodep->rangep()) {
|
if (nodep->rangep()) {
|
||||||
puts(" ");
|
puts(" ");
|
||||||
iterateAndNextConstNull(nodep->rangep());
|
iterateAndNextConstNull(nodep->rangep());
|
||||||
|
|
@ -627,12 +656,50 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void visit(AstConstDType* nodep) override {
|
void visit(AstConstDType* nodep) override {
|
||||||
|
if (m_arrayPost) return;
|
||||||
putfs(nodep, "const ");
|
putfs(nodep, "const ");
|
||||||
iterateConst(nodep->subDTypep());
|
iterateConst(nodep->subDTypep());
|
||||||
}
|
}
|
||||||
void visit(AstNodeArrayDType* nodep) override {
|
void visit(AstDynArrayDType* nodep) override {
|
||||||
|
if (!m_arrayPost) {
|
||||||
|
iterateConst(nodep->subDTypep());
|
||||||
|
} else {
|
||||||
|
puts("[]");
|
||||||
|
iterateConst(nodep->subDTypep()); // For post's key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void visit(AstEnumDType* nodep) override {
|
||||||
|
if (m_arrayPost) return;
|
||||||
|
putfs(nodep, "enum ");
|
||||||
iterateConst(nodep->subDTypep());
|
iterateConst(nodep->subDTypep());
|
||||||
iterateAndNextConstNull(nodep->rangep());
|
puts("{\n");
|
||||||
|
iterateAndNextConstNull(nodep->itemsp());
|
||||||
|
puts("}");
|
||||||
|
}
|
||||||
|
void visit(AstEnumItem* nodep) override {
|
||||||
|
putfs(nodep, nodep->name());
|
||||||
|
iterateConstNull(nodep->rangep());
|
||||||
|
puts(" = ");
|
||||||
|
iterateConstNull(nodep->valuep());
|
||||||
|
if (nodep->nextp()) puts(",");
|
||||||
|
puts("\n");
|
||||||
|
}
|
||||||
|
void visit(AstNodeArrayDType* nodep) override {
|
||||||
|
if (!m_arrayPost) {
|
||||||
|
if (VN_IS(nodep, PackArrayDType)) {
|
||||||
|
// Unpacked ranges handled in BasicDType, as they print "backwards"
|
||||||
|
m_packedps.push_back(nodep);
|
||||||
|
}
|
||||||
|
iterateConst(nodep->subDTypep());
|
||||||
|
} else {
|
||||||
|
if (VN_IS(nodep, UnpackArrayDType)) {
|
||||||
|
VL_RESTORER(m_arrayPost);
|
||||||
|
m_arrayPost = false;
|
||||||
|
iterateAndNextConstNull(nodep->rangep());
|
||||||
|
m_arrayPost = true;
|
||||||
|
}
|
||||||
|
iterateConst(nodep->subDTypep()); // For post's key
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void visit(AstRefDType* nodep) override {
|
void visit(AstRefDType* nodep) override {
|
||||||
if (nodep->subDTypep()) {
|
if (nodep->subDTypep()) {
|
||||||
|
|
@ -642,21 +709,43 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void visit(AstNodeUOrStructDType* nodep) override {
|
void visit(AstNodeUOrStructDType* nodep) override {
|
||||||
|
if (m_arrayPost) return;
|
||||||
puts(nodep->verilogKwd() + " ");
|
puts(nodep->verilogKwd() + " ");
|
||||||
if (nodep->packed()) puts("packed ");
|
if (nodep->packed()) puts("packed ");
|
||||||
puts("\n");
|
{
|
||||||
puts("{");
|
puts("{\n");
|
||||||
for (AstMemberDType* itemp = nodep->membersp(); itemp;
|
VL_RESTORER(m_packedps);
|
||||||
itemp = VN_AS(itemp->nextp(), MemberDType)) {
|
m_packedps.clear();
|
||||||
iterateConst(itemp);
|
for (AstMemberDType* itemp = nodep->membersp(); itemp;
|
||||||
puts(";");
|
itemp = VN_AS(itemp->nextp(), MemberDType)) {
|
||||||
|
iterateConst(itemp);
|
||||||
|
}
|
||||||
|
puts("}");
|
||||||
}
|
}
|
||||||
puts("}");
|
emitPacked();
|
||||||
}
|
}
|
||||||
void visit(AstMemberDType* nodep) override {
|
void visit(AstMemberDType* nodep) override {
|
||||||
|
if (m_arrayPost) return;
|
||||||
iterateConst(nodep->subDTypep());
|
iterateConst(nodep->subDTypep());
|
||||||
puts(" ");
|
puts(" ");
|
||||||
puts(nodep->name());
|
puts(nodep->name());
|
||||||
|
puts(";\n");
|
||||||
|
}
|
||||||
|
void visit(AstQueueDType* nodep) override {
|
||||||
|
if (!m_arrayPost) {
|
||||||
|
iterateConst(nodep->subDTypep());
|
||||||
|
} else {
|
||||||
|
VL_RESTORER(m_arrayPost);
|
||||||
|
m_arrayPost = false;
|
||||||
|
puts("[$");
|
||||||
|
if (nodep->boundp()) {
|
||||||
|
puts(":");
|
||||||
|
iterateConst(nodep->boundp());
|
||||||
|
}
|
||||||
|
puts("]");
|
||||||
|
m_arrayPost = true;
|
||||||
|
iterateConst(nodep->subDTypep()); // For post's key
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void visit(AstNodeFTaskRef* nodep) override {
|
void visit(AstNodeFTaskRef* nodep) override {
|
||||||
if (nodep->dotted() != "") {
|
if (nodep->dotted() != "") {
|
||||||
|
|
@ -719,37 +808,23 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
putfs(nodep, nodep->verilogKwd());
|
putfs(nodep, nodep->verilogKwd());
|
||||||
puts(" ");
|
puts(" ");
|
||||||
}
|
}
|
||||||
std::vector<const AstUnpackArrayDType*> unpackps;
|
VL_RESTORER(m_arrayPost);
|
||||||
for (AstNodeDType* dtypep = nodep->dtypep(); dtypep;) {
|
m_arrayPost = false;
|
||||||
dtypep = dtypep->skipRefp();
|
iterateConstNull(nodep->dtypep()); // Dtype part before identifier
|
||||||
if (const AstUnpackArrayDType* const unpackp = VN_CAST(dtypep, UnpackArrayDType)) {
|
puts(" ");
|
||||||
unpackps.push_back(unpackp);
|
puts(nodep->prettyName());
|
||||||
dtypep = unpackp->subDTypep();
|
m_arrayPost = true;
|
||||||
} else {
|
iterateConstNull(nodep->dtypep()); // Dtype part after identifier
|
||||||
iterateConst(dtypep);
|
|
||||||
puts(" ");
|
|
||||||
puts(nodep->prettyName());
|
|
||||||
dtypep = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If nodep is an unpacked array, append unpacked dimensions
|
|
||||||
for (const auto& unpackp : unpackps) {
|
|
||||||
puts("[");
|
|
||||||
puts(cvtToStr(unpackp->rangep()->leftConst()));
|
|
||||||
puts(":");
|
|
||||||
puts(cvtToStr(unpackp->rangep()->rightConst()));
|
|
||||||
puts("]");
|
|
||||||
}
|
|
||||||
puts(m_suppressVarSemi ? "\n" : ";\n");
|
puts(m_suppressVarSemi ? "\n" : ";\n");
|
||||||
}
|
}
|
||||||
void visit(AstActive* nodep) override {
|
void visit(AstActive* nodep) override {
|
||||||
|
VL_RESTORER(m_sensesp);
|
||||||
m_sensesp = nodep->sensesp();
|
m_sensesp = nodep->sensesp();
|
||||||
iterateAndNextConstNull(nodep->stmtsp());
|
iterateAndNextConstNull(nodep->stmtsp());
|
||||||
m_sensesp = nullptr;
|
|
||||||
}
|
}
|
||||||
void visit(AstParseRef* nodep) override { puts(nodep->prettyName()); }
|
void visit(AstParseRef* nodep) override { puts(nodep->prettyName()); }
|
||||||
void visit(AstVarScope*) override {}
|
|
||||||
void visit(AstNodeText*) override {}
|
void visit(AstNodeText*) override {}
|
||||||
|
void visit(AstVarScope*) override {}
|
||||||
void visit(AstTraceDecl*) override {}
|
void visit(AstTraceDecl*) override {}
|
||||||
void visit(AstTraceInc*) override {}
|
void visit(AstTraceInc*) override {}
|
||||||
// NOPs
|
// NOPs
|
||||||
|
|
@ -767,7 +842,6 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool m_suppressVarSemi = false; // Suppress emitting semicolon for AstVars
|
|
||||||
explicit EmitVBaseVisitorConst(bool suppressUnknown, AstSenTree* domainp)
|
explicit EmitVBaseVisitorConst(bool suppressUnknown, AstSenTree* domainp)
|
||||||
: m_suppressUnknown{suppressUnknown}
|
: m_suppressUnknown{suppressUnknown}
|
||||||
, m_sensesp{domainp} {}
|
, m_sensesp{domainp} {}
|
||||||
|
|
|
||||||
|
|
@ -1,94 +1,65 @@
|
||||||
module Vt_debug_emitv_t;
|
module Vt_debug_emitv_t;
|
||||||
input logic clk;
|
input logic clk;
|
||||||
input logic in;
|
input logic in;
|
||||||
typedef
|
typedef enum logic [2:0] {
|
||||||
???? // ENUMDTYPE 't.e_t'
|
ZERO = 3'h0,
|
||||||
|
ONE = 3'h1
|
||||||
???? // ENUMITEM 'ZERO'
|
} e_t;
|
||||||
32'h0
|
typedef struct packed {
|
||||||
???? // ENUMITEM 'ONE'
|
logic [2:0] a;
|
||||||
32'h1int signedstruct packed
|
} ps_t;
|
||||||
{int signed a;}logic signed [2:0] struct
|
typedef struct {
|
||||||
{logic signed [2:0] a;}logicunion
|
logic signed [2:0] a;
|
||||||
{logic a;}struct packed
|
} us_t;
|
||||||
{int signed a;}bit [31:0] const struct packed
|
typedef union {
|
||||||
{int signed a;}const struct packed
|
logic a;
|
||||||
{int signed a;}[0:2]struct
|
} union_t;
|
||||||
{logic signed [2:0] a;}union
|
const struct packed {
|
||||||
{logic a;}int signedint signed[0:2]logic [15:0] logic [15:0] logic [15:0] int signedint signedint signed
|
logic [2:0] a;
|
||||||
???? // QUEUEDTYPE
|
} ps[0:2];
|
||||||
int signedstring
|
struct {
|
||||||
???? // ASSOCARRAYDTYPE
|
logic signed [2:0] a;
|
||||||
int signed
|
} us;
|
||||||
???? // DYNARRAYDTYPE
|
union {
|
||||||
int signedint signedint signedint signedint signedint signedint signedreal signedstringIDatalogic signed [31:0] int signed e_t;
|
logic a;
|
||||||
typedef struct packed
|
} unu;
|
||||||
{int signed a;}logic signed [2:0] struct
|
|
||||||
{logic signed [2:0] a;}logicunion
|
|
||||||
{logic a;}struct packed
|
|
||||||
{int signed a;}bit [31:0] const struct packed
|
|
||||||
{int signed a;}const struct packed
|
|
||||||
{int signed a;}[0:2]struct
|
|
||||||
{logic signed [2:0] a;}union
|
|
||||||
{logic a;}int signedint signed[0:2]logic [15:0] logic [15:0] logic [15:0] int signedint signedint signed
|
|
||||||
???? // QUEUEDTYPE
|
|
||||||
int signedstring
|
|
||||||
???? // ASSOCARRAYDTYPE
|
|
||||||
int signed
|
|
||||||
???? // DYNARRAYDTYPE
|
|
||||||
int signedint signedint signedint signedint signedint signedint signedreal signedstringIDatalogic signed [31:0] int signed ps_t;
|
|
||||||
typedef struct
|
|
||||||
{logic signed [2:0] a;}logicunion
|
|
||||||
{logic a;}struct packed
|
|
||||||
{int signed a;}bit [31:0] const struct packed
|
|
||||||
{int signed a;}const struct packed
|
|
||||||
{int signed a;}[0:2]struct
|
|
||||||
{logic signed [2:0] a;}union
|
|
||||||
{logic a;}int signedint signed[0:2]logic [15:0] logic [15:0] logic [15:0] int signedint signedint signed
|
|
||||||
???? // QUEUEDTYPE
|
|
||||||
int signedstring
|
|
||||||
???? // ASSOCARRAYDTYPE
|
|
||||||
int signed
|
|
||||||
???? // DYNARRAYDTYPE
|
|
||||||
int signedint signedint signedint signedint signedint signedint signedreal signedstringIDatalogic signed [31:0] int signed us_t;
|
|
||||||
typedef union
|
|
||||||
{logic a;}struct packed
|
|
||||||
{int signed a;}bit [31:0] const struct packed
|
|
||||||
{int signed a;}const struct packed
|
|
||||||
{int signed a;}[0:2]struct
|
|
||||||
{logic signed [2:0] a;}union
|
|
||||||
{logic a;}int signedint signed[0:2]logic [15:0] logic [15:0] logic [15:0] int signedint signedint signed
|
|
||||||
???? // QUEUEDTYPE
|
|
||||||
int signedstring
|
|
||||||
???? // ASSOCARRAYDTYPE
|
|
||||||
int signed
|
|
||||||
???? // DYNARRAYDTYPE
|
|
||||||
int signedint signedint signedint signedint signedint signedint signedreal signedstringIDatalogic signed [31:0] int signed union_t;
|
|
||||||
struct packed
|
|
||||||
{int signed a;} ps[0:2];
|
|
||||||
struct
|
|
||||||
{logic signed [2:0] a;} us;
|
|
||||||
union
|
|
||||||
{logic a;} unu;
|
|
||||||
int signed array[0:2];
|
int signed array[0:2];
|
||||||
initial begin
|
initial begin
|
||||||
array = '{0:32'sh1, 1:32'sh2, 2:32'sh3};
|
array = '{0:32'sh1, 1:32'sh2, 2:32'sh3};
|
||||||
end
|
end
|
||||||
|
bit [6:5] [4:3] [2:1] arraymanyd[10:11][12:13][14:15];
|
||||||
logic [15:0] pubflat;
|
logic [15:0] pubflat;
|
||||||
logic [15:0] pubflat_r;
|
logic [15:0] pubflat_r;
|
||||||
logic [15:0] pubflat_w;
|
logic [15:0] pubflat_w;
|
||||||
assign pubflat_w = pubflat;
|
assign pubflat_w = pubflat;
|
||||||
int signed fd;
|
int signed fd;
|
||||||
int signed i;
|
int signed i;
|
||||||
|
int signed q[$];
|
||||||
???? // QUEUEDTYPE
|
int signed qb[$:'sh3];
|
||||||
q;
|
int signed assoc[string];
|
||||||
|
int signed assocassoc[string][real];
|
||||||
???? // ASSOCARRAYDTYPE
|
int signed dyn[];
|
||||||
assoc;
|
typedef struct packed {
|
||||||
|
logic nn1;
|
||||||
???? // DYNARRAYDTYPE
|
} nested_named_t;
|
||||||
dyn;
|
typedef struct packed {
|
||||||
|
struct packed {
|
||||||
|
logic nn2;
|
||||||
|
} nested_anonymous;
|
||||||
|
struct packed {
|
||||||
|
logic nn1;
|
||||||
|
} nested_named;
|
||||||
|
logic [11:10] nn3;
|
||||||
|
} nibble_t;
|
||||||
|
struct packed {
|
||||||
|
struct packed {
|
||||||
|
logic nn2;
|
||||||
|
} nested_anonymous;
|
||||||
|
struct packed {
|
||||||
|
logic nn1;
|
||||||
|
} nested_named;
|
||||||
|
logic [11:10] nn3;
|
||||||
|
} [5:4] nibblearray[3:2];
|
||||||
task t;
|
task t;
|
||||||
$display("stmt");
|
$display("stmt");
|
||||||
endtask
|
endtask
|
||||||
|
|
@ -111,7 +82,7 @@ module Vt_debug_emitv_t;
|
||||||
begin
|
begin
|
||||||
other = f(i);
|
other = f(i);
|
||||||
$display("stmt %~ %~",
|
$display("stmt %~ %~",
|
||||||
iother, other);
|
i, other);
|
||||||
t();
|
t();
|
||||||
end
|
end
|
||||||
i = (i + 'h1);
|
i = (i + 'h1);
|
||||||
|
|
@ -128,7 +99,7 @@ module Vt_debug_emitv_t;
|
||||||
$display("stmt");
|
$display("stmt");
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
always @([changed] in) begin
|
always @( in) begin
|
||||||
begin
|
begin
|
||||||
$display("stmt");
|
$display("stmt");
|
||||||
end
|
end
|
||||||
|
|
@ -147,7 +118,7 @@ module Vt_debug_emitv_t;
|
||||||
int signed cyc;
|
int signed cyc;
|
||||||
int signed fo;
|
int signed fo;
|
||||||
int signed sum;
|
int signed sum;
|
||||||
real signed r;
|
real r;
|
||||||
string str;
|
string str;
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
begin
|
begin
|
||||||
|
|
@ -156,7 +127,7 @@ module Vt_debug_emitv_t;
|
||||||
fo = cyc;
|
fo = cyc;
|
||||||
sub.inc(fosum);
|
sub.inc(fosum);
|
||||||
sum = sub.f(sum);
|
sum = sub.f(sum);
|
||||||
$display("[%0t] sum = %~", $timesum, sum);
|
$display("[%0t] sum = %~", $time, sum);
|
||||||
$display("a?= %d", ($c('sh1) ? $c('sh14)
|
$display("a?= %d", ($c('sh1) ? $c('sh14)
|
||||||
: $c('sh1e)));
|
: $c('sh1e)));
|
||||||
$c(;);
|
$c(;);
|
||||||
|
|
@ -248,32 +219,23 @@ module Vt_debug_emitv_t;
|
||||||
else begin
|
else begin
|
||||||
$display("0");
|
$display("0");
|
||||||
end
|
end
|
||||||
$display("%~%~", $past(cyc)$past(cyc, 'sh1),
|
$display("%~%~", $past(cyc), $past(cyc,
|
||||||
$past(cyc, 'sh1));
|
'sh1));
|
||||||
str = $sformatf("cyc=%~", cyc);
|
str = $sformatf("cyc=%~", cyc);
|
||||||
;
|
;
|
||||||
$display("str = %@", str);
|
$display("str = %@", str);
|
||||||
$display("%% [%t] [%^] to=%o td=%d", $time
|
$display("%% [%t] [%^] to=%o td=%d", $time,
|
||||||
$realtime$time$time, $realtime
|
$realtime, $time, $time);
|
||||||
$time$time, $time$time, $time);
|
|
||||||
$sscanf(40'h666f6f3d35, "foo=%d", i);
|
$sscanf(40'h666f6f3d35, "foo=%d", i);
|
||||||
;
|
;
|
||||||
$printtimescale;
|
$printtimescale;
|
||||||
if ((i != 'sh5)) begin
|
if ((i != 'sh5)) begin
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
sum =
|
sum = $random();
|
||||||
???? // RAND
|
sum = $random('sha);
|
||||||
;
|
sum = $urandom();
|
||||||
sum =
|
sum = $urandom('sha);
|
||||||
???? // RAND
|
|
||||||
'sha;
|
|
||||||
sum =
|
|
||||||
???? // RAND
|
|
||||||
;
|
|
||||||
sum =
|
|
||||||
???? // RAND
|
|
||||||
'sha;
|
|
||||||
if ((PKG_PARAM != 'sh1)) begin
|
if ((PKG_PARAM != 'sh1)) begin
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
|
|
@ -318,8 +280,8 @@ package Vt_debug_emitv___024unit;
|
||||||
member = 'sh1;
|
member = 'sh1;
|
||||||
task method;
|
task method;
|
||||||
endtask
|
endtask
|
||||||
task new;
|
function new;
|
||||||
endtask
|
endfunction
|
||||||
endclass
|
endclass
|
||||||
endpackage
|
endpackage
|
||||||
module Vt_debug_emitv_sub;
|
module Vt_debug_emitv_sub;
|
||||||
|
|
@ -339,7 +301,7 @@ module Vt_debug_emitv_sub;
|
||||||
disable label0;
|
disable label0;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
real signed r;
|
real r;
|
||||||
endmodule
|
endmodule
|
||||||
package Vt_debug_emitv_p;
|
package Vt_debug_emitv_p;
|
||||||
logic pkgvar;
|
logic pkgvar;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,16 @@ test.lint(
|
||||||
# Likewise XML
|
# Likewise XML
|
||||||
v_flags=["--lint-only --dumpi-tree 9 --dumpi-V3EmitV 9 --debug-emitv"])
|
v_flags=["--lint-only --dumpi-tree 9 --dumpi-V3EmitV 9 --debug-emitv"])
|
||||||
|
|
||||||
test.files_identical(test.glob_one(test.obj_dir + "/" + test.vm_prefix + "_*_width.tree.v"),
|
output_v = test.glob_one(test.obj_dir + "/" + test.vm_prefix + "_*_width.tree.v")
|
||||||
test.golden_filename)
|
|
||||||
|
test.files_identical(output_v, test.golden_filename)
|
||||||
|
|
||||||
|
if test.verbose:
|
||||||
|
# Print if that the output Verilog is clean
|
||||||
|
# TODO not yet round-trip clean
|
||||||
|
test.run(cmd=[os.environ["VERILATOR_ROOT"] + "/bin/verilator", "--lint-only", output_v],
|
||||||
|
logfile=test.obj_dir + "/sim_roundtrip.log",
|
||||||
|
fails=True,
|
||||||
|
verilator_run=True)
|
||||||
|
|
||||||
test.passes()
|
test.passes()
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ module t (/*AUTOARG*/
|
||||||
|
|
||||||
// verilator lint_off UNPACKED
|
// verilator lint_off UNPACKED
|
||||||
|
|
||||||
typedef enum {
|
typedef enum [2:0] {
|
||||||
ZERO,
|
ZERO,
|
||||||
ONE = 1
|
ONE = 1
|
||||||
} e_t;
|
} e_t;
|
||||||
|
|
@ -52,19 +52,35 @@ module t (/*AUTOARG*/
|
||||||
us_t us;
|
us_t us;
|
||||||
union_t unu;
|
union_t unu;
|
||||||
|
|
||||||
int array[3];
|
int array[3];
|
||||||
initial array = '{1,2,3};
|
initial array = '{1,2,3};
|
||||||
|
|
||||||
reg [15:0] pubflat /*verilator public_flat_rw @(posedge clk) */;
|
bit [6:5][4:3][2:1] arraymanyd[10:11][12:13][14:15];
|
||||||
|
|
||||||
reg [15:0] pubflat_r;
|
reg [15:0] pubflat /*verilator public_flat_rw @(posedge clk) */;
|
||||||
wire [15:0] pubflat_w = pubflat;
|
|
||||||
int fd;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
int q[$];
|
reg [15:0] pubflat_r;
|
||||||
int assoc[string];
|
wire [15:0] pubflat_w = pubflat;
|
||||||
int dyn[];
|
int fd;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
int q[$];
|
||||||
|
int qb[$ : 3];
|
||||||
|
int assoc[string];
|
||||||
|
int assocassoc[string][real];
|
||||||
|
int dyn[];
|
||||||
|
|
||||||
|
typedef struct packed {
|
||||||
|
logic nn1;
|
||||||
|
} nested_named_t;
|
||||||
|
typedef struct packed {
|
||||||
|
struct packed {
|
||||||
|
logic nn2;
|
||||||
|
} nested_anonymous;
|
||||||
|
nested_named_t nested_named;
|
||||||
|
logic [11:10] nn3;
|
||||||
|
} nibble_t;
|
||||||
|
nibble_t [5:4] nibblearray[3:2];
|
||||||
|
|
||||||
task t;
|
task t;
|
||||||
$display("stmt");
|
$display("stmt");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue