Add code to test the width of individual structure elements.
This patch adds code to correctly set the type and width of individual structure elements. Note the sign information is not currently available.
This commit is contained in:
parent
c222169608
commit
42239a8498
62
elab_expr.cc
62
elab_expr.cc
|
|
@ -1419,24 +1419,38 @@ static NetExpr* check_for_enum_methods(const LineInfo*li,
|
|||
return sys_expr;
|
||||
}
|
||||
|
||||
static NetExpr* check_for_struct_members(const LineInfo*li,
|
||||
Design*des, NetScope*,
|
||||
NetNet*net, perm_string method_name)
|
||||
/*
|
||||
* If the method matches a structure member then return the member otherwise
|
||||
* return 0. Also return the offset of the member.
|
||||
*/
|
||||
static const netstruct_t::member_t*get_struct_member(const LineInfo*li,
|
||||
Design*des, NetScope*,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
unsigned long&off)
|
||||
{
|
||||
netstruct_t*type = net->struct_type();
|
||||
ivl_assert(*li, type);
|
||||
|
||||
if (! type->packed()) {
|
||||
cerr << li->get_fileline() << ": sorry: unpacked structures not supported here. "
|
||||
cerr << li->get_fileline()
|
||||
<< ": sorry: unpacked structures not supported here. "
|
||||
<< "Method=" << method_name << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return type->packed_member(method_name, off);
|
||||
}
|
||||
|
||||
static NetExpr* check_for_struct_members(const LineInfo*li,
|
||||
Design*des, NetScope*,
|
||||
NetNet*net, perm_string method_name)
|
||||
{
|
||||
unsigned long off;
|
||||
const netstruct_t::member_t*mem = type->packed_member(method_name, off);
|
||||
if (mem == 0)
|
||||
return 0;
|
||||
const netstruct_t::member_t*mem = get_struct_member(li, des, 0, net,
|
||||
method_name, off);
|
||||
if (mem == 0) return 0;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << li->get_fileline() << ": debug: Found struct member " <<mem->name
|
||||
|
|
@ -2010,7 +2024,8 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
symbol_search(0, des, scope, path_, net, par, eve, ex1, ex2);
|
||||
NetScope*found_in = symbol_search(0, des, scope, path_, net, par, eve,
|
||||
ex1, ex2);
|
||||
|
||||
// If there is a part/bit select expression, then process it
|
||||
// here. This constrains the results no matter what kind the
|
||||
|
|
@ -2146,6 +2161,37 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
return expr_width_;
|
||||
}
|
||||
|
||||
// If this is SystemVerilog then maybe this is a structure element.
|
||||
if (gn_system_verilog() && found_in==0 && path_.size() >= 2) {
|
||||
pform_name_t use_path = path_;
|
||||
perm_string method_name = peek_tail_name(use_path);
|
||||
use_path.pop_back();
|
||||
|
||||
found_in = symbol_search(this, des, scope, use_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
|
||||
// Check to see if we have a net and if so is it a structure?
|
||||
if (net != 0) {
|
||||
// If this net is a struct, the method name may be
|
||||
// a struct member.
|
||||
if (net->struct_type() != 0) {
|
||||
ivl_assert(*this, use_path.back().index.empty());
|
||||
|
||||
const netstruct_t::member_t*mem;
|
||||
unsigned long unused;
|
||||
mem = get_struct_member(this, des, scope, net,
|
||||
method_name, unused);
|
||||
if (mem) {
|
||||
expr_type_ = mem->data_type();
|
||||
expr_width_ = mem->width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = mem->get_signed();
|
||||
return expr_width_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not a net, and not a parameter? Give up on the type, but
|
||||
// set the width to 0.
|
||||
expr_type_ = IVL_VT_NO_TYPE;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __netstruct_H
|
||||
#define __netstruct_H
|
||||
/*
|
||||
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2011-2012 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -32,6 +32,9 @@ class netstruct_t : public LineInfo {
|
|||
long msb;
|
||||
long lsb;
|
||||
long width() const;
|
||||
ivl_variable_type_t data_type() const { return type; };
|
||||
// We need to keep the individual element sign information.
|
||||
bool get_signed() const { return false; };
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
|||
Loading…
Reference in New Issue