From efba4bfd0907a8fa27d0f40cc4c76ba01714d903 Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 25 Apr 2008 13:48:14 -0700 Subject: [PATCH] Allow multiple ports in single ANSI decl for tasks and functions This patch adds the functionality to tasks/functions to handle the declaration of multiple ports using a single ANSI declaration. It also deletes the old range vector before it adds the new one. The tasks and functions are different than modules so we need to copy the range for them. --- parse.y | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 7 deletions(-) diff --git a/parse.y b/parse.y index 4ccada4c2..7e33c76d2 100644 --- a/parse.y +++ b/parse.y @@ -42,9 +42,11 @@ static bool active_signed = false; static struct { NetNet::Type port_net_type; NetNet::PortType port_type; + ivl_variable_type_t var_type; bool sign_flag; svector* range; -} port_declaration_context; +} port_declaration_context = {NetNet::NONE, NetNet::NOT_A_PORT, + IVL_VT_NO_TYPE, false, 0}; /* The task and function rules need to briefly hold the pointer to the task/function that is currently in progress. */ @@ -98,6 +100,19 @@ static inline void FILE_NAME(LineInfo*tmp, const struct vlltype&where) tmp->set_file(filename_strings.make(where.text)); } +static svector* copy_range(svector* orig) +{ + svector*copy = 0; + + if (orig) { + copy = new svector(2); + (*copy)[0] = (*orig)[0]; + (*copy)[1] = (*orig)[1]; + } + + return copy; +} + %} %union { @@ -1407,6 +1422,7 @@ port_declaration port_declaration_context.port_type = NetNet::PINPUT; port_declaration_context.port_net_type = $3; port_declaration_context.sign_flag = $4; + delete port_declaration_context.range; port_declaration_context.range = $5; delete $1; delete[]$6; @@ -1423,6 +1439,7 @@ port_declaration port_declaration_context.port_type = NetNet::PINOUT; port_declaration_context.port_net_type = $3; port_declaration_context.sign_flag = $4; + delete port_declaration_context.range; port_declaration_context.range = $5; delete $1; delete[]$6; @@ -1439,6 +1456,7 @@ port_declaration port_declaration_context.port_type = NetNet::POUTPUT; port_declaration_context.port_net_type = $3; port_declaration_context.sign_flag = $4; + delete port_declaration_context.range; port_declaration_context.range = $5; delete $1; delete[]$6; @@ -1455,6 +1473,7 @@ port_declaration port_declaration_context.port_type = NetNet::POUTPUT; port_declaration_context.port_net_type = $3; port_declaration_context.sign_flag = $4; + delete port_declaration_context.range; port_declaration_context.range = $5; delete $1; delete[]$6; @@ -1471,6 +1490,7 @@ port_declaration port_declaration_context.port_type = NetNet::POUTPUT; port_declaration_context.port_net_type = $3; port_declaration_context.sign_flag = $4; + delete port_declaration_context.range; port_declaration_context.range = $5; if (! pform_expression_is_constant($8)) @@ -3397,7 +3417,12 @@ task_item_list_opt task_port_decl : K_input signed_opt range_opt IDENTIFIER - { svector*tmp + { port_declaration_context.port_type = NetNet::PINPUT; + port_declaration_context.var_type = IVL_VT_LOGIC; + port_declaration_context.sign_flag = $2; + delete port_declaration_context.range; + port_declaration_context.range = copy_range($3); + svector*tmp = pform_make_task_ports(NetNet::PINPUT, IVL_VT_LOGIC, $2, $3, list_from_identifier($4), @@ -3406,7 +3431,12 @@ task_port_decl } | K_output signed_opt range_opt IDENTIFIER - { svector*tmp + { port_declaration_context.port_type = NetNet::POUTPUT; + port_declaration_context.var_type = IVL_VT_LOGIC; + port_declaration_context.sign_flag = $2; + delete port_declaration_context.range; + port_declaration_context.range = copy_range($3); + svector*tmp = pform_make_task_ports(NetNet::POUTPUT, IVL_VT_LOGIC, $2, $3, list_from_identifier($4), @@ -3414,7 +3444,12 @@ task_port_decl $$ = tmp; } | K_inout signed_opt range_opt IDENTIFIER - { svector*tmp + { port_declaration_context.port_type = NetNet::PINOUT; + port_declaration_context.var_type = IVL_VT_LOGIC; + port_declaration_context.sign_flag = $2; + delete port_declaration_context.range; + port_declaration_context.range = copy_range($3); + svector*tmp = pform_make_task_ports(NetNet::PINOUT, IVL_VT_LOGIC, $2, $3, list_from_identifier($4), @@ -3431,6 +3466,11 @@ task_port_decl (*range_stub)[0] = re; re = new PENumber(new verinum((uint64_t)0, integer_width)); (*range_stub)[1] = re; + port_declaration_context.port_type = NetNet::PINPUT; + port_declaration_context.var_type = IVL_VT_LOGIC; + port_declaration_context.sign_flag = true; + delete port_declaration_context.range; + port_declaration_context.range = copy_range(range_stub); svector*tmp = pform_make_task_ports(NetNet::PINPUT, IVL_VT_LOGIC, true, @@ -3448,6 +3488,11 @@ task_port_decl (*range_stub)[0] = re; re = new PENumber(new verinum((uint64_t)0, integer_width)); (*range_stub)[1] = re; + port_declaration_context.port_type = NetNet::POUTPUT; + port_declaration_context.var_type = IVL_VT_LOGIC; + port_declaration_context.sign_flag = true; + delete port_declaration_context.range; + port_declaration_context.range = copy_range(range_stub); svector*tmp = pform_make_task_ports(NetNet::POUTPUT, IVL_VT_LOGIC, true, @@ -3465,6 +3510,11 @@ task_port_decl (*range_stub)[0] = re; re = new PENumber(new verinum((uint64_t)0, integer_width)); (*range_stub)[1] = re; + port_declaration_context.port_type = NetNet::PINOUT; + port_declaration_context.var_type = IVL_VT_LOGIC; + port_declaration_context.sign_flag = true; + delete port_declaration_context.range; + port_declaration_context.range = copy_range(range_stub); svector*tmp = pform_make_task_ports(NetNet::PINOUT, IVL_VT_LOGIC, true, @@ -3477,7 +3527,12 @@ task_port_decl /* Ports can be real. */ | K_input K_real IDENTIFIER - { svector*tmp + { port_declaration_context.port_type = NetNet::PINPUT; + port_declaration_context.var_type = IVL_VT_REAL; + port_declaration_context.sign_flag = false; + delete port_declaration_context.range; + port_declaration_context.range = 0; + svector*tmp = pform_make_task_ports(NetNet::PINPUT, IVL_VT_REAL, false, 0, list_from_identifier($3), @@ -3485,7 +3540,12 @@ task_port_decl $$ = tmp; } | K_output K_real IDENTIFIER - { svector*tmp + { port_declaration_context.port_type = NetNet::POUTPUT; + port_declaration_context.var_type = IVL_VT_REAL; + port_declaration_context.sign_flag = false; + delete port_declaration_context.range; + port_declaration_context.range = 0; + svector*tmp = pform_make_task_ports(NetNet::POUTPUT, IVL_VT_REAL, false, 0, list_from_identifier($3), @@ -3493,7 +3553,12 @@ task_port_decl $$ = tmp; } | K_inout K_real IDENTIFIER - { svector*tmp + { port_declaration_context.port_type = NetNet::PINOUT; + port_declaration_context.var_type = IVL_VT_REAL; + port_declaration_context.sign_flag = false; + delete port_declaration_context.range; + port_declaration_context.range = 0; + svector*tmp = pform_make_task_ports(NetNet::PINOUT, IVL_VT_REAL, false, 0, list_from_identifier($3), @@ -3511,6 +3576,31 @@ task_port_decl_list } | task_port_decl { $$ = $1; } + | task_port_decl_list ',' IDENTIFIER + { svector*new_decl + = pform_make_task_ports( + port_declaration_context.port_type, + port_declaration_context.var_type, + port_declaration_context.sign_flag, + copy_range(port_declaration_context.range), + list_from_identifier($3), + @3.text, @3.first_line); + svector*tmp = new svector(*$1, *new_decl); + delete $1; + delete new_decl; + $$ = tmp; + } + | task_port_decl_list ',' + { + yyerror(@2, "error: NULL port declarations are not " + "allowed."); + } + | task_port_decl_list ';' + { + yyerror(@2, "error: ';' is an invalid port declaration " + "separator."); + } + ; ; udp_body