From b37d806ee162fedb1b2214faf35ef787deaa6ad4 Mon Sep 17 00:00:00 2001 From: Cary R Date: Wed, 23 Nov 2011 19:07:26 -0800 Subject: [PATCH] Add preliminary support for wreal in Verilog-AMS mode. This patch adds wreal support when in Verilog-AMS mode. It doesn't add everything that is shown in the Verilog-A standard. It adds the following: Declaring a wreal net. Declaring a wreal net with an initialization. Declaring a wreal input/output using ANSI syntax. Declaring a wreal input/output using the old style. Declaring wreal inout ports are also allowed and parsed, but the compiler does not know how to handle this. There are other deviations from what is shown in the Verilog-A standard, but this should get most of the syntax people actually use. --- parse.y | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 6 deletions(-) diff --git a/parse.y b/parse.y index d78f8ee6c..41a14a7de 100644 --- a/parse.y +++ b/parse.y @@ -2263,7 +2263,8 @@ port_declaration delete[]$7; $$ = ptmp; } - | attribute_list_opt K_input atom2_type signed_unsigned_opt IDENTIFIER + | attribute_list_opt + K_input atom2_type signed_unsigned_opt IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($5); list*use_range = make_range_from_width($3); @@ -2282,7 +2283,24 @@ port_declaration $$ = ptmp; } | attribute_list_opt - K_inout net_type_opt primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER + K_input K_wreal IDENTIFIER + { Module::port_t*ptmp; + perm_string name = lex_strings.make($4); + ptmp = pform_module_port_reference(name, @2.text, + @2.first_line); + pform_module_define_port(@2, name, NetNet::PINPUT, + NetNet::WIRE, IVL_VT_REAL, true, 0, $1); + port_declaration_context.port_type = NetNet::PINPUT; + port_declaration_context.port_net_type = NetNet::WIRE; + port_declaration_context.var_type = IVL_VT_REAL; + port_declaration_context.sign_flag = true; + delete port_declaration_context.range; + port_declaration_context.range = 0; + delete[]$4; + $$ = ptmp; + } + | attribute_list_opt + K_inout net_type_opt primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($7); ptmp = pform_module_port_reference(name, @2.text, @@ -2298,6 +2316,23 @@ port_declaration delete[]$7; $$ = ptmp; } + | attribute_list_opt + K_inout K_wreal IDENTIFIER + { Module::port_t*ptmp; + perm_string name = lex_strings.make($4); + ptmp = pform_module_port_reference(name, @2.text, + @2.first_line); + pform_module_define_port(@2, name, NetNet::PINOUT, + NetNet::WIRE, IVL_VT_REAL, true, 0, $1); + port_declaration_context.port_type = NetNet::PINOUT; + port_declaration_context.port_net_type = NetNet::WIRE; + port_declaration_context.var_type = IVL_VT_REAL; + port_declaration_context.sign_flag = true; + delete port_declaration_context.range; + port_declaration_context.range = 0; + delete[]$4; + $$ = ptmp; + } | attribute_list_opt K_output net_type_opt primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER { Module::port_t*ptmp; @@ -2382,7 +2417,8 @@ port_declaration delete[]$7; $$ = ptmp; } - | attribute_list_opt K_output atom2_type signed_unsigned_opt IDENTIFIER + | attribute_list_opt + K_output atom2_type signed_unsigned_opt IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($5); list*use_range = make_range_from_width($3); @@ -2400,7 +2436,8 @@ port_declaration delete[]$5; $$ = ptmp; } - | attribute_list_opt K_output atom2_type signed_unsigned_opt IDENTIFIER '=' expression + | attribute_list_opt + K_output atom2_type signed_unsigned_opt IDENTIFIER '=' expression { Module::port_t*ptmp; perm_string name = lex_strings.make($5); list*use_range = make_range_from_width($3); @@ -2421,7 +2458,23 @@ port_declaration delete[]$5; $$ = ptmp; } - + | attribute_list_opt + K_output K_wreal IDENTIFIER + { Module::port_t*ptmp; + perm_string name = lex_strings.make($4); + ptmp = pform_module_port_reference(name, @2.text, + @2.first_line); + pform_module_define_port(@2, name, NetNet::POUTPUT, + NetNet::WIRE, IVL_VT_REAL, true, 0, $1); + port_declaration_context.port_type = NetNet::POUTPUT; + port_declaration_context.port_net_type = NetNet::WIRE; + port_declaration_context.var_type = IVL_VT_REAL; + port_declaration_context.sign_flag = true; + delete port_declaration_context.range; + port_declaration_context.range = 0; + delete[]$4; + $$ = ptmp; + } ; @@ -2612,7 +2665,22 @@ module_item yyerror(@6, "sorry: net delays not supported."); delete $6; } - if ($1) delete $1; + delete $1; + } + + | attribute_list_opt K_wreal delay3 net_variable_list ';' + { pform_makewire(@2, 0, true, $4, NetNet::WIRE, + NetNet::NOT_A_PORT, IVL_VT_REAL, $1); + if ($3 != 0) { + yyerror(@3, "sorry: net delays not supported."); + delete $3; + } + delete $1; + } + | attribute_list_opt K_wreal net_variable_list ';' + { pform_makewire(@2, 0, true, $3, NetNet::WIRE, + NetNet::NOT_A_PORT, IVL_VT_REAL, $1); + delete $1; } /* Very similar to the rule above, but this takes a list of @@ -2652,6 +2720,15 @@ module_item delete $1; } } + | attribute_list_opt K_wreal net_decl_assigns ';' + { pform_makewire(@2, 0, true, 0, str_strength, $3, + NetNet::WIRE, IVL_VT_REAL); + if ($1) { + yyerror(@2, "sorry: Attributes not supported " + "on net declaration assignments."); + delete $1; + } + } | K_trireg charge_strength_opt range_opt delay3_opt list_of_identifiers ';' { yyerror(@1, "sorry: trireg nets not supported."); @@ -2688,6 +2765,11 @@ module_item delete $5; } + | port_type K_wreal list_of_identifiers ';' + { pform_makewire(@1, 0, true, $3, NetNet::WIRE, $1, + IVL_VT_REAL, 0, SR_BOTH); + } + /* var_type declaration (reg variables) cannot be input or output, because the port declaration implies an external driver, which cannot be attached to a reg. These rules catch that error early. */