Merge branch 'master' of github.com:steveicarus/iverilog

This commit is contained in:
Stephen Williams 2012-04-03 07:57:02 -07:00
commit cf0b45702f
2 changed files with 58 additions and 9 deletions

View File

@ -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;

View File

@ -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: