Parse support for struct variables.

This commit is contained in:
Stephen Williams 2011-12-03 17:16:01 -08:00
parent 5677efdfe6
commit d362c8dba0
14 changed files with 342 additions and 23 deletions

View File

@ -107,10 +107,10 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
elab_scope.o elab_sig.o elab_sig_analog.o emit.o eval.o eval_attrib.o \ elab_scope.o elab_sig.o elab_sig_analog.o emit.o eval.o eval_attrib.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_analog.o net_assign.o net_design.o \ load_module.o netlist.o netmisc.o net_analog.o net_assign.o net_design.o \
netenum.o net_event.o net_expr.o net_func.o net_link.o net_modulo.o \ netenum.o netstruct.o net_event.o net_expr.o net_func.o net_link.o net_modulo.o \
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \ net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \ net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
pform_disciplines.o pform_dump.o pform_types.o \ pform_disciplines.o pform_dump.o pform_struct_type.o pform_types.o \
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \ symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
Attrib.o HName.o Module.o PDelays.o PEvent.o PExpr.o PGate.o \ Attrib.o HName.o Module.o PDelays.o PEvent.o PExpr.o PGate.o \
PGenerate.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \ PGenerate.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \

View File

@ -30,7 +30,8 @@ PWire::PWire(perm_string n,
signed_(false), isint_(false), signed_(false), isint_(false),
port_msb_(0), port_lsb_(0), port_set_(false), port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false), net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
error_cnt_(0), lidx_(0), ridx_(0), enum_type_(0), discipline_(0) error_cnt_(0), lidx_(0), ridx_(0), enum_type_(0), struct_type_(0),
discipline_(0)
{ {
if (t == NetNet::INTEGER) { if (t == NetNet::INTEGER) {
type_ = NetNet::REG; type_ = NetNet::REG;
@ -217,9 +218,17 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
void PWire::set_enumeration(enum_type_t*enum_type) void PWire::set_enumeration(enum_type_t*enum_type)
{ {
assert(enum_type_ == 0); assert(enum_type_ == 0);
assert(struct_type_ == 0);
enum_type_ = enum_type; enum_type_ = enum_type;
} }
void PWire::set_struct_type(struct_type_t*type)
{
assert(enum_type_ == 0);
assert(struct_type_ == 0);
struct_type_ = type;
}
void PWire::set_discipline(ivl_discipline_t d) void PWire::set_discipline(ivl_discipline_t d)
{ {
assert(discipline_ == 0); assert(discipline_ == 0);

View File

@ -80,6 +80,7 @@ class PWire : public LineInfo {
void set_memory_idx(PExpr*ldx, PExpr*rdx); void set_memory_idx(PExpr*ldx, PExpr*rdx);
void set_enumeration(enum_type_t*enum_type); void set_enumeration(enum_type_t*enum_type);
void set_struct_type(struct_type_t*type);
void set_discipline(ivl_discipline_t); void set_discipline(ivl_discipline_t);
ivl_discipline_t get_discipline(void) const; ivl_discipline_t get_discipline(void) const;
@ -116,6 +117,7 @@ class PWire : public LineInfo {
PExpr*ridx_; PExpr*ridx_;
enum_type_t*enum_type_; enum_type_t*enum_type_;
struct_type_t*struct_type_;
ivl_discipline_t discipline_; ivl_discipline_t discipline_;

View File

@ -1418,6 +1418,15 @@ static NetExpr* check_for_enum_methods(const LineInfo*li,
return sys_expr; return sys_expr;
} }
static NetExpr* check_for_struct_members(const LineInfo*li,
Design*des, NetScope*scope,
NetNet*net, perm_string method_name)
{
cerr << li->get_fileline() << ": sorry: structures not supported here." << endl;
des->errors += 1;
return 0;
}
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const unsigned expr_wid, unsigned flags) const
{ {
@ -1456,8 +1465,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
// enumeration? If so then check to see if this is an // enumeration? If so then check to see if this is an
// enumeration method call. // enumeration method call.
if (net != 0) { if (net != 0) {
netenum_t*netenum = net->enumeration(); if (netenum_t*netenum = net->enumeration()) {
if (netenum) {
// We may need the net expression for the // We may need the net expression for the
// enumeration variable so get it. // enumeration variable so get it.
NetESignal*expr = new NetESignal(net); NetESignal*expr = new NetESignal(net);
@ -1472,6 +1480,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
expr_wid, tmp, expr_wid, tmp,
parms_.size()); parms_.size());
} }
} }
} }
@ -2289,8 +2298,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
// enumeration? If so then check to see if this is an // enumeration? If so then check to see if this is an
// enumeration method call. // enumeration method call.
if (net != 0) { if (net != 0) {
netenum_t*netenum = net->enumeration(); // If this net is actually an enum, the method may
if (netenum) { // be an enumeration method.
if (netenum_t*netenum = net->enumeration()) {
// We may need the net expression for the // We may need the net expression for the
// enumeration variable so get it. // enumeration variable so get it.
NetESignal*expr = new NetESignal(net); NetESignal*expr = new NetESignal(net);
@ -2303,6 +2313,16 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
use_path, method_name, use_path, method_name,
expr, expr_wid, NULL, 0); expr, expr_wid, NULL, 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());
return check_for_struct_members(this, des, scope,
net, method_name);
}
} }
} }

View File

@ -32,6 +32,7 @@
# include "compiler.h" # include "compiler.h"
# include "netlist.h" # include "netlist.h"
# include "netmisc.h" # include "netmisc.h"
# include "netstruct.h"
# include "util.h" # include "util.h"
# include "ivl_assert.h" # include "ivl_assert.h"
@ -1094,6 +1095,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
sig->set_enumeration(use_enum); sig->set_enumeration(use_enum);
} }
if (struct_type_) {
netstruct_t*use_type = new netstruct_t;
sig->set_struct_type(use_type);
}
if (wtype == NetNet::WIRE) sig->devirtualize_pins(); if (wtype == NetNet::WIRE) sig->devirtualize_pins();
ivl_variable_type_t use_data_type = data_type_; ivl_variable_type_t use_data_type = data_type_;

View File

@ -450,7 +450,8 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
: NetObj(s, n, 1), : NetObj(s, n, 1),
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
signed_(false), isint_(false), is_scalar_(false), local_flag_(false), signed_(false), isint_(false), is_scalar_(false), local_flag_(false),
enumeration_(0), discipline_(0), msb_(npins-1), lsb_(0), dimensions_(0), enumeration_(0), struct_type_(0), discipline_(0),
msb_(npins-1), lsb_(0), dimensions_(0),
s0_(0), e0_(0), eref_count_(0), lref_count_(0) s0_(0), e0_(0), eref_count_(0), lref_count_(0)
{ {
assert(s); assert(s);
@ -496,7 +497,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
: NetObj(s, n, 1), type_(t), : NetObj(s, n, 1), type_(t),
port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false),
isint_(false), is_scalar_(false), local_flag_(false), isint_(false), is_scalar_(false), local_flag_(false),
enumeration_(0), discipline_(0), enumeration_(0), struct_type_(0), discipline_(0),
msb_(ms), lsb_(ls), msb_(ms), lsb_(ls),
dimensions_(0), s0_(0), e0_(0), dimensions_(0), s0_(0), e0_(0),
eref_count_(0), lref_count_(0) eref_count_(0), lref_count_(0)
@ -544,7 +545,8 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
: NetObj(s, n, calculate_count(array_s, array_e)), : NetObj(s, n, calculate_count(array_s, array_e)),
type_(t), port_type_(NOT_A_PORT), type_(t), port_type_(NOT_A_PORT),
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false), data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
is_scalar_(false), local_flag_(false), enumeration_(0), discipline_(0), is_scalar_(false), local_flag_(false), enumeration_(0), struct_type_(0),
discipline_(0),
msb_(ms), lsb_(ls), msb_(ms), lsb_(ls),
dimensions_(1), s0_(array_s), e0_(array_e), dimensions_(1), s0_(array_s), e0_(array_e),
eref_count_(0), lref_count_(0) eref_count_(0), lref_count_(0)
@ -692,10 +694,23 @@ netenum_t*NetNet::enumeration(void) const
void NetNet::set_enumeration(netenum_t*es) void NetNet::set_enumeration(netenum_t*es)
{ {
ivl_assert(*this, struct_type_ == 0);
ivl_assert(*this, enumeration_ == 0); ivl_assert(*this, enumeration_ == 0);
enumeration_ = es; enumeration_ = es;
} }
netstruct_t*NetNet::struct_type(void) const
{
return struct_type_;
}
void NetNet::set_struct_type(netstruct_t*type)
{
ivl_assert(*this, struct_type_ == 0);
ivl_assert(*this, enumeration_ == 0);
struct_type_ = type;
}
ivl_discipline_t NetNet::get_discipline() const ivl_discipline_t NetNet::get_discipline() const
{ {
return discipline_; return discipline_;

View File

@ -75,6 +75,7 @@ class NetEvWait;
class PExpr; class PExpr;
class PFunction; class PFunction;
class netenum_t; class netenum_t;
class netstruct_t;
struct target; struct target;
struct functor_t; struct functor_t;
@ -603,6 +604,9 @@ class NetNet : public NetObj {
void set_enumeration(netenum_t*enum_set); void set_enumeration(netenum_t*enum_set);
netenum_t*enumeration(void) const; netenum_t*enumeration(void) const;
void set_struct_type(netstruct_t*type);
netstruct_t*struct_type(void) const;
/* Attach a discipline to the net. */ /* Attach a discipline to the net. */
ivl_discipline_t get_discipline() const; ivl_discipline_t get_discipline() const;
void set_discipline(ivl_discipline_t dis); void set_discipline(ivl_discipline_t dis);
@ -676,6 +680,7 @@ class NetNet : public NetObj {
bool is_scalar_ : 1; bool is_scalar_ : 1;
bool local_flag_: 1; bool local_flag_: 1;
netenum_t*enumeration_; netenum_t*enumeration_;
netstruct_t*struct_type_;
ivl_discipline_t discipline_; ivl_discipline_t discipline_;
long msb_, lsb_; long msb_, lsb_;

29
netstruct.cc Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2011 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "netstruct.h"
netstruct_t::netstruct_t()
: packed_(false)
{
}
netstruct_t::~netstruct_t()
{
}

34
netstruct.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef __netstruct_H
#define __netstruct_H
/*
* Copyright (c) 2011 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "LineInfo.h"
class netstruct_t : public LineInfo {
public:
netstruct_t();
~netstruct_t();
private:
bool packed_;
};
#endif

135
parse.y
View File

@ -330,6 +330,13 @@ static void current_task_set_statement(vector<Statement*>*s)
net_decl_assign_t*net_decl_assign; net_decl_assign_t*net_decl_assign;
enum_type_t*enum_type; enum_type_t*enum_type;
decl_assignment_t*decl_assignment;
list<decl_assignment_t*>*decl_assignments;
struct_member_t*struct_member;
list<struct_member_t*>*struct_members;
struct_type_t*struct_type;
verinum* number; verinum* number;
verireal* realtime; verireal* realtime;
@ -436,7 +443,8 @@ static void current_task_set_statement(vector<Statement*>*s)
%type <flag> from_exclude %type <flag> from_exclude
%type <number> number pos_neg_number %type <number> number pos_neg_number
%type <flag> unsigned_signed_opt signed_unsigned_opt reg_opt %type <flag> unsigned_signed_opt signed_unsigned_opt
%type <flag> K_packed_opt K_reg_opt
%type <flag> udp_reg_opt edge_operator automatic_opt %type <flag> udp_reg_opt edge_operator automatic_opt
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1 %type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
%type <letter> udp_input_sym udp_output_sym %type <letter> udp_input_sym udp_output_sym
@ -491,6 +499,13 @@ static void current_task_set_statement(vector<Statement*>*s)
%type <exprs> expression_list_with_nuls expression_list_proper %type <exprs> expression_list_with_nuls expression_list_proper
%type <exprs> cont_assign cont_assign_list %type <exprs> cont_assign cont_assign_list
%type <decl_assignment> variable_decl_assignment
%type <decl_assignments> list_of_variable_decl_assignments
%type <struct_member> struct_union_member
%type <struct_members> struct_union_member_list
%type <struct_type> struct_data_type
%type <exprs> range range_opt %type <exprs> range range_opt
%type <dimensions> dimensions_opt dimensions %type <dimensions> dimensions_opt dimensions
%type <nettype> net_type var_type net_type_opt %type <nettype> net_type var_type net_type_opt
@ -695,6 +710,13 @@ block_item_decl
if ($1) delete $1; if ($1) delete $1;
} }
/* struct data type declarations */
| attribute_list_opt struct_data_type register_variable_list ';'
{ pform_set_struct_type($2, $3);
if ($1) delete $1;
}
/* real declarations are fairly simple as there is no range of /* real declarations are fairly simple as there is no range of
signed flag in the declaration. Create the real as a NetNet::REG signed flag in the declaration. Create the real as a NetNet::REG
with real value. Note that real and realtime are interchangeable with real value. Note that real and realtime are interchangeable
@ -879,6 +901,63 @@ enum_name
} }
; ;
struct_data_type
: K_struct K_packed_opt '{' struct_union_member_list '}'
{ struct_type_t*tmp = new struct_type_t;
FILE_NAME(tmp, @1);
tmp->packed_flag = $2;
tmp->members .reset($4);
$$ = tmp;
}
| K_struct K_packed_opt '{' error '}'
{ yyerror(@4, "error: Errors in struct/union member list.");
yyerrok;
struct_type_t*tmp = new struct_type_t;
FILE_NAME(tmp, @1);
tmp->packed_flag = $2;
$$ = tmp;
}
;
struct_union_member_list
: struct_union_member_list struct_union_member
{ list<struct_member_t*>*tmp = $1;
tmp->push_back($2);
$$ = tmp;
}
| struct_union_member
{ list<struct_member_t*>*tmp = new list<struct_member_t*>;
$$ = tmp;
}
;
struct_union_member
: attribute_list_opt K_bit range_opt list_of_variable_decl_assignments ';'
{ struct_member_t*tmp = new struct_member_t;
FILE_NAME(tmp, @2);
tmp->type = IVL_VT_BOOL;
tmp->range .reset($3);
tmp->names .reset($4);
$$ = tmp;
}
| attribute_list_opt K_logic range_opt list_of_variable_decl_assignments ';'
{ struct_member_t*tmp = new struct_member_t;
FILE_NAME(tmp, @2);
tmp->type = IVL_VT_LOGIC;
tmp->range .reset($3);
tmp->names .reset($4);
$$ = tmp;
}
| attribute_list_opt atom2_type list_of_variable_decl_assignments ';'
{ struct_member_t*tmp = new struct_member_t;
FILE_NAME(tmp, @2);
tmp->type = IVL_VT_BOOL;
tmp->range .reset( make_range_from_width($2) );
tmp->names .reset($3);
$$ = tmp;
}
;
case_item case_item
: expression_list_proper ':' statement_or_null : expression_list_proper ':' statement_or_null
{ PCase::Item*tmp = new PCase::Item; { PCase::Item*tmp = new PCase::Item;
@ -3954,6 +4033,40 @@ register_variable_list
} }
; ;
/* TODO: Replace register_variable_list with list_of_variable_decl_assignments. */
list_of_variable_decl_assignments
: variable_decl_assignment
{ list<decl_assignment_t*>*tmp = new list<decl_assignment_t*>;
tmp->push_back($1);
$$ = tmp;
}
| list_of_variable_decl_assignments ',' variable_decl_assignment
{ list<decl_assignment_t*>*tmp = $1;
tmp->push_back($3);
$$ = tmp;
}
;
variable_decl_assignment
: IDENTIFIER dimensions_opt
{ decl_assignment_t*tmp = new decl_assignment_t;
tmp->name = lex_strings.make($1);
if ($2) {
tmp->index = *$2;
delete $2;
}
delete[]$1;
$$ = tmp;
}
| IDENTIFIER '=' expression
{ decl_assignment_t*tmp = new decl_assignment_t;
tmp->name = lex_strings.make($1);
tmp->expr .reset($3);
delete[]$1;
$$ = tmp;
}
;
real_variable real_variable
: IDENTIFIER dimensions_opt : IDENTIFIER dimensions_opt
{ perm_string name = lex_strings.make($1); { perm_string name = lex_strings.make($1);
@ -4820,13 +4933,8 @@ task_item
| task_port_item { $$ = $1; } | task_port_item { $$ = $1; }
; ;
reg_opt
: K_reg { $$ = true; }
| { $$ = false; }
;
task_port_item task_port_item
: K_input reg_opt unsigned_signed_opt range_opt list_of_identifiers ';' : K_input K_reg_opt unsigned_signed_opt range_opt list_of_identifiers ';'
{ svector<PWire*>*tmp = pform_make_task_ports(NetNet::PINPUT, { svector<PWire*>*tmp = pform_make_task_ports(NetNet::PINPUT,
$2 ? IVL_VT_LOGIC : $2 ? IVL_VT_LOGIC :
IVL_VT_NO_TYPE, IVL_VT_NO_TYPE,
@ -4834,7 +4942,7 @@ task_port_item
@1.text, @1.first_line); @1.text, @1.first_line);
$$ = tmp; $$ = tmp;
} }
| K_output reg_opt unsigned_signed_opt range_opt list_of_identifiers ';' | K_output K_reg_opt unsigned_signed_opt range_opt list_of_identifiers ';'
{ svector<PWire*>*tmp = pform_make_task_ports(NetNet::POUTPUT, { svector<PWire*>*tmp = pform_make_task_ports(NetNet::POUTPUT,
$2 ? IVL_VT_LOGIC : $2 ? IVL_VT_LOGIC :
IVL_VT_NO_TYPE, IVL_VT_NO_TYPE,
@ -4842,7 +4950,7 @@ task_port_item
@1.text, @1.first_line); @1.text, @1.first_line);
$$ = tmp; $$ = tmp;
} }
| K_inout reg_opt unsigned_signed_opt range_opt list_of_identifiers ';' | K_inout K_reg_opt unsigned_signed_opt range_opt list_of_identifiers ';'
{ svector<PWire*>*tmp = pform_make_task_ports(NetNet::PINOUT, { svector<PWire*>*tmp = pform_make_task_ports(NetNet::PINOUT,
$2 ? IVL_VT_LOGIC : $2 ? IVL_VT_LOGIC :
IVL_VT_NO_TYPE, IVL_VT_NO_TYPE,
@ -4954,7 +5062,7 @@ task_item_list_opt
task_port_decl task_port_decl
: K_input reg_opt unsigned_signed_opt range_opt IDENTIFIER : K_input K_reg_opt unsigned_signed_opt range_opt IDENTIFIER
{ port_declaration_context.port_type = NetNet::PINPUT; { port_declaration_context.port_type = NetNet::PINPUT;
port_declaration_context.var_type = IVL_VT_LOGIC; port_declaration_context.var_type = IVL_VT_LOGIC;
port_declaration_context.sign_flag = $3; port_declaration_context.sign_flag = $3;
@ -4968,7 +5076,7 @@ task_port_decl
$$ = tmp; $$ = tmp;
} }
| K_output reg_opt unsigned_signed_opt range_opt IDENTIFIER | K_output K_reg_opt unsigned_signed_opt range_opt IDENTIFIER
{ port_declaration_context.port_type = NetNet::POUTPUT; { port_declaration_context.port_type = NetNet::POUTPUT;
port_declaration_context.var_type = IVL_VT_LOGIC; port_declaration_context.var_type = IVL_VT_LOGIC;
port_declaration_context.sign_flag = $3; port_declaration_context.sign_flag = $3;
@ -4981,7 +5089,7 @@ task_port_decl
@1.text, @1.first_line); @1.text, @1.first_line);
$$ = tmp; $$ = tmp;
} }
| K_inout reg_opt unsigned_signed_opt range_opt IDENTIFIER | K_inout K_reg_opt unsigned_signed_opt range_opt IDENTIFIER
{ port_declaration_context.port_type = NetNet::PINOUT; { port_declaration_context.port_type = NetNet::PINOUT;
port_declaration_context.var_type = IVL_VT_LOGIC; port_declaration_context.var_type = IVL_VT_LOGIC;
port_declaration_context.sign_flag = $3; port_declaration_context.sign_flag = $3;
@ -5504,3 +5612,6 @@ udp_primitive
delete[]$6; delete[]$6;
} }
; ;
K_packed_opt : K_packed { $$ = true; } | { $$ = false; } ;
K_reg_opt : K_reg { $$ = true; } | { $$ = false; } ;

View File

@ -385,7 +385,7 @@ static void pform_put_enum_type_in_scope(enum_type_t*enum_set)
lexical_scope->enum_sets.push_back(enum_set); lexical_scope->enum_sets.push_back(enum_set);
} }
static PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetNet::PortType port_type, ivl_variable_type_t vt_type) PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetNet::PortType port_type, ivl_variable_type_t vt_type)
{ {
PWire*cur = pform_get_wire_in_scope(name); PWire*cur = pform_get_wire_in_scope(name);
if (cur == 0) { if (cur == 0) {

View File

@ -135,6 +135,8 @@ extern void pform_set_default_nettype(NetNet::Type net,
*/ */
extern PWire* pform_get_wire_in_scope(perm_string name); extern PWire* pform_get_wire_in_scope(perm_string name);
extern PWire* pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetNet::PortType port_type, ivl_variable_type_t vt_type);
/* /*
* The parser uses startmodule and endmodule together to build up a * The parser uses startmodule and endmodule together to build up a
* module as it parses it. The startmodule tells the pform code that a * module as it parses it. The startmodule tells the pform code that a
@ -280,6 +282,8 @@ extern void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_
extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names); extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names);
extern void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names);
/* pform_set_attrib and pform_set_type_attrib exist to support the /* pform_set_attrib and pform_set_type_attrib exist to support the
$attribute syntax, which can only set string values to $attribute syntax, which can only set string values to
attributes. The functions keep the value strings that are attributes. The functions keep the value strings that are

68
pform_struct_type.cc Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2011 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "pform.h"
# include "ivl_assert.h"
/*
* When we parse a packed struct, we can early on (right here) figure
* out the base type of the packed variable. Elaboration, later on,
* well figure out the rest.
*/
static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name)
{
ivl_variable_type_t base_type = IVL_VT_BOOL;
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
; cur != struct_type->members->end() ; ++ cur) {
struct_member_t*tmp = *cur;
if (tmp->type == IVL_VT_BOOL) {
continue;
}
if (tmp->type == IVL_VT_LOGIC) {
base_type = IVL_VT_LOGIC;
continue;
}
}
PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, base_type);
net->set_struct_type(struct_type);
}
static void pform_set_struct_type(struct_type_t*struct_type, perm_string name)
{
if (struct_type->packed_flag) {
pform_set_packed_struct(struct_type, name);
return;
}
// For now, can only handle packed structs.
ivl_assert(*struct_type, 0);
}
void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) {
pform_set_struct_type(struct_type, *cur);
}
}

View File

@ -57,6 +57,12 @@ struct name_component_t {
std::list<index_component_t>index; std::list<index_component_t>index;
}; };
struct decl_assignment_t {
perm_string name;
std::list<index_component_t>index;
std::auto_ptr<PExpr> expr;
};
/* /*
* The enum_type_t holds the parsed declaration to represent an * The enum_type_t holds the parsed declaration to represent an
* enumeration. Since this is in the pform, it represents the type * enumeration. Since this is in the pform, it represents the type
@ -71,6 +77,16 @@ struct enum_type_t {
LineInfo li; LineInfo li;
}; };
struct struct_member_t : public LineInfo {
ivl_variable_type_t type;
std::auto_ptr< list<PExpr*> > range;
std::auto_ptr< list<decl_assignment_t*> > names;
};
struct struct_type_t : public LineInfo {
bool packed_flag;
std::auto_ptr< list<struct_member_t*> > members;
};
/* /*
* The pform_name_t is the general form for a hierarchical * The pform_name_t is the general form for a hierarchical