diff --git a/parse.y b/parse.y index f47c2f72d..4646d3f00 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: parse.y,v 1.150 2002/05/19 23:37:28 steve Exp $" +#ident "$Id: parse.y,v 1.151 2002/05/20 02:06:01 steve Exp $" #endif # include "config.h" @@ -39,7 +39,10 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; %} %union { + bool flag; + char letter; + /* text items are C strings allocated by the lexor using strdup. They can be put into lists with the texts type. */ char*text; @@ -119,6 +122,7 @@ const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; %token KK_attribute +%type signed_opt %type drive_strength drive_strength_opt dr_strength0 dr_strength1 %type udp_input_sym udp_output_sym %type udp_input_list udp_sequ_entry udp_comb_entry @@ -1112,36 +1116,40 @@ list_of_port_declarations ; port_declaration - : K_input net_type IDENTIFIER + : K_input net_type signed_opt range_opt IDENTIFIER { Module::port_t*ptmp; - ptmp = pform_module_port_reference($3, @1.text, + ptmp = pform_module_port_reference($5, @1.text, @1.first_line); - pform_makewire(@1, $3, $2, NetNet::PINPUT); - delete $3; + pform_module_define_port(@1, $5, NetNet::PINPUT, + $2, $3, $4); + delete $5; $$ = ptmp; } - | K_inout net_type IDENTIFIER + | K_inout net_type signed_opt range_opt IDENTIFIER { Module::port_t*ptmp; - ptmp = pform_module_port_reference($3, @1.text, + ptmp = pform_module_port_reference($5, @1.text, @1.first_line); - pform_makewire(@1, $3, $2, NetNet::PINOUT); - delete $3; + pform_module_define_port(@1, $5, NetNet::PINOUT, + $2, $3, $4); + delete $5; $$ = ptmp; } - | K_output net_type IDENTIFIER + | K_output net_type signed_opt range_opt IDENTIFIER { Module::port_t*ptmp; - ptmp = pform_module_port_reference($3, @1.text, + ptmp = pform_module_port_reference($5, @1.text, @1.first_line); - pform_makewire(@1, $3, $2, NetNet::POUTPUT); - delete $3; + pform_module_define_port(@1, $5, NetNet::POUTPUT, + $2, $3, $4); + delete $5; $$ = ptmp; } - | K_output var_type IDENTIFIER + | K_output var_type signed_opt range_opt IDENTIFIER { Module::port_t*ptmp; - ptmp = pform_module_port_reference($3, @1.text, + ptmp = pform_module_port_reference($5, @1.text, @1.first_line); - pform_makewire(@1, $3, $2, NetNet::POUTPUT); - delete $3; + pform_module_define_port(@1, $5, NetNet::POUTPUT, + $2, $3, $4); + delete $5; $$ = ptmp; } ; @@ -1152,6 +1160,7 @@ list_of_ports_opt | { $$ = 0; } ; +signed_opt : K_signed { $$ = true; } | {$$ = false; } ; /* An lavalue is the expression that can go on the left side of a continuous assign statement. This checks (where it can) that the diff --git a/pform.cc b/pform.cc index 782aa5512..5361de299 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.cc,v 1.94 2002/05/19 23:37:28 steve Exp $" +#ident "$Id: pform.cc,v 1.95 2002/05/20 02:06:01 steve Exp $" #endif # include "config.h" @@ -783,6 +783,54 @@ void pform_make_reginit(const struct vlltype&li, pform_cur_module->add_behavior(top); } +/* + * This function is used by the parser when I have port definition of + * the form like this: + * + * input wire signed [7:0] nm; + * + * The port_type, type, signed_flag and range are known all at once, + * so we can create the PWire object all at once instead of piecemeal + * as is done for the old method. + */ +void pform_module_define_port(const struct vlltype&li, + const char*nm, + NetNet::PortType port_type, + NetNet::Type type, + bool signed_flag, + svector*range) +{ + hname_t name = hier_name(nm); + PWire*cur = pform_cur_module->get_wire(name); + if (cur) { + strstream msg; + msg << name << " definition conflicts with " + << "definition at " << cur->get_line() + << "." << ends; + VLerror(msg.str()); + return; + } + + + cur = new PWire(name, type, port_type); + cur->set_file(li.text); + cur->set_lineno(li.first_line); + + cur->set_signed(signed_flag); + + if (range == 0) { + cur->set_range(0, 0); + + } else { + assert(range->count() == 2); + assert((*range)[0]); + assert((*range)[1]); + cur->set_range((*range)[0], (*range)[1]); + } + + pform_cur_module->add_wire(cur); +} + /* * This function makes a single signal (a wire, a reg, etc) as * requested by the parser. The name is unscoped, so I attach the @@ -801,9 +849,7 @@ void pform_make_reginit(const struct vlltype&li, * do check to see if the name has already been declared, as this * function is called for every declaration. */ -void pform_makewire(const vlltype&li, const char*nm, - NetNet::Type type, - NetNet::PortType port_type) +void pform_makewire(const vlltype&li, const char*nm, NetNet::Type type) { hname_t name = hier_name(nm); PWire*cur = pform_cur_module->get_wire(name); @@ -830,7 +876,7 @@ void pform_makewire(const vlltype&li, const char*nm, return; } - cur = new PWire(name, type, port_type); + cur = new PWire(name, type, NetNet::NOT_A_PORT); cur->set_file(li.text); cur->set_lineno(li.first_line); pform_cur_module->add_wire(cur); @@ -1262,6 +1308,9 @@ int pform_parse(const char*path, FILE*file) /* * $Log: pform.cc,v $ + * Revision 1.95 2002/05/20 02:06:01 steve + * Add ranges and signed to port list declarations. + * * Revision 1.94 2002/05/19 23:37:28 steve * Parse port_declaration_lists from the 2001 Standard. * diff --git a/pform.h b/pform.h index ade7ac792..b9289a4ee 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: pform.h,v 1.56 2002/05/19 23:37:28 steve Exp $" +#ident "$Id: pform.h,v 1.57 2002/05/20 02:06:01 steve Exp $" #endif # include "netlist.h" @@ -119,6 +119,17 @@ struct lgate { */ extern void pform_startmodule(const char*, const char*file, unsigned lineno); extern void pform_module_set_ports(svector*); + +/* This function is used to support the port definition in a + port_definition_list. In this case, we have everything needed to + define the port, all in one place. */ +extern void pform_module_define_port(const struct vlltype&li, + const char*name, + NetNet::PortType, + NetNet::Type type, + bool signed_flag, + svector*range); + extern Module::port_t* pform_module_port_reference(char*name, const char*file, unsigned lineno); @@ -142,8 +153,8 @@ extern void pform_pop_scope(); * go into a module that is currently opened. */ extern void pform_makewire(const struct vlltype&li, const char*name, - NetNet::Type type = NetNet::IMPLICIT, - NetNet::PortType =NetNet::NOT_A_PORT); + NetNet::Type type = NetNet::IMPLICIT); + extern void pform_makewire(const struct vlltype&li, svector*range, list*names, @@ -230,6 +241,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.57 2002/05/20 02:06:01 steve + * Add ranges and signed to port list declarations. + * * Revision 1.56 2002/05/19 23:37:28 steve * Parse port_declaration_lists from the 2001 Standard. *