Handle struct members in continuous assign l-values.

This commit is contained in:
Stephen Williams 2011-12-31 17:27:30 -08:00
parent e9e2fb33e9
commit d2c3ff7999
1 changed files with 33 additions and 1 deletions

View File

@ -22,6 +22,7 @@
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include "netstruct.h"
# include "compiler.h"
# include <cstdlib>
@ -405,6 +406,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
NetNet* sig = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
perm_string method_name;
symbol_search(this, des, scope, path_, sig, par, eve);
@ -416,6 +418,17 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
return 0;
}
/* 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",
remove the member and store it into method_name, and retry
the search with "a.b". */
if (sig == 0 && path_.size() >= 2) {
pform_name_t use_path = path_;
method_name = peek_tail_name(use_path);
use_path.pop_back();
symbol_search(this, des, scope, use_path, sig, par, eve);
}
if (sig == 0) {
cerr << get_fileline() << ": error: Net " << path_
<< " is not defined in this context." << endl;
@ -460,7 +473,26 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
const name_component_t&name_tail = path_.back();
if (sig->array_dimensions() > 0) {
netstruct_t*struct_type = 0;
if ((struct_type = sig->struct_type()) && !method_name.nil()) {
// Detect the variable is a structure and there was a
// methos name detected.
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Signal " << sig->name() << " is a structure, "
<< "try to match member " << method_name << endl;
unsigned long member_off = 0;
const struct netstruct_t::member_t*member = struct_type->packed_member(method_name, member_off);
ivl_assert(*this, member);
// Rewrite a member select of a packed structure as a
// part select of the base variable.
lidx = member_off;
midx = lidx + member->width() - 1;
} else if (sig->array_dimensions() > 0) {
if (name_tail.index.empty()) {
cerr << get_fileline() << ": error: array " << sig->name()