packages can contain variables.

This commit is contained in:
Stephen Williams 2013-04-07 16:38:48 -07:00
parent 44cd9158e8
commit eba3d407ca
7 changed files with 82 additions and 18 deletions

View File

@ -343,10 +343,9 @@ PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
path_.push_back(name_component_t(s));
}
PEIdent::PEIdent(PPackage*pkg, perm_string s)
: package_(pkg), no_implicit_sig_(true)
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
: package_(pkg), path_(that), no_implicit_sig_(true)
{
path_.push_back(name_component_t(s));
}
PEIdent::~PEIdent()

View File

@ -291,7 +291,7 @@ class PEIdent : public PExpr {
public:
explicit PEIdent(perm_string, bool no_implicit_sig=false);
explicit PEIdent(PPackage*pkg, perm_string name);
explicit PEIdent(PPackage*pkg, const pform_name_t&name);
explicit PEIdent(const pform_name_t&);
~PEIdent();

View File

@ -21,6 +21,7 @@
# include "config.h"
# include "PExpr.h"
# include "PPackage.h"
# include "netlist.h"
# include "netmisc.h"
# include "netstruct.h"
@ -163,7 +164,13 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (NetAssign_*tmp = elaborate_lval_method_class_member_(des, scope))
return tmp;
symbol_search(this, des, scope, path_, reg, par, eve);
NetScope*use_scope = scope;
if (package_) {
use_scope = des->find_package(package_->pscope_name());
ivl_assert(*this, use_scope);
}
symbol_search(this, des, use_scope, path_, reg, par, eve);
/* If the signal is not found, check to see if this is a
member of a struct. Take the name of the form "a.b.member",
@ -173,7 +180,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
pform_name_t use_path = path_;
perm_string tmp_name = peek_tail_name(use_path);
use_path.pop_back();
symbol_search(this, des, scope, use_path, reg, par, eve);
symbol_search(this, des, use_scope, use_path, reg, par, eve);
if (reg && reg->struct_type()) {
method_name = tmp_name;
@ -228,7 +235,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_fileline() << ": error: " << path_ <<
" is not a valid l-value in " << scope_path(scope) <<
" is not a valid l-value in " << scope_path(use_scope) <<
"." << endl;
cerr << reg->get_fileline() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
@ -238,13 +245,13 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (reg->struct_type() && !method_name.nil()) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_packed_member_(des, scope, lv, method_name);
elaborate_lval_net_packed_member_(des, use_scope, lv, method_name);
return lv;
}
if (reg->class_type() && !method_name.nil() && gn_system_verilog()) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_class_member_(des, scope, lv, method_name);
elaborate_lval_net_class_member_(des, use_scope, lv, method_name);
return lv;
}
@ -768,7 +775,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
return true;
}
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope,
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*,
NetAssign_*lv,
const perm_string&method_name) const
{

20
parse.y
View File

@ -896,6 +896,17 @@ constraint_set /* IEEE1800-2005 A.1.9 */
| '{' constraint_expression_list '}'
;
data_declaration /* IEEE1800-2005: A.2.1.3 */
: attribute_list_opt data_type_or_implicit list_of_variable_decl_assignments ';'
{ data_type_t*data_type = $2;
if (data_type == 0) {
data_type = new vector_type_t(IVL_VT_LOGIC, false, 0);
FILE_NAME(data_type, @2);
}
pform_makewire(@2, 0, str_strength, $3, NetNet::IMPLICIT_REG, data_type);
}
;
data_type /* IEEE1800-2005: A.2.2.1 */
: integer_vector_type unsigned_signed_opt range_opt
{ ivl_variable_type_t use_vtype = $1;
@ -1401,6 +1412,7 @@ package_item /* IEEE1800-2005 A.1.10 */
| K_localparam param_type localparam_assign_list ';'
| type_declaration
| function_declaration
| data_declaration
;
package_item_list
@ -2991,8 +3003,10 @@ expr_primary
delete $1;
}
| PACKAGE_IDENTIFIER K_SCOPE_RES IDENTIFIER
{ $$ = pform_package_ident(@2, $1, $3); }
| PACKAGE_IDENTIFIER K_SCOPE_RES hierarchy_identifier
{ $$ = pform_package_ident(@2, $1, $3);
delete $3;
}
/* An identifier followed by an expression list in parentheses is a
function call. If a system identifier, then a system function
@ -3848,7 +3862,7 @@ atom2_type
rule to reflect the rules for assignment l-values. */
lpvalue
: hierarchy_identifier
{ PEIdent*tmp = new PEIdent(*$1);
{ PEIdent*tmp = pform_new_ident(*$1);
FILE_NAME(tmp, @1);
$$ = tmp;
delete $1;

View File

@ -435,7 +435,7 @@ PEIdent* pform_new_ident(const pform_name_t&name)
// XXXX For now, do not support indexed imported names.
assert(name.back().index.size() == 0);
return new PEIdent(pkg->second, name.back().name);
return new PEIdent(pkg->second, name);
}
PGenerate* pform_parent_generate(void)
@ -2295,6 +2295,7 @@ void pform_makewire(const vlltype&li,
first = first->next;
} while (first != decls->next);
// The pform_set_data_type function will delete the names list.
pform_set_data_type(li, data_type, names, type, 0);
// This time, go through the list, deleting cells as I'm done.
@ -2316,6 +2317,35 @@ void pform_makewire(const vlltype&li,
}
}
/*
* This should eventually repliace the form above that takes a
* net_decl_assign_t argument.
*/
void pform_makewire(const struct vlltype&li,
std::list<PExpr*>*, str_pair_t ,
std::list<decl_assignment_t*>*assign_list,
NetNet::Type type,
data_type_t*data_type)
{
list<perm_string>*names = new list<perm_string>;
for (list<decl_assignment_t*>::iterator cur = assign_list->begin()
; cur != assign_list->end() ; ++ cur) {
decl_assignment_t* curp = *cur;
names->push_back(curp->name);
}
pform_set_data_type(li, data_type, names, type, 0);
while (! assign_list->empty()) {
decl_assignment_t*first = assign_list->front();
assign_list->pop_front();
// For now, do not handle assignment expressions.
assert(! first->expr.get());
delete first;
}
}
/*
* This function is called by the parser to create task ports. The
* resulting wire (which should be a register) is put into a list to

View File

@ -211,7 +211,7 @@ extern void pform_package_import(const struct vlltype&loc,
PPackage*pkg, const char*ident);
extern PExpr* pform_package_ident(const struct vlltype&loc,
PPackage*pkg, const char*ident);
PPackage*pkg, pform_name_t*ident);
/*
* This creates an identifier aware of names that may have been
@ -310,6 +310,13 @@ extern void pform_makewire(const struct vlltype&li,
NetNet::Type type,
data_type_t*data_type);
extern void pform_makewire(const struct vlltype&li,
std::list<PExpr*>*delay,
str_pair_t str,
std::list<decl_assignment_t*>*assign_list,
NetNet::Type type,
data_type_t*data_type);
/* This form handles nets declared as structures. (See pform_struct_type.cc) */
extern void pform_makewire(const struct vlltype&li,
struct_type_t*struct_type,

View File

@ -105,6 +105,13 @@ void pform_package_import(const struct vlltype&, PPackage*pkg, const char*ident)
return;
}
map<perm_string,PWire*>::const_iterator wcur;
wcur = pkg->wires.find(use_ident);
if (wcur != pkg->wires.end()) {
scope->imports[wcur->first] = pkg;
return;
}
ostringstream msg;
msg << "Symbol " << use_ident
<< " not found in package " << pkg->pscope_name() << "." << ends;
@ -142,10 +149,10 @@ void pform_package_import(const struct vlltype&, PPackage*pkg, const char*ident)
}
PExpr* pform_package_ident(const struct vlltype&loc,
PPackage*pkg, const char*ident_name)
PPackage*pkg, pform_name_t*ident_name)
{
perm_string use_ident = lex_strings.make(ident_name);
PEIdent*tmp = new PEIdent(pkg, use_ident);
assert(ident_name);
PEIdent*tmp = new PEIdent(pkg, *ident_name);
FILE_NAME(tmp, loc);
return tmp;
}