Skip to content
Browse files

Packed struct members in behavioral assign l-values.

  • Loading branch information...
1 parent d2c3ff7 commit 124314576dfac46784f514771329ee718bf90af6 @steveicarus committed Jan 3, 2012
Showing with 66 additions and 0 deletions.
  1. +3 −0 PExpr.h
  2. +57 −0 elab_lval.cc
  3. +6 −0 elab_net.cc
View
3 PExpr.h
@@ -349,6 +349,9 @@ class PEIdent : public PExpr {
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
index_component_t::ctype_t) const;
+ bool elaborate_lval_net_packed_member_(Design*, NetScope*,
+ NetAssign_*,
+ const perm_string&) const;
private:
NetExpr*elaborate_expr_param_(Design*des,
View
57 elab_lval.cc
@@ -22,6 +22,7 @@
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
+# include "netstruct.h"
# include "compiler.h"
# include <cstdlib>
# include <iostream>
@@ -152,8 +153,26 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
NetNet* reg = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
+ perm_string method_name;
symbol_search(this, des, 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",
+ remove the member and store it into method_name, and retry
+ the search with "a.b". */
+ if (reg == 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, reg, par, eve);
+
+ if (reg && reg->struct_type() == 0) {
+ method_name = perm_string();
+ reg = 0;
+ }
+ }
+
if (reg == 0) {
cerr << get_fileline() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope_path(scope) <<
@@ -193,6 +212,12 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return 0;
}
+ if (reg->struct_type() && !method_name.nil()) {
+ NetAssign_*lv = new NetAssign_(reg);
+ elaborate_lval_net_packed_member_(des, scope, lv, method_name);
+ return lv;
+ }
+
if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg);
@@ -533,6 +558,38 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
return true;
}
+bool PEIdent::elaborate_lval_net_packed_member_(Design*des,
+ NetScope*scope,
+ NetAssign_*lv,
+ const perm_string&member_name) const
+{
+ NetNet*reg = lv->sig();
+ ivl_assert(*this, reg);
+
+ netstruct_t*struct_type = reg->struct_type();
+ ivl_assert(*this, struct_type);
+
+ if (! struct_type->packed()) {
+ cerr << get_fileline() << ": sorry: Only packed structures "
+ << "are supported in l-value." << endl;
+ des->errors += 1;
+ return false;
+ }
+
+ unsigned long off;
+ const netstruct_t::member_t* member = struct_type->packed_member(member_name, off);
+
+ if (member == 0) {
+ cerr << get_fileline() << ": error: Member " << member_name
+ << " is not a member of variable " << reg->name() << endl;
+ des->errors += 1;
+ return false;
+ }
+
+ lv->set_part(new NetEConst(verinum(off)), member->width());
+ return true;
+}
+
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
{
cerr << get_fileline() << ": error: Constant values not allowed "
View
6 elab_net.cc
@@ -427,6 +427,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
method_name = peek_tail_name(use_path);
use_path.pop_back();
symbol_search(this, des, scope, use_path, sig, par, eve);
+
+ // Whoops, not a struct signal, so give up on this avenue.
+ if (sig && sig->struct_type() == 0) {
+ method_name = perm_string();
+ sig = 0;
+ }
}
if (sig == 0) {

0 comments on commit 1243145

Please sign in to comment.
Something went wrong with that request. Please try again.