packages can contain variables.
This commit is contained in:
parent
44cd9158e8
commit
eba3d407ca
5
PExpr.cc
5
PExpr.cc
|
|
@ -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()
|
||||
|
|
|
|||
2
PExpr.h
2
PExpr.h
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
19
elab_lval.cc
19
elab_lval.cc
|
|
@ -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
20
parse.y
|
|
@ -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;
|
||||
|
|
|
|||
32
pform.cc
32
pform.cc
|
|
@ -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
|
||||
|
|
|
|||
9
pform.h
9
pform.h
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue