Merge branch 'work13a'

This commit is contained in:
Stephen Williams 2013-03-04 08:59:50 -08:00
commit 64401ab815
27 changed files with 420 additions and 75 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 1998-2012 Stephen Williams <steve@icarus.com>
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -305,12 +306,18 @@ const verireal& PEFNumber::value() const
}
PEIdent::PEIdent(const pform_name_t&that)
: path_(that), no_implicit_sig_(false)
: package_(0), path_(that), no_implicit_sig_(false)
{
}
PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
: no_implicit_sig_(no_implicit_sig)
: package_(0), no_implicit_sig_(no_implicit_sig)
{
path_.push_back(name_component_t(s));
}
PEIdent::PEIdent(PPackage*pkg, perm_string s)
: package_(pkg), no_implicit_sig_(true)
{
path_.push_back(name_component_t(s));
}

View File

@ -2,6 +2,7 @@
#define __PExpr_H
/*
* Copyright (c) 1998-2011 Stephen Williams <steve@icarus.com>
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -33,6 +34,7 @@ class LexicalScope;
class NetNet;
class NetExpr;
class NetScope;
class PPackage;
/*
* The PExpr class hierarchy supports the description of
@ -286,6 +288,7 @@ class PEIdent : public PExpr {
public:
explicit PEIdent(perm_string, bool no_implicit_sig=false);
explicit PEIdent(PPackage*pkg, perm_string name);
explicit PEIdent(const pform_name_t&);
~PEIdent();
@ -329,6 +332,7 @@ class PEIdent : public PExpr {
const pform_name_t& path() const { return path_; }
private:
PPackage*package_;
pform_name_t path_;
bool no_implicit_sig_;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012 Picture Elements, Inc.
* Stephen Williams (steve@icarus.com)
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU

View File

@ -2,6 +2,7 @@
#define __PPackage_H
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -22,6 +23,7 @@
# include "PScope.h"
# include "LineInfo.h"
# include "StringHeap.h"
# include <iostream>
/*
* SystemVerilog supports class declarations with their own lexical
@ -35,6 +37,9 @@ class PPackage : public PScopeExtra, public LineInfo {
explicit PPackage (perm_string name, LexicalScope*parent);
~PPackage();
bool elaborate_scope(Design*des, NetScope*scope);
void pform_dump(std::ostream&out) const;
};
#endif

View File

@ -28,6 +28,7 @@
class PEvent;
class PExpr;
class PFunction;
class PPackage;
class AProcess;
class PProcess;
class PClass;
@ -92,6 +93,10 @@ class LexicalScope {
// Named events in the scope.
map<perm_string,PEvent*>events;
// Symbols that are imported. Bind the imported name to the
// package from which the name is imported.
std::map<perm_string,PPackage*>imports;
// Nets and variables (wires) in the scope
map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);

View File

@ -1643,10 +1643,18 @@ void NetEUnary::dump(ostream&o) const
void Design::dump(ostream&o) const
{
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
o << "PACKAGES:" << endl;
for (map<perm_string,NetScope*>::const_iterator cur = packages_.begin()
; cur != packages_.end() ; ++cur) {
cur->second->dump(o);
}
o << "SCOPES:" << endl;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); ++ scope )
scope != root_scopes_.end(); ++ scope ) {
(*scope)->dump(o);
}
o << "ELABORATED NODES:" << endl;

View File

@ -24,6 +24,7 @@
# include <climits>
# include "compiler.h"
# include "PPackage.h"
# include "pform.h"
# include "netlist.h"
# include "netclass.h"
@ -2410,7 +2411,14 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
const NetExpr*ex1, *ex2;
NetScope*found_in = symbol_search(this, des, scope, path_, net, par, eve,
NetScope*use_scope = scope;
if (package_) {
use_scope = des->find_package(package_->pscope_name());
ivl_assert(*this, use_scope);
}
NetScope*found_in = symbol_search(this, des, use_scope, path_,
net, par, eve,
ex1, ex2);
// If there is a part/bit select expression, then process it
@ -2610,7 +2618,13 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
NetEvent* eve = 0;
const NetExpr*ex1, *ex2;
/* NetScope*found_in = */ symbol_search(this, des, scope, path_,
NetScope*use_scope = scope;
if (package_) {
use_scope = des->find_package(package_->pscope_name());
ivl_assert(*this, use_scope);
}
/* NetScope*found_in = */ symbol_search(this, des, use_scope, path_,
net, par, eve,
ex1, ex2);
@ -2718,7 +2732,13 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
if (debug_elaborate)
cerr << get_fileline() << ": PEIdent::elaborate_expr: path_=" << path_ << endl;
NetScope*found_in = symbol_search(this, des, scope, path_,
NetScope*use_scope = scope;
if (package_) {
use_scope = des->find_package(package_->pscope_name());
ivl_assert(*this, use_scope);
}
NetScope*found_in = symbol_search(this, des, use_scope, path_,
net, par, eve,
ex1, ex2);

View File

@ -39,6 +39,7 @@
# include "PClass.h"
# include "PGate.h"
# include "PGenerate.h"
# include "PPackage.h"
# include "PTask.h"
# include "PWire.h"
# include "Statement.h"
@ -495,6 +496,18 @@ class generate_schemes_work_item_t : public elaborator_work_item_t {
Module*mod_;
};
bool PPackage::elaborate_scope(Design*des, NetScope*scope)
{
if (debug_scopes) {
cerr << get_fileline() << ": debug: Elaborate package scope "
<< scope_path(scope) << "." << endl;
}
collect_scope_parameters_(des, scope, parameters);
return true;
}
bool Module::elaborate_scope(Design*des, NetScope*scope,
const replace_t&replacements)
{

View File

@ -33,6 +33,7 @@
# include "pform.h"
# include "PEvent.h"
# include "PGenerate.h"
# include "PPackage.h"
# include "PSpec.h"
# include "netlist.h"
# include "netvector.h"
@ -4860,6 +4861,25 @@ struct root_elem {
NetScope *scope;
};
class elaborate_package_t : public elaborator_work_item_t {
public:
elaborate_package_t(Design*d, NetScope*scope, PPackage*p)
: elaborator_work_item_t(d), scope_(scope), package_(p)
{ }
~elaborate_package_t() { }
virtual void elaborate_runrun()
{
if (! package_->elaborate_scope(des, scope_))
des->errors += 1;
}
private:
NetScope*scope_;
PPackage*package_;
};
class elaborate_root_scope_t : public elaborator_work_item_t {
public:
elaborate_root_scope_t(Design*des__, NetScope*scope, Module*rmod)
@ -5022,6 +5042,18 @@ Design* elaborate(list<perm_string>roots)
// module and elaborate what I find.
Design*des = new Design;
// Elaborate the packages. Package elaboration is simpler
// because there are fewer sub-scopes involved.
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
; pac != pform_packages.end() ; ++ pac) {
NetScope*scope = des->make_package_scope(pac->first);
scope->set_line(pac->second);
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
des->elaboration_work_list.push_back(es);
}
// Scan the root modules by name, and elaborate their scopes.
for (list<perm_string>::const_iterator root = roots.begin()
; root != roots.end() ; ++ root ) {

View File

@ -353,7 +353,8 @@ typedef enum ivl_scope_type_e {
IVL_SCT_TASK = 2,
IVL_SCT_BEGIN = 3,
IVL_SCT_FORK = 4,
IVL_SCT_GENERATE= 5
IVL_SCT_GENERATE= 5,
IVL_SCT_PACKAGE = 6
} ivl_scope_type_t;
/* Signals (ivl_signal_t) that are ports into the scope that contains

View File

@ -47,8 +47,12 @@ struct ivl_design_s {
ivl_process_t threads_;
ivl_scope_t *roots_;
unsigned nroots_;
// Keep arrays of root scopes.
std::vector<ivl_scope_t> packages;
std::vector<ivl_scope_t> roots;
// This is used to implement the ivl_design_roots function.
std::vector<ivl_scope_t> root_scope_list;
// Keep an array of constants objects.
std::valarray<ivl_net_const_t> consts;

View File

@ -987,6 +987,12 @@ int main(int argc, char*argv[])
; cur != disciplines.end() ; ++ cur ) {
pform_dump(out, (*cur).second);
}
out << "PFORM DUMP PACKAGES:" << endl;
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
; pac != pform_packages.end() ; ++ pac) {
pform_dump(out, pac->second);
}
out << "PFORM DUMP MODULES:" << endl;
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
; mod != pform_modules.end() ; ++ mod ) {

View File

@ -119,14 +119,39 @@ NetScope* Design::find_root_scope()
return root_scopes_.front();
}
list<NetScope*> Design::find_root_scopes()
list<NetScope*> Design::find_root_scopes() const
{
return root_scopes_;
}
const list<NetScope*> Design::find_root_scopes() const
NetScope* Design::make_package_scope(perm_string name)
{
return root_scopes_;
NetScope*scope;
scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, false, false);
scope->set_module_name(scope->basename());
packages_[name] = scope;
return scope;
}
NetScope* Design::find_package(perm_string name) const
{
map<perm_string,NetScope*>::const_iterator cur = packages_.find(name);
if (cur == packages_.end())
return 0;
return cur->second;
}
list<NetScope*> Design::find_package_scopes() const
{
list<NetScope*>res;
for (map<perm_string,NetScope*>::const_iterator cur = packages_.begin()
; cur != packages_.end() ; ++cur) {
res.push_back (cur->second);
}
return res;
}
/*

View File

@ -60,7 +60,7 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest, bo
time_unit_ = 0;
time_prec_ = 0;
time_from_timescale_ = false;
assert(t == MODULE);
assert(t==MODULE || t==PACKAGE);
}
switch (t) {
@ -71,6 +71,7 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest, bo
func_ = 0;
break;
case NetScope::MODULE:
case NetScope::PACKAGE:
module_name_ = perm_string();
break;
default: /* BEGIN_END and FORK_JOIN, do nothing */
@ -301,8 +302,7 @@ void NetScope::print_type(ostream&stream) const
stream << "function";
break;
case MODULE:
stream << "module <" << (module_name_ ? module_name_.str() : "")
<< "> instance";
stream << "module <" << module_name_ << "> instance";
break;
case TASK:
stream << "task";
@ -310,6 +310,9 @@ void NetScope::print_type(ostream&stream) const
case GENBLOCK:
stream << "generate block";
break;
case PACKAGE:
stream << "package " << module_name_;
break;
}
}
@ -358,13 +361,13 @@ const NetFuncDef* NetScope::func_def() const
void NetScope::set_module_name(perm_string n)
{
assert(type_ == MODULE);
module_name_ = n; /* NOTE: n must have been permallocated. */
assert(type_==MODULE || type_==PACKAGE);
module_name_ = n;
}
perm_string NetScope::module_name() const
{
assert(type_ == MODULE);
assert(type_==MODULE || type_==PACKAGE);
return module_name_;
}

View File

@ -2,6 +2,7 @@
#define __netlist_H
/*
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -763,7 +764,7 @@ class NetNet : public NetObj, public PortType {
class NetScope : public Attrib {
public:
enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK };
enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE };
/* Create a new scope, and attach it to the given parent. The
name is expected to have been permallocated. */
@ -4281,9 +4282,10 @@ class Design {
NetScope* make_root_scope(perm_string name, bool program_block);
NetScope* find_root_scope();
list<NetScope*> find_root_scopes();
std::list<NetScope*> find_root_scopes() const;
const list<NetScope*> find_root_scopes() const;
NetScope* make_package_scope(perm_string name);
std::list<NetScope*> find_package_scopes() const;
/* Attempt to set the precision to the specified value. If the
precision is already more precise, the keep the precise
@ -4304,6 +4306,9 @@ class Design {
NetScope* find_scope(const hname_t&path) const;
NetScope* find_scope(NetScope*, const hname_t&name,
NetScope::TYPE type = NetScope::MODULE) const;
NetScope* find_package(perm_string name) const;
// Note: Try to remove these versions of find_scope. Avoid
// using these in new code, use the above forms (or
// symbol_search) instead.
@ -4372,6 +4377,10 @@ class Design {
// tree and per-hop searches for me.
list<NetScope*>root_scopes_;
// Keep a map of all the elaborated packages. Note that
// packages do not nest.
std::map<perm_string,NetScope*>packages_;
// List the nodes in the design.
NetNode*nodes_;
// These are in support of the node functor iterator.

20
parse.y
View File

@ -1,8 +1,8 @@
%{
/*
* Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -1354,13 +1354,19 @@ package_declaration /* IEEE1800-2005 A.1.2 */
package_import_declaration /* IEEE1800-2005 A.2.1.3 */
: K_import package_import_item_list ';'
{ yyerror(@1, "sorry: Package import declarations not supported.");
}
{ }
;
package_import_item
: IDENTIFIER K_SCOPE_RES IDENTIFIER
{ pform_package_import(@2, $1, $3);
delete[]$1;
delete[]$3;
}
| IDENTIFIER K_SCOPE_RES '*'
{ pform_package_import(@2, $1, 0);
delete[]$1;
}
;
package_import_item_list
@ -1370,6 +1376,7 @@ package_import_item_list
package_item /* IEEE1800-2005 A.1.10 */
: timeunits_declaration
| K_parameter param_type parameter_assign_list ';'
| K_localparam param_type localparam_assign_list ';'
| type_declaration
| function_declaration
@ -2949,12 +2956,15 @@ expr_primary
indexed arrays and part selects */
| hierarchy_identifier
{ PEIdent*tmp = new PEIdent(*$1);
{ PEIdent*tmp = pform_new_ident(*$1);
FILE_NAME(tmp, @1);
$$ = tmp;
delete $1;
}
| IDENTIFIER K_SCOPE_RES IDENTIFIER
{ $$ = pform_package_ident(@3, $1, $3); }
/* An identifier followed by an expression list in parentheses is a
function call. If a system identifier, then a system function
call. */

View File

@ -22,9 +22,11 @@
# include <cstdio>
# include "StringHeap.h"
# include <string>
# include <ostream>
# include <map>
class Module;
class PPackage;
class PUdp;
/*
@ -32,8 +34,11 @@ class PUdp;
* Verilog source into pform for elaboration. The parser adds modules
* to these maps as it compiles modules in the Verilog source.
*/
extern map<perm_string,Module*> pform_modules;
extern map<perm_string,PUdp*> pform_primitives;
extern std::map<perm_string,Module*> pform_modules;
extern std::map<perm_string,PUdp*> pform_primitives;
extern std::map<perm_string,PPackage*> pform_packages;
extern void pform_dump(std::ostream&out, const PPackage*pac);
/*
* This code actually invokes the parser to make modules. The first

View File

@ -294,6 +294,12 @@ static PScopeExtra* find_nearest_scopex(LexicalScope*scope)
return scopex;
}
LexicalScope* pform_peek_scope(void)
{
assert(lexical_scope);
return lexical_scope;
}
PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name)
{
PClass*class_scope = new PClass(name, lexical_scope);
@ -413,6 +419,25 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
return block;
}
/*
* Create a new identifier. Check if this is an imported name.
*/
PEIdent* pform_new_ident(const pform_name_t&name)
{
if (name.size() != 1)
return new PEIdent(name);
LexicalScope*scope = pform_peek_scope();
map<perm_string,PPackage*>::const_iterator pkg = scope->imports.find(name.back().name);
if (pkg == scope->imports.end())
return new PEIdent(name);
// XXXX For now, do not support indexed imported names.
assert(name.back().index.size() == 0);
return new PEIdent(pkg->second, name.back().name);
}
PGenerate* pform_parent_generate(void)
{
return pform_cur_generate;

26
pform.h
View File

@ -187,10 +187,6 @@ extern void pform_class_property(const struct vlltype&loc,
std::list<decl_assignment_t*>*decls);
extern void pform_end_class_declaration(void);
extern void pform_start_package_declaration(const struct vlltype&loc,
const char*type);
extern void pform_end_package_declaration(const struct vlltype&loc);
extern void pform_make_udp(perm_string name, list<perm_string>*parms,
svector<PWire*>*decl, list<string>*table,
Statement*init,
@ -202,6 +198,23 @@ extern void pform_make_udp(perm_string name,
list<perm_string>*parms,
list<string>*table,
const char*file, unsigned lineno);
/*
* Package related functions.
*/
extern void pform_start_package_declaration(const struct vlltype&loc,
const char*type);
extern void pform_end_package_declaration(const struct vlltype&loc);
extern void pform_package_import(const struct vlltype&loc,
const char*pkg_name, const char*ident);
extern PExpr* pform_package_ident(const struct vlltype&loc,
const char*pkg_name, const char*ident);
/*
* This creates an identifier aware of names that may have been
* imported from other packages.
*/
extern PEIdent* pform_new_ident(const pform_name_t&name);
/*
* Enter/exit name scopes. The push_scope function pushes the scope
@ -210,6 +223,11 @@ extern void pform_make_udp(perm_string name,
*/
extern void pform_pop_scope();
/*
* Peek at the current (most recently active) scope.
*/
extern LexicalScope* pform_peek_scope();
extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name);
extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name);
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,

View File

@ -29,6 +29,7 @@
# include "PClass.h"
# include "PEvent.h"
# include "PGenerate.h"
# include "PPackage.h"
# include "PSpec.h"
# include "discipline.h"
# include "ivl_target_priv.h"
@ -303,6 +304,8 @@ void PENumber::dump(ostream&out) const
void PEIdent::dump(ostream&out) const
{
if (package_)
out << package_->pscope_name() << "::";
out << path_;
}
@ -1496,3 +1499,16 @@ void pform_dump(std::ostream&out, const ivl_discipline_s*dis)
out << " flow " << tmp->name() << ";" << endl;
out << "enddiscipline" << endl;
}
void pform_dump(std::ostream&out, const PPackage*pac)
{
pac->pform_dump(out);
}
void PPackage::pform_dump(std::ostream&out) const
{
out << "package " << pscope_name() << endl;
dump_localparams_(out, 4);
dump_parameters_(out, 4);
out << "endpackage" << endl;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -20,23 +21,112 @@
# include "pform.h"
# include "PPackage.h"
# include "parse_misc.h"
# include "parse_api.h"
# include <map>
# include <sstream>
# include "ivl_assert.h"
using namespace std;
/*
* This is a map of packages that have been defined.
*/
map<perm_string,PPackage*> pform_packages;
static PPackage*pform_cur_package = 0;
void pform_start_package_declaration(const struct vlltype&loc, const char*name)
{
VLerror(loc, "sorry: Package declarations not supported.");
ivl_assert(loc, pform_cur_package == 0);
perm_string use_name = lex_strings.make(name);
PPackage*pkg_scope = pform_push_package_scope(loc, use_name);
FILE_NAME(pkg_scope, loc);
pform_cur_package = pkg_scope;
}
void pform_end_package_declaration(const struct vlltype&loc)
{
ivl_assert(loc, pform_cur_package);
perm_string use_name = pform_cur_package->pscope_name();
map<perm_string,PPackage*>::const_iterator test = pform_packages.find(use_name);
if (test != pform_packages.end()) {
ostringstream msg;
msg << "Package " << use_name << " was already declared here: "
<< test->second->get_fileline() << ends;
VLerror(msg.str().c_str());
} else {
pform_packages[use_name] = pform_cur_package;
}
pform_packages[use_name] = pform_cur_package;
pform_cur_package = 0;
pform_pop_scope();
}
/*
* Do the import early, during processing. This requires that the
* package is declared in pform ahead of time (it is) and that we can
* simply transfer definitions to the current scope (we can).
*/
void pform_package_import(const struct vlltype&, const char*pkg_name, const char*ident)
{
perm_string use_name = lex_strings.make(pkg_name);
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
if (pcur == pform_packages.end()) {
ostringstream msg;
msg << "Package " << pkg_name << " not found." << ends;
VLerror(msg.str().c_str());
return;
}
PPackage*pkg = pcur->second;
LexicalScope*scope = pform_peek_scope();
if (ident) {
perm_string use_ident = lex_strings.make(ident);
map<perm_string,LexicalScope::param_expr_t>::const_iterator cur
= pkg->parameters.find(use_ident);
if (cur == pkg->parameters.end()) {
ostringstream msg;
msg << "Symbol " << use_ident
<< " not found in package " << pcur->first << "." << ends;
VLerror(msg.str().c_str());
return;
}
scope->imports[cur->first] = pkg;
} else {
// Handle the pkg::* case by importing everything from
// the package.
for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->parameters.begin()
; cur != pkg->parameters.end() ; ++cur) {
scope->imports[cur->first] = pkg;
}
}
}
PExpr* pform_package_ident(const struct vlltype&loc,
const char*pkg_name, const char*ident_name)
{
perm_string use_name = lex_strings.make(pkg_name);
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
if (pcur == pform_packages.end()) {
ostringstream msg;
msg << "Package " << pkg_name << " not found." << ends;
VLerror(msg.str().c_str());
return 0;
}
assert(pcur->second);
perm_string use_ident = lex_strings.make(ident_name);
PEIdent*tmp = new PEIdent(pcur->second, use_ident);
FILE_NAME(tmp, loc);
return tmp;
}

View File

@ -43,6 +43,7 @@
EXTERN_C_START
/********* OBJECT TYPES ***********/
#define vpiPackage 600
#define vpiLongIntVar 610
#define vpiShortIntVar 611
#define vpiIntVar 612

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -73,16 +74,24 @@ extern "C" ivl_scope_t ivl_design_root(ivl_design_t des)
cerr << "ANACHRONISM: ivl_design_root called. "
"Use ivl_design_roots instead." << endl;
assert (des->nroots_);
return des->roots_[0];
assert (des->roots.size() > 0);
return des->roots[0];
}
extern "C" void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes,
unsigned int *nscopes)
{
assert (nscopes && scopes);
*scopes = &des->roots_[0];
*nscopes = des->nroots_;
if (des->root_scope_list.size() == 0) {
des->root_scope_list.resize(des->packages.size() + des->roots.size());
for (size_t idx = 0 ; idx < des->packages.size() ; idx += 1)
des->root_scope_list[idx] = des->packages[idx];
for (size_t idx = 0 ; idx < des->roots.size() ; idx += 1)
des->root_scope_list[idx+des->packages.size()] = des->roots[idx];
}
*scopes = &des->root_scope_list[0];
*nscopes = des->root_scope_list.size();
}
extern "C" int ivl_design_time_precision(ivl_design_t des)

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -234,10 +235,21 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
{
assert(cur);
// If the scope is a PACKAGE, then it is a special kind of
// root scope and it in the packages array instead.
if (cur->type() == NetScope::PACKAGE) {
perm_string cur_name = cur->module_name();
for (size_t idx = 0 ; idx < des.packages.size() ; idx += 1) {
if (des.packages[idx]->name_ = cur_name)
return des.packages[idx];
}
return 0;
}
ivl_scope_t scope = 0;
for (unsigned i = 0; i < des.nroots_ && scope == 0; i += 1) {
assert(des.roots_[i]);
scope = find_scope_from_root(des.roots_[i], cur);
for (unsigned i = 0; i < des.roots.size() && scope == 0; i += 1) {
assert(des.roots[i]);
scope = find_scope_from_root(des.roots[i], cur);
}
return scope;
}
@ -537,7 +549,7 @@ void dll_target::add_root(ivl_design_s &des__, const NetScope *s)
root_->lpm_ = 0;
root_->def = 0;
make_scope_parameters(root_, s);
root_->type_ = IVL_SCT_MODULE;
root_->type_ = s->type()==NetScope::PACKAGE? IVL_SCT_PACKAGE : IVL_SCT_MODULE;
root_->tname_ = root_->name_;
root_->time_precision = s->time_precision();
root_->time_units = s->time_unit();
@ -545,6 +557,7 @@ void dll_target::add_root(ivl_design_s &des__, const NetScope *s)
root_->attr = fill_in_attributes(s);
root_->is_auto = 0;
root_->is_cell = s->is_cell();
if (s->type()==NetScope::MODULE) {
root_->ports = s->module_port_nets();
if (root_->ports > 0) {
root_->u_.net = new NetNet*[root_->ports];
@ -554,20 +567,16 @@ void dll_target::add_root(ivl_design_s &des__, const NetScope *s)
}
root_->module_ports_info = s->module_port_info();
des__.nroots_++;
if (des__.roots_)
des__.roots_ = (ivl_scope_t *)realloc(des__.roots_,
des__.nroots_ *
sizeof(ivl_scope_t));
else
des__.roots_ = (ivl_scope_t *)malloc(des__.nroots_ *
sizeof(ivl_scope_t));
des__.roots_[des__.nroots_ - 1] = root_;
des__.roots.push_back(root_);
} else {
root_->ports = 0;
des__.packages.push_back(root_);
}
}
bool dll_target::start_design(const Design*des)
{
list<NetScope *> root_scopes;
const char*dll_path_ = des->get_flag("DLL");
dll_ = ivl_dlopen(dll_path_);
@ -591,8 +600,6 @@ bool dll_target::start_design(const Design*des)
// Initialize the design object.
des_.self = des;
des_.time_precision = des->get_precision();
des_.nroots_ = 0;
des_.roots_ = NULL;
des_.disciplines.resize(disciplines.size());
unsigned idx = 0;
@ -603,11 +610,17 @@ bool dll_target::start_design(const Design*des)
}
assert(idx == des_.disciplines.size());
root_scopes = des->find_root_scopes();
for (list<NetScope*>::const_iterator scop = root_scopes.begin();
scop != root_scopes.end(); ++ scop )
list<NetScope *> package_scopes = des->find_package_scopes();
for (list<NetScope*>::const_iterator scop = package_scopes.begin()
; scop != package_scopes.end(); ++ scop ) {
add_root(des_, *scop);
}
list<NetScope *> root_scopes = des->find_root_scopes();
for (list<NetScope*>::const_iterator scop = root_scopes.begin()
; scop != root_scopes.end(); ++ scop ) {
add_root(des_, *scop);
}
target_ = (target_design_f)ivl_dlsym(dll_, LU "target_design" TU);
if (target_ == 0) {
@ -2267,9 +2280,9 @@ void dll_target::scope(const NetScope*net)
if (net->parent() == 0) {
unsigned i;
scop = NULL;
for (i = 0; i < des_.nroots_ && scop == NULL; i++) {
if (strcmp(des_.roots_[i]->name_, net->basename()) == 0)
scop = des_.roots_[i];
for (i = 0; i < des_.roots.size() && scop == NULL; i++) {
if (strcmp(des_.roots[i]->name_, net->basename()) == 0)
scop = des_.roots[i];
}
assert(scop);
@ -2297,6 +2310,9 @@ void dll_target::scope(const NetScope*net)
scop->is_cell = net->is_cell();
switch (net->type()) {
case NetScope::PACKAGE:
cerr << "?:?" << ": internal error: "
<< "Package scopes should not have parents." << endl;
case NetScope::MODULE:
scop->type_ = IVL_SCT_MODULE;
scop->tname_ = net->module_name();

View File

@ -1701,8 +1701,13 @@ int target_design(ivl_design_t des)
ivl_design_roots(des, &root_scopes, &nroot);
for (idx = 0 ; idx < nroot ; idx += 1) {
if (ivl_scope_type(root_scopes[idx]) == IVL_SCT_PACKAGE) {
fprintf(out, "package = %s;\n",
ivl_scope_name(root_scopes[idx]));
} else {
fprintf(out, "root module = %s;\n",
ivl_scope_name(root_scopes[idx]));
}
show_scope(root_scopes[idx], 0);
}

View File

@ -2145,6 +2145,7 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
case IVL_SCT_BEGIN: type = "begin"; break;
case IVL_SCT_FORK: type = "fork"; break;
case IVL_SCT_GENERATE: type = "generate"; break;
case IVL_SCT_PACKAGE: type = "package"; break;
default: type = "?"; assert(0);
}

View File

@ -346,6 +346,11 @@ struct vpiScopeModule : public __vpiScope {
int get_type_code(void) const { return vpiModule; }
};
struct vpiScopePackage : public __vpiScope {
inline vpiScopePackage() { }
int get_type_code(void) const { return vpiPackage; }
};
struct vpiScopeTask : public __vpiScope {
inline vpiScopeTask() { }
int get_type_code(void) const { return vpiTask; }
@ -424,6 +429,8 @@ compile_scope_decl(char*label, char*type, char*name, char*tname,
scope = new vpiScopeBegin;
} else if (strcmp(base_type,"generate") == 0) {
scope = new vpiScopeBegin;
} else if (strcmp(base_type,"package") == 0) {
scope = new vpiScopePackage;
} else {
scope = new vpiScopeModule;
assert(0);