Merge branch 'work13a'
This commit is contained in:
commit
64401ab815
11
PExpr.cc
11
PExpr.cc
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
4
PExpr.h
4
PExpr.h
|
|
@ -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_;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
5
PScope.h
5
PScope.h
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
26
elab_expr.cc
26
elab_expr.cc
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
32
elaborate.cc
32
elaborate.cc
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
6
main.cc
6
main.cc
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
15
net_scope.cc
15
net_scope.cc
|
|
@ -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_;
|
||||
}
|
||||
|
||||
|
|
|
|||
15
netlist.h
15
netlist.h
|
|
@ -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.
|
||||
|
|
|
|||
30
parse.y
30
parse.y
|
|
@ -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
|
||||
|
|
@ -2948,12 +2955,15 @@ expr_primary
|
|||
/* The hierarchy_identifier rule matches simple identifiers as well as
|
||||
indexed arrays and part selects */
|
||||
|
||||
| hierarchy_identifier
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
delete $1;
|
||||
}
|
||||
| hierarchy_identifier
|
||||
{ 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
25
pform.cc
25
pform.cc
|
|
@ -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
26
pform.h
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
EXTERN_C_START
|
||||
|
||||
/********* OBJECT TYPES ***********/
|
||||
#define vpiPackage 600
|
||||
#define vpiLongIntVar 610
|
||||
#define vpiShortIntVar 611
|
||||
#define vpiIntVar 612
|
||||
|
|
|
|||
17
t-dll-api.cc
17
t-dll-api.cc
|
|
@ -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)
|
||||
|
|
|
|||
74
t-dll.cc
74
t-dll.cc
|
|
@ -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,29 +557,26 @@ 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();
|
||||
root_->ports = s->module_port_nets();
|
||||
if (root_->ports > 0) {
|
||||
root_->u_.net = new NetNet*[root_->ports];
|
||||
for (unsigned idx = 0; idx < root_->ports; idx += 1) {
|
||||
root_->u_.net[idx] = s->module_port_net(idx);
|
||||
if (s->type()==NetScope::MODULE) {
|
||||
root_->ports = s->module_port_nets();
|
||||
if (root_->ports > 0) {
|
||||
root_->u_.net = new NetNet*[root_->ports];
|
||||
for (unsigned idx = 0; idx < root_->ports; idx += 1) {
|
||||
root_->u_.net[idx] = s->module_port_net(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
root_->module_ports_info = s->module_port_info();
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
fprintf(out, "root module = %s;\n",
|
||||
ivl_scope_name(root_scopes[idx]));
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue