From 00759f777e3d83b101d235e072ec65219f1afd9e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 16 Jun 2015 19:27:18 -0400 Subject: [PATCH] Fix dpi imports inside generates. --- Changes | 2 ++ src/V3AstNodes.cpp | 26 +++----------------- src/V3AstNodes.h | 9 ++++--- src/V3EmitC.cpp | 2 +- src/V3EmitCSyms.cpp | 8 ++++-- test_regress/t/t_dpi_imp_gen.pl | 19 +++++++++++++++ test_regress/t/t_dpi_imp_gen.v | 33 +++++++++++++++++++++++++ test_regress/t/t_dpi_imp_gen_c.cpp | 39 ++++++++++++++++++++++++++++++ 8 files changed, 110 insertions(+), 28 deletions(-) create mode 100755 test_regress/t/t_dpi_imp_gen.pl create mode 100644 test_regress/t/t_dpi_imp_gen.v create mode 100644 test_regress/t/t_dpi_imp_gen_c.cpp diff --git a/Changes b/Changes index 7129dd0b9..d8a4ebd6f 100644 --- a/Changes +++ b/Changes @@ -11,6 +11,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix string-to-int space conversion, bug931. [Fabrizio Ferrandi] +**** Fix dpi imports inside generates. [Michael Tresidder] + * Verilator 3.874 2015-06-06 diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index ed0907d27..1931330e5 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -506,9 +506,9 @@ string AstScope::nameDotless() const { return out; } -string AstScopeName::scopePrettyName() const { +string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const { string out; - for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) { + for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) { out += textp->text(); } // TOP will be replaced by top->name() @@ -518,27 +518,9 @@ string AstScopeName::scopePrettyName() const { return AstNode::prettyName(out); } -string AstScopeName::scopeSymName() const { +string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const { string out; - for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) { - out += textp->text(); - } - if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,""); - if (out.substr(0,7) == "__DOT__") out.replace(0,7,""); - if (out.substr(0,1) == ".") out.replace(0,1,""); - string::size_type pos; - while ((pos=out.find(".")) != string::npos) { - out.replace(pos, 1, "__"); - } - while ((pos=out.find("__DOT__")) != string::npos) { - out.replace(pos, 7, "__"); - } - return out; -} - -string AstScopeName::scopeDpiName() const { - string out; - for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) { + for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) { out += textp->text(); } if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,""); diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 184234c31..eb40e6bd8 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -3067,6 +3067,8 @@ class AstScopeName : public AstNodeMath { // Children: TEXT private: bool m_dpiExport; // Is for dpiExport + string scopeNameFormatter(AstText* textp) const; + string scopePrettyNameFormatter(AstText* textp) const; public: AstScopeName(FileLine* fl) : AstNodeMath(fl), m_dpiExport(false) { dtypeSetUInt64(); } @@ -3080,9 +3082,10 @@ public: void scopeAttrp(AstNode* nodep) { addOp1p(nodep); } AstText* scopeEntrp() const { return op2p()->castText(); } void scopeEntrp(AstNode* nodep) { addOp2p(nodep); } - string scopeSymName() const; // Name for __Vscope variable including children - string scopeDpiName() const; // Name for DPI import scope - string scopePrettyName() const; // Name for __Vscope printing + string scopeSymName() const { return scopeNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children + string scopeDpiName() const { return scopeNameFormatter(scopeEntrp()); } // Name for DPI import scope + string scopePrettySymName() const { return scopePrettyNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children + string scopePrettyDpiName() const { return scopePrettyNameFormatter(scopeEntrp()); } // Name for __Vscope variable including children bool dpiExport() const { return m_dpiExport; } void dpiExport(bool flag) { m_dpiExport=flag; } }; diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 4f9bd928b..642444b11 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -1351,7 +1351,7 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, case 'g': displayArg(nodep,&elistp,isScan, vfmt,'g'); break; case 'm': { if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName"); - string suffix = scopenamep->scopePrettyName(); + string suffix = scopenamep->scopePrettySymName(); if (suffix=="") emitDispState.pushFormat("%S"); else emitDispState.pushFormat("%N"); // Add a . when needed emitDispState.pushArg(' ',NULL, "vlSymsp->name()"); diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 152e9658c..88a010ad2 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -193,14 +193,18 @@ class EmitCSyms : EmitCBaseVisitor { } virtual void visit(AstScopeName* nodep, AstNUser*) { string name = nodep->scopeSymName(); - //UINFO(9,"scnameins sp "<name()<<" sp "<scopePrettyName()<<" ss "<name()<<" sp "<scopePrettySymName()<<" ss "<scopePrettyName()))); + m_scopeNames.insert(make_pair(name, ScopeNameData(name, nodep->scopePrettySymName()))); } if (nodep->dpiExport()) { if (!m_funcp) nodep->v3fatalSrc("ScopeName not under DPI function"); m_scopeFuncs.insert(make_pair(name + " " + m_funcp->name(), ScopeFuncData(nodep, m_funcp, m_modp))); + } else { + if (m_scopeNames.find(nodep->scopeDpiName()) == m_scopeNames.end()) { + m_scopeNames.insert(make_pair(nodep->scopeDpiName(), ScopeNameData(nodep->scopeDpiName(), nodep->scopePrettyDpiName()))); + } } } virtual void visit(AstVar* nodep, AstNUser*) { diff --git a/test_regress/t/t_dpi_imp_gen.pl b/test_regress/t/t_dpi_imp_gen.pl new file mode 100755 index 000000000..15fc697c3 --- /dev/null +++ b/test_regress/t/t_dpi_imp_gen.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 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. + +compile ( + v_flags2 => ["t/t_dpi_imp_gen_c.cpp"], + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_dpi_imp_gen.v b/test_regress/t/t_dpi_imp_gen.v new file mode 100644 index 000000000..1a6527c1c --- /dev/null +++ b/test_regress/t/t_dpi_imp_gen.v @@ -0,0 +1,33 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2009 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. + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + parameter integer BLKS = 3; + + generate + for (genvar blkIdx=0; blkIdx < BLKS; blkIdx=blkIdx+1 ) begin : slice + + import "DPI-C" context function void dpi_genvarTest (); + + initial begin + dpi_genvarTest(); + $display("slice = %0d : %m", blkIdx); + end + end + endgenerate + + always @ (posedge clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_dpi_imp_gen_c.cpp b/test_regress/t/t_dpi_imp_gen_c.cpp new file mode 100644 index 000000000..4994f08a2 --- /dev/null +++ b/test_regress/t/t_dpi_imp_gen_c.cpp @@ -0,0 +1,39 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +// +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2009 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. +//************************************************************************* + +#include +#include +#include "svdpi.h" + +//====================================================================== + +#if defined(VERILATOR) +# include "Vt_dpi_imp_gen__Dpi.h" +#elif defined(VCS) +# include "../vc_hdrs.h" +#elif defined(CADENCE) +# define NEED_EXTERNS +#else +# error "Unknown simulator for DPI test" +#endif + +#ifdef NEED_EXTERNS +extern "C" { + extern void dpi_genvarTest(); +} +#endif + +//====================================================================== + +// Called from our Verilog code to run the tests +void dpi_genvarTest () { + const char *scopeName = svGetNameFromScope(svGetScope()); + printf("scope name : %s\n", scopeName); +}