Packed struct members in behavioral assign l-values.
This commit is contained in:
parent
d2c3ff7999
commit
124314576d
3
PExpr.h
3
PExpr.h
|
|
@ -349,6 +349,9 @@ class PEIdent : public PExpr {
|
||||||
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
||||||
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
|
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
|
||||||
index_component_t::ctype_t) const;
|
index_component_t::ctype_t) const;
|
||||||
|
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
|
||||||
|
NetAssign_*,
|
||||||
|
const perm_string&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetExpr*elaborate_expr_param_(Design*des,
|
NetExpr*elaborate_expr_param_(Design*des,
|
||||||
|
|
|
||||||
57
elab_lval.cc
57
elab_lval.cc
|
|
@ -22,6 +22,7 @@
|
||||||
# include "PExpr.h"
|
# include "PExpr.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
|
# include "netstruct.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
@ -152,8 +153,26 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
NetNet* reg = 0;
|
NetNet* reg = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
perm_string method_name;
|
||||||
|
|
||||||
symbol_search(this, des, scope, path_, reg, par, eve);
|
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) {
|
if (reg == 0) {
|
||||||
cerr << get_fileline() << ": error: Could not find variable ``"
|
cerr << get_fileline() << ": error: Could not find variable ``"
|
||||||
<< path_ << "'' in ``" << scope_path(scope) <<
|
<< path_ << "'' in ``" << scope_path(scope) <<
|
||||||
|
|
@ -193,6 +212,12 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
return 0;
|
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)
|
if (reg->array_dimensions() > 0)
|
||||||
return elaborate_lval_net_word_(des, scope, reg);
|
return elaborate_lval_net_word_(des, scope, reg);
|
||||||
|
|
||||||
|
|
@ -533,6 +558,38 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
||||||
return true;
|
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
|
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
||||||
{
|
{
|
||||||
cerr << get_fileline() << ": error: Constant values not allowed "
|
cerr << get_fileline() << ": error: Constant values not allowed "
|
||||||
|
|
|
||||||
|
|
@ -427,6 +427,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
method_name = peek_tail_name(use_path);
|
method_name = peek_tail_name(use_path);
|
||||||
use_path.pop_back();
|
use_path.pop_back();
|
||||||
symbol_search(this, des, scope, use_path, sig, par, eve);
|
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) {
|
if (sig == 0) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue