1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
%{
|
|
|
|
|
/*
|
2000-02-23 03:56:53 +01:00
|
|
|
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
|
1998-11-04 00:28:49 +01:00
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2000-02-23 03:56:53 +01:00
|
|
|
#if !defined(WINNT) && !defined(macintosh)
|
2001-04-21 02:55:46 +02:00
|
|
|
#ident "$Id: parse.y,v 1.119 2001/04/21 00:55:46 steve Exp $"
|
1998-11-04 00:28:49 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
# include "parse_misc.h"
|
|
|
|
|
# include "pform.h"
|
|
|
|
|
|
1998-11-23 01:20:22 +01:00
|
|
|
extern void lex_start_table();
|
|
|
|
|
extern void lex_end_table();
|
2000-05-08 07:30:19 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* These are the strengths to use for net declaration
|
|
|
|
|
* assignments. They are stored here so that scope that contains the
|
|
|
|
|
* net_decl_assigns can change them during specific statements.
|
|
|
|
|
*/
|
|
|
|
|
static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
|
1998-11-04 00:28:49 +01:00
|
|
|
%}
|
|
|
|
|
|
|
|
|
|
%union {
|
1998-11-25 03:35:53 +01:00
|
|
|
char letter;
|
2000-10-31 18:00:04 +01:00
|
|
|
/* text items are C strings allocated by the lexor using
|
|
|
|
|
strdup. They can be put into lists with the texts type. */
|
1999-07-10 03:03:18 +02:00
|
|
|
char*text;
|
2000-10-31 18:00:04 +01:00
|
|
|
list<char*>*texts;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
list<string>*strings;
|
|
|
|
|
|
2000-05-06 17:41:56 +02:00
|
|
|
struct str_pair_t drive;
|
|
|
|
|
|
1999-02-03 05:20:11 +01:00
|
|
|
PCase::Item*citem;
|
1999-06-06 22:45:38 +02:00
|
|
|
svector<PCase::Item*>*citems;
|
1999-02-03 05:20:11 +01:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
lgate*gate;
|
1999-05-06 06:37:17 +02:00
|
|
|
svector<lgate>*gates;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-08-03 06:14:49 +02:00
|
|
|
Module::port_t *mport;
|
|
|
|
|
svector<Module::port_t*>*mports;
|
|
|
|
|
|
1999-05-29 04:36:17 +02:00
|
|
|
portname_t*portname;
|
|
|
|
|
svector<portname_t*>*portnames;
|
2000-01-09 06:50:48 +01:00
|
|
|
struct parmvalue_t*parmvalue;
|
1999-05-29 04:36:17 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
PExpr*expr;
|
1999-05-10 02:16:57 +02:00
|
|
|
svector<PExpr*>*exprs;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-04-29 04:16:26 +02:00
|
|
|
svector<PEEvent*>*event_expr;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
NetNet::Type nettype;
|
|
|
|
|
PGBuiltin::Type gatetype;
|
|
|
|
|
NetNet::PortType porttype;
|
|
|
|
|
|
|
|
|
|
PWire*wire;
|
1999-06-12 22:35:27 +02:00
|
|
|
svector<PWire*>*wires;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
PEventStatement*event_statement;
|
|
|
|
|
Statement*statement;
|
1999-06-24 06:24:18 +02:00
|
|
|
svector<Statement*>*statement_list;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
verinum* number;
|
1999-06-15 04:50:02 +02:00
|
|
|
|
|
|
|
|
verireal* realtime;
|
1998-11-04 00:28:49 +01:00
|
|
|
};
|
|
|
|
|
|
1999-06-16 05:13:29 +02:00
|
|
|
%token <text> HIDENTIFIER IDENTIFIER PORTNAME SYSTEM_IDENTIFIER STRING
|
1998-11-04 00:28:49 +01:00
|
|
|
%token <number> NUMBER
|
1999-06-15 04:50:02 +02:00
|
|
|
%token <realtime> REALTIME
|
1999-06-19 05:21:21 +02:00
|
|
|
%token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_LS K_RS K_SG
|
1999-12-31 04:24:30 +01:00
|
|
|
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
|
1998-11-04 00:28:49 +01:00
|
|
|
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case
|
|
|
|
|
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
|
|
|
|
|
%token K_edge K_else K_end K_endcase K_endfunction K_endmodule
|
|
|
|
|
%token K_endprimitive K_endspecify K_endtable K_endtask K_event K_for
|
|
|
|
|
%token K_force K_forever K_fork K_function K_highz0 K_highz1 K_if
|
2000-03-12 18:09:40 +01:00
|
|
|
%token K_initial K_inout K_input K_integer K_join K_large K_localparam
|
|
|
|
|
%token K_macromodule
|
1998-11-04 00:28:49 +01:00
|
|
|
%token K_medium K_module K_nand K_negedge K_nmos K_nor K_not K_notif0
|
1999-02-21 18:01:57 +01:00
|
|
|
%token K_notif1 K_or K_output K_parameter K_pmos K_posedge K_primitive
|
1999-05-20 06:31:45 +02:00
|
|
|
%token K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real K_realtime
|
|
|
|
|
%token K_reg K_release K_repeat
|
1998-11-04 00:28:49 +01:00
|
|
|
%token K_rnmos K_rpmos K_rtran K_rtranif0 K_rtranif1 K_scalered
|
2000-04-02 06:25:39 +02:00
|
|
|
%token K_signed K_small K_specify
|
1998-11-04 00:28:49 +01:00
|
|
|
%token K_specparam K_strong0 K_strong1 K_supply0 K_supply1 K_table K_task
|
|
|
|
|
%token K_time K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand
|
1999-06-15 04:50:02 +02:00
|
|
|
%token K_trior K_trireg K_vectored K_wait K_wand K_weak0 K_weak1
|
|
|
|
|
%token K_while K_wire
|
1998-11-04 00:28:49 +01:00
|
|
|
%token K_wor K_xnor K_xor
|
|
|
|
|
|
1998-11-23 01:20:22 +01:00
|
|
|
%token KK_attribute
|
|
|
|
|
|
2000-05-06 17:41:56 +02:00
|
|
|
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
1998-11-25 03:35:53 +01:00
|
|
|
%type <letter> udp_input_sym udp_output_sym
|
|
|
|
|
%type <text> udp_input_list udp_sequ_entry udp_comb_entry
|
|
|
|
|
%type <strings> udp_entry_list udp_comb_entry_list udp_sequ_entry_list
|
|
|
|
|
%type <strings> udp_body udp_port_list
|
|
|
|
|
%type <wires> udp_port_decl udp_port_decls
|
|
|
|
|
%type <statement> udp_initial udp_init_opt
|
|
|
|
|
|
1999-05-10 02:16:57 +02:00
|
|
|
%type <text> identifier register_variable
|
2000-10-31 18:00:04 +01:00
|
|
|
%type <texts> register_variable_list list_of_variables
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-06-02 04:56:29 +02:00
|
|
|
%type <text> net_decl_assign
|
2000-10-31 18:00:04 +01:00
|
|
|
%type <texts> net_decl_assigns
|
1999-06-02 04:56:29 +02:00
|
|
|
|
1999-09-17 04:06:25 +02:00
|
|
|
%type <mport> port port_opt port_reference port_reference_list
|
1999-08-03 06:14:49 +02:00
|
|
|
%type <mports> list_of_ports list_of_ports_opt
|
|
|
|
|
|
1999-07-24 04:11:19 +02:00
|
|
|
%type <wires> task_item task_item_list task_item_list_opt
|
1999-07-31 21:14:47 +02:00
|
|
|
%type <wires> function_item function_item_list
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2000-01-09 06:50:48 +01:00
|
|
|
%type <portname> port_name parameter_value_byname
|
|
|
|
|
%type <portnames> port_name_list parameter_value_byname_list
|
1999-05-29 04:36:17 +02:00
|
|
|
|
1999-02-03 05:20:11 +01:00
|
|
|
%type <citem> case_item
|
|
|
|
|
%type <citems> case_items
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
%type <gate> gate_instance
|
|
|
|
|
%type <gates> gate_instance_list
|
|
|
|
|
|
1999-05-30 05:12:56 +02:00
|
|
|
%type <expr> expression expr_primary
|
1999-05-10 02:16:57 +02:00
|
|
|
%type <expr> lavalue lpvalue
|
2000-01-02 02:59:52 +01:00
|
|
|
%type <expr> delay_value delay_value_simple
|
2000-01-09 06:50:48 +01:00
|
|
|
%type <exprs> delay1 delay3 delay3_opt
|
1998-11-04 00:28:49 +01:00
|
|
|
%type <exprs> expression_list
|
1999-08-27 17:08:37 +02:00
|
|
|
%type <exprs> assign assign_list
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
%type <exprs> range range_opt
|
|
|
|
|
%type <nettype> net_type
|
|
|
|
|
%type <gatetype> gatetype
|
|
|
|
|
%type <porttype> port_type
|
2000-01-09 06:50:48 +01:00
|
|
|
%type <parmvalue> parameter_value_opt
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-08-26 00:22:41 +02:00
|
|
|
%type <exprs> range_or_type_opt
|
1999-09-30 00:56:31 +02:00
|
|
|
%type <event_expr> event_expression_list
|
1999-04-29 04:16:26 +02:00
|
|
|
%type <event_expr> event_expression
|
|
|
|
|
%type <event_statement> event_control
|
1998-11-04 00:28:49 +01:00
|
|
|
%type <statement> statement statement_opt
|
|
|
|
|
%type <statement_list> statement_list
|
|
|
|
|
|
1999-09-30 00:56:31 +02:00
|
|
|
%right '?' ':'
|
1999-03-15 03:43:32 +01:00
|
|
|
%left K_LOR
|
1999-03-16 05:44:45 +01:00
|
|
|
%left K_LAND
|
|
|
|
|
%left '|'
|
1999-09-30 04:43:01 +02:00
|
|
|
%left '^' K_NXOR K_NOR
|
|
|
|
|
%left '&' K_NAND
|
1999-03-16 05:44:45 +01:00
|
|
|
%left K_EQ K_NE K_CEQ K_CNE
|
|
|
|
|
%left K_GE K_LE '<' '>'
|
1999-05-16 07:08:42 +02:00
|
|
|
%left K_LS K_RS
|
1999-03-16 05:44:45 +01:00
|
|
|
%left '+' '-'
|
1999-05-16 07:08:42 +02:00
|
|
|
%left '*' '/' '%'
|
1999-03-16 05:44:45 +01:00
|
|
|
%left UNARY_PREC
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-09-30 00:56:31 +02:00
|
|
|
/* to resolve dangling else ambiguity: */
|
|
|
|
|
%nonassoc less_than_K_else
|
|
|
|
|
%nonassoc K_else
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
%%
|
|
|
|
|
|
1999-10-15 07:03:33 +02:00
|
|
|
/* A degenerate source file can be completely empty. */
|
|
|
|
|
main : source_file | ;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
source_file
|
|
|
|
|
: description
|
|
|
|
|
| source_file description
|
|
|
|
|
;
|
|
|
|
|
|
1999-09-30 03:22:37 +02:00
|
|
|
/* The block_item_decl is used in function definitions, task
|
|
|
|
|
definitions, module definitions and named blocks. Wherever a new
|
|
|
|
|
scope is entered, the source may declare new registers and
|
|
|
|
|
integers. This rule matches those declarations. The containing
|
|
|
|
|
rule has presumably set up the scope. */
|
1999-06-24 06:24:18 +02:00
|
|
|
block_item_decl
|
1999-09-10 07:02:09 +02:00
|
|
|
: K_reg range register_variable_list ';'
|
2000-12-11 01:31:43 +01:00
|
|
|
{ pform_set_net_range($3, $2, false);
|
1999-09-10 07:02:09 +02:00
|
|
|
}
|
|
|
|
|
| K_reg register_variable_list ';'
|
|
|
|
|
{ delete $2; }
|
2000-04-02 06:25:39 +02:00
|
|
|
| K_reg K_signed range register_variable_list ';'
|
2000-12-11 01:31:43 +01:00
|
|
|
{ pform_set_net_range($4, $3, true);
|
2000-04-02 06:25:39 +02:00
|
|
|
}
|
|
|
|
|
| K_reg K_signed register_variable_list ';'
|
|
|
|
|
{ delete $3;
|
|
|
|
|
yyerror(@2, "sorry: signed reg not supported.");
|
|
|
|
|
}
|
2001-01-06 03:29:35 +01:00
|
|
|
| K_integer register_variable_list ';'
|
1999-09-10 07:02:09 +02:00
|
|
|
{ pform_set_reg_integer($2);
|
|
|
|
|
}
|
2001-01-06 07:31:58 +01:00
|
|
|
| K_time register_variable_list ';'
|
2000-10-31 18:49:02 +01:00
|
|
|
{ pform_set_reg_time($2);
|
|
|
|
|
}
|
2000-12-05 23:32:05 +01:00
|
|
|
| K_real list_of_variables ';'
|
|
|
|
|
{ delete $2;
|
|
|
|
|
yyerror(@1, "sorry: real variables not supported.");
|
|
|
|
|
}
|
|
|
|
|
| K_realtime list_of_variables ';'
|
|
|
|
|
{ delete $2;
|
|
|
|
|
yyerror(@1, "sorry: reatime variables not supported.");
|
|
|
|
|
}
|
2001-01-13 23:20:08 +01:00
|
|
|
| K_parameter parameter_assign_list ';'
|
|
|
|
|
| K_localparam localparam_assign_list ';'
|
2001-01-06 07:31:58 +01:00
|
|
|
|
|
|
|
|
/* Recover from errors that happen within variable lists. Use the
|
|
|
|
|
trailing semi-colon to resync the parser. */
|
|
|
|
|
|
|
|
|
|
| K_reg error ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error in reg variable list.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
|
|
|
|
| K_integer error ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error in integer variable list.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
|
|
|
|
| K_time error ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error in time variable list.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
|
|
|
|
| K_real error ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error in real variable list.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
|
|
|
|
| K_realtime error ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error in realtime variable list.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
2001-01-13 23:20:08 +01:00
|
|
|
| K_parameter error ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error in parameter list.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
|
|
|
|
| K_localparam error ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error localparam list.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
1999-06-24 06:24:18 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
block_item_decls
|
|
|
|
|
: block_item_decl
|
|
|
|
|
| block_item_decls block_item_decl
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
block_item_decls_opt
|
|
|
|
|
: block_item_decls
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
1999-02-03 05:20:11 +01:00
|
|
|
case_item
|
1999-06-12 05:42:57 +02:00
|
|
|
: expression_list ':' statement_opt
|
1999-02-03 05:20:11 +01:00
|
|
|
{ PCase::Item*tmp = new PCase::Item;
|
1999-06-15 07:38:39 +02:00
|
|
|
tmp->expr = *$1;
|
1999-02-03 05:20:11 +01:00
|
|
|
tmp->stat = $3;
|
1999-06-15 07:38:39 +02:00
|
|
|
delete $1;
|
1999-02-03 05:20:11 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_default ':' statement_opt
|
|
|
|
|
{ PCase::Item*tmp = new PCase::Item;
|
|
|
|
|
tmp->stat = $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_default statement_opt
|
|
|
|
|
{ PCase::Item*tmp = new PCase::Item;
|
|
|
|
|
tmp->stat = $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-06-12 05:42:57 +02:00
|
|
|
| error ':' statement_opt
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@1, "error: Incomprehensible case expression.");
|
1999-06-12 05:42:57 +02:00
|
|
|
yyerrok;
|
|
|
|
|
}
|
1999-02-03 05:20:11 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
case_items
|
|
|
|
|
: case_items case_item
|
1999-06-06 22:45:38 +02:00
|
|
|
{ svector<PCase::Item*>*tmp;
|
|
|
|
|
tmp = new svector<PCase::Item*>(*$1, $2);
|
|
|
|
|
delete $1;
|
1999-02-03 05:20:11 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| case_item
|
1999-06-06 22:45:38 +02:00
|
|
|
{ svector<PCase::Item*>*tmp = new svector<PCase::Item*>(1);
|
|
|
|
|
(*tmp)[0] = $1;
|
1999-02-03 05:20:11 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
1999-06-15 04:50:02 +02:00
|
|
|
charge_strength
|
|
|
|
|
: '(' K_small ')'
|
|
|
|
|
| '(' K_medium ')'
|
|
|
|
|
| '(' K_large ')'
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
charge_strength_opt
|
|
|
|
|
: charge_strength
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
1999-06-16 05:13:29 +02:00
|
|
|
defparam_assign
|
|
|
|
|
: identifier '=' expression
|
|
|
|
|
{ PExpr*tmp = $3;
|
|
|
|
|
if (!pform_expression_is_constant(tmp)) {
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@3, "error: parameter value "
|
|
|
|
|
"must be constant.");
|
1999-06-16 05:13:29 +02:00
|
|
|
delete tmp;
|
|
|
|
|
tmp = 0;
|
|
|
|
|
}
|
2000-03-08 05:36:53 +01:00
|
|
|
pform_set_defparam($1, $3);
|
1999-06-16 05:13:29 +02:00
|
|
|
delete $1;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
defparam_assign_list
|
|
|
|
|
: defparam_assign
|
|
|
|
|
| range defparam_assign
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yywarn(@1, "Ranges in parameter definition "
|
|
|
|
|
"are not supported.");
|
1999-06-16 05:13:29 +02:00
|
|
|
delete $1;
|
|
|
|
|
}
|
|
|
|
|
| defparam_assign_list ',' defparam_assign
|
|
|
|
|
;
|
|
|
|
|
|
1999-12-31 04:24:30 +01:00
|
|
|
delay1
|
2000-01-02 02:59:52 +01:00
|
|
|
: '#' delay_value_simple
|
1999-08-01 18:34:50 +02:00
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
|
|
|
|
|
(*tmp)[0] = $2;
|
|
|
|
|
$$ = tmp;
|
1999-05-30 05:12:56 +02:00
|
|
|
}
|
1999-12-31 18:39:00 +01:00
|
|
|
| '#' '(' delay_value ')'
|
|
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
|
|
|
|
|
(*tmp)[0] = $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-12-31 04:24:30 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
delay3
|
2000-01-02 02:59:52 +01:00
|
|
|
: '#' delay_value_simple
|
1999-12-31 04:24:30 +01:00
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
|
|
|
|
|
(*tmp)[0] = $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| '#' '(' delay_value ')'
|
|
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
|
|
|
|
|
(*tmp)[0] = $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| '#' '(' delay_value ',' delay_value ')'
|
|
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(2);
|
|
|
|
|
(*tmp)[0] = $3;
|
|
|
|
|
(*tmp)[1] = $5;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| '#' '(' delay_value ',' delay_value ',' delay_value ')'
|
|
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(3);
|
|
|
|
|
(*tmp)[0] = $3;
|
|
|
|
|
(*tmp)[1] = $5;
|
2000-05-31 03:31:52 +02:00
|
|
|
(*tmp)[2] = $7;
|
1999-12-31 04:24:30 +01:00
|
|
|
$$ = tmp;
|
1999-05-30 05:12:56 +02:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
1999-12-31 04:24:30 +01:00
|
|
|
delay3_opt
|
|
|
|
|
: delay3 { $$ = $1; }
|
|
|
|
|
| { $$ = 0; }
|
1999-05-30 05:12:56 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
delay_value
|
2000-01-02 02:59:52 +01:00
|
|
|
: expression
|
|
|
|
|
{ PExpr*tmp = $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| expression ':' expression ':' expression
|
2000-07-29 19:58:20 +02:00
|
|
|
{ $$ = pform_select_mtm_expr($1, $3, $5); }
|
2000-01-02 02:59:52 +01:00
|
|
|
;
|
2000-06-27 18:00:40 +02:00
|
|
|
|
2000-01-02 02:59:52 +01:00
|
|
|
|
|
|
|
|
delay_value_simple
|
1999-05-30 05:12:56 +02:00
|
|
|
: NUMBER
|
|
|
|
|
{ verinum*tmp = $1;
|
1999-03-16 05:44:45 +01:00
|
|
|
if (tmp == 0) {
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@1, "internal error: delay.");
|
1999-03-16 05:44:45 +01:00
|
|
|
$$ = 0;
|
|
|
|
|
} else {
|
|
|
|
|
$$ = new PENumber(tmp);
|
1999-07-12 02:59:36 +02:00
|
|
|
$$->set_file(@1.text);
|
|
|
|
|
$$->set_lineno(@1.first_line);
|
1999-03-16 05:44:45 +01:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
2000-12-10 23:01:35 +01:00
|
|
|
| REALTIME
|
|
|
|
|
{ verireal*tmp = $1;
|
|
|
|
|
if (tmp == 0) {
|
|
|
|
|
yyerror(@1, "internal error: delay.");
|
|
|
|
|
$$ = 0;
|
|
|
|
|
} else {
|
|
|
|
|
$$ = new PEFNumber(tmp);
|
|
|
|
|
$$->set_file(@1.text);
|
|
|
|
|
$$->set_lineno(@1.first_line);
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-05-30 05:12:56 +02:00
|
|
|
| IDENTIFIER
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-05-08 22:19:20 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-30 05:12:56 +02:00
|
|
|
delete $1;
|
1999-05-20 06:31:45 +02:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
description
|
|
|
|
|
: module
|
1998-11-23 01:20:22 +01:00
|
|
|
| udp_primitive
|
1998-12-01 01:42:13 +01:00
|
|
|
| KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_set_type_attrib($3, $5, $7);
|
1998-12-01 01:42:13 +01:00
|
|
|
delete $3;
|
|
|
|
|
delete $5;
|
|
|
|
|
delete $7;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
1999-11-05 20:36:36 +01:00
|
|
|
drive_strength
|
|
|
|
|
: '(' dr_strength0 ',' dr_strength1 ')'
|
2000-05-06 17:41:56 +02:00
|
|
|
{ $$.str0 = $2.str0;
|
|
|
|
|
$$.str1 = $4.str1;
|
|
|
|
|
}
|
1999-11-05 20:36:36 +01:00
|
|
|
| '(' dr_strength1 ',' dr_strength0 ')'
|
2000-05-06 17:41:56 +02:00
|
|
|
{ $$.str0 = $4.str0;
|
|
|
|
|
$$.str1 = $2.str1;
|
|
|
|
|
}
|
1999-11-05 20:36:36 +01:00
|
|
|
| '(' dr_strength0 ',' K_highz1 ')'
|
2000-05-06 17:41:56 +02:00
|
|
|
{ $$.str0 = $2.str0;
|
|
|
|
|
$$.str1 = PGate::HIGHZ;
|
|
|
|
|
}
|
1999-11-05 20:36:36 +01:00
|
|
|
| '(' dr_strength1 ',' K_highz0 ')'
|
2000-05-06 17:41:56 +02:00
|
|
|
{ $$.str0 = PGate::HIGHZ;
|
|
|
|
|
$$.str1 = $2.str1;
|
|
|
|
|
}
|
1999-11-05 20:36:36 +01:00
|
|
|
| '(' K_highz1 ',' dr_strength0 ')'
|
2000-05-06 17:41:56 +02:00
|
|
|
{ $$.str0 = $4.str0;
|
|
|
|
|
$$.str1 = PGate::HIGHZ;
|
|
|
|
|
}
|
1999-11-05 20:36:36 +01:00
|
|
|
| '(' K_highz0 ',' dr_strength1 ')'
|
2000-05-06 17:41:56 +02:00
|
|
|
{ $$.str0 = PGate::HIGHZ;
|
|
|
|
|
$$.str1 = $4.str1;
|
|
|
|
|
}
|
1999-11-05 20:36:36 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
drive_strength_opt
|
2000-05-06 17:41:56 +02:00
|
|
|
: drive_strength { $$ = $1; }
|
|
|
|
|
| { $$.str0 = PGate::STRONG; $$.str1 = PGate::STRONG; }
|
1999-11-05 20:36:36 +01:00
|
|
|
;
|
|
|
|
|
|
2000-05-06 17:41:56 +02:00
|
|
|
dr_strength0
|
|
|
|
|
: K_supply0 { $$.str0 = PGate::SUPPLY; }
|
|
|
|
|
| K_strong0 { $$.str0 = PGate::STRONG; }
|
|
|
|
|
| K_pull0 { $$.str0 = PGate::PULL; }
|
|
|
|
|
| K_weak0 { $$.str0 = PGate::WEAK; }
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
dr_strength1
|
|
|
|
|
: K_supply1 { $$.str1 = PGate::SUPPLY; }
|
|
|
|
|
| K_strong1 { $$.str1 = PGate::STRONG; }
|
|
|
|
|
| K_pull1 { $$.str1 = PGate::PULL; }
|
|
|
|
|
| K_weak1 { $$.str1 = PGate::WEAK; }
|
|
|
|
|
;
|
1999-11-05 20:36:36 +01:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
event_control
|
|
|
|
|
: '@' IDENTIFIER
|
2000-04-12 06:23:57 +02:00
|
|
|
{ PEIdent*tmpi = new PEIdent($2);
|
|
|
|
|
tmpi->set_file(@2.text);
|
|
|
|
|
tmpi->set_lineno(@2.first_line);
|
2000-04-01 21:31:57 +02:00
|
|
|
delete[]$2;
|
2000-04-12 06:23:57 +02:00
|
|
|
PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi);
|
2000-04-01 21:31:57 +02:00
|
|
|
PEventStatement*tmps = new PEventStatement(tmpe);
|
|
|
|
|
tmps->set_file(@1.text);
|
|
|
|
|
tmps->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmps;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-09-30 00:56:31 +02:00
|
|
|
| '@' '(' event_expression_list ')'
|
1999-04-29 04:16:26 +02:00
|
|
|
{ PEventStatement*tmp = new PEventStatement(*$3);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| '@' '(' error ')'
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@1, "error: Malformed event control expression.");
|
1999-04-29 04:16:26 +02:00
|
|
|
$$ = 0;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
1999-09-30 00:56:31 +02:00
|
|
|
event_expression_list
|
|
|
|
|
: event_expression
|
|
|
|
|
{ $$ = $1; }
|
|
|
|
|
| event_expression_list K_or event_expression
|
|
|
|
|
{ svector<PEEvent*>*tmp = new svector<PEEvent*>(*$1, *$3);
|
|
|
|
|
delete $1;
|
|
|
|
|
delete $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2000-04-15 21:51:30 +02:00
|
|
|
| event_expression_list ',' event_expression
|
|
|
|
|
{ svector<PEEvent*>*tmp = new svector<PEEvent*>(*$1, *$3);
|
|
|
|
|
delete $1;
|
|
|
|
|
delete $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-09-30 00:56:31 +02:00
|
|
|
;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
event_expression
|
|
|
|
|
: K_posedge expression
|
2000-04-12 06:23:57 +02:00
|
|
|
{ PEEvent*tmp = new PEEvent(PEEvent::POSEDGE, $2);
|
1999-04-29 04:16:26 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
|
|
|
|
|
(*tl)[0] = tmp;
|
|
|
|
|
$$ = tl;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
| K_negedge expression
|
2000-04-12 06:23:57 +02:00
|
|
|
{ PEEvent*tmp = new PEEvent(PEEvent::NEGEDGE, $2);
|
1999-04-29 04:16:26 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
|
|
|
|
|
(*tl)[0] = tmp;
|
|
|
|
|
$$ = tl;
|
|
|
|
|
}
|
|
|
|
|
| expression
|
2000-04-12 06:23:57 +02:00
|
|
|
{ PEEvent*tmp = new PEEvent(PEEvent::ANYEDGE, $1);
|
1999-04-29 04:16:26 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
svector<PEEvent*>*tl = new svector<PEEvent*>(1);
|
|
|
|
|
(*tl)[0] = tmp;
|
|
|
|
|
$$ = tl;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
expression
|
|
|
|
|
: expr_primary
|
|
|
|
|
{ $$ = $1; }
|
1999-05-20 06:31:45 +02:00
|
|
|
| '+' expr_primary %prec UNARY_PREC
|
1999-06-13 19:30:23 +02:00
|
|
|
{ $$ = $2; }
|
1999-05-20 06:31:45 +02:00
|
|
|
| '-' expr_primary %prec UNARY_PREC
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEUnary*tmp = new PEUnary('-', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-20 06:31:45 +02:00
|
|
|
}
|
|
|
|
|
| '~' expr_primary %prec UNARY_PREC
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEUnary*tmp = new PEUnary('~', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-05-20 06:31:45 +02:00
|
|
|
| '&' expr_primary %prec UNARY_PREC
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEUnary*tmp = new PEUnary('&', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-05-20 06:31:45 +02:00
|
|
|
| '!' expr_primary %prec UNARY_PREC
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEUnary*tmp = new PEUnary('!', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-03-15 03:43:32 +01:00
|
|
|
}
|
1999-05-20 06:31:45 +02:00
|
|
|
| '|' expr_primary %prec UNARY_PREC
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEUnary*tmp = new PEUnary('|', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-20 06:31:45 +02:00
|
|
|
}
|
|
|
|
|
| '^' expr_primary %prec UNARY_PREC
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEUnary*tmp = new PEUnary('^', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-20 06:31:45 +02:00
|
|
|
}
|
1999-06-13 19:30:23 +02:00
|
|
|
| K_NAND expr_primary %prec UNARY_PREC
|
|
|
|
|
{ PEUnary*tmp = new PEUnary('A', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_NOR expr_primary %prec UNARY_PREC
|
|
|
|
|
{ PEUnary*tmp = new PEUnary('N', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_NXOR expr_primary %prec UNARY_PREC
|
|
|
|
|
{ PEUnary*tmp = new PEUnary('X', $2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2000-04-21 05:22:18 +02:00
|
|
|
| '!' error %prec UNARY_PREC
|
|
|
|
|
{ yyerror(@1, "error: Operand of unary ! "
|
|
|
|
|
"is not a primary expression.");
|
|
|
|
|
$$ = 0;
|
|
|
|
|
}
|
|
|
|
|
| '^' error %prec UNARY_PREC
|
|
|
|
|
{ yyerror(@1, "error: Operand of reduction ^ "
|
|
|
|
|
"is not a primary expression.");
|
|
|
|
|
$$ = 0;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
| expression '^' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('^', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-05-16 07:08:42 +02:00
|
|
|
| expression '*' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('*', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
|
|
|
|
| expression '/' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('/', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
|
|
|
|
| expression '%' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('%', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
| expression '+' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('+', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1998-11-09 19:55:33 +01:00
|
|
|
| expression '-' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('-', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-09 19:55:33 +01:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
| expression '&' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('&', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-03-15 03:43:32 +01:00
|
|
|
| expression '|' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('|', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-03-15 03:43:32 +01:00
|
|
|
}
|
1999-09-30 04:43:01 +02:00
|
|
|
| expression K_NOR expression
|
|
|
|
|
{ PEBinary*tmp = new PEBinary('O', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| expression K_NXOR expression
|
|
|
|
|
{ PEBinary*tmp = new PEBinary('X', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-05-08 22:19:20 +02:00
|
|
|
| expression '<' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('<', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-08 22:19:20 +02:00
|
|
|
}
|
|
|
|
|
| expression '>' expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('>', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-08 22:19:20 +02:00
|
|
|
}
|
1999-05-16 07:08:42 +02:00
|
|
|
| expression K_LS expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('l', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
|
|
|
|
| expression K_RS expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('r', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
1998-11-07 18:05:05 +01:00
|
|
|
| expression K_EQ expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('e', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-07 18:05:05 +01:00
|
|
|
}
|
|
|
|
|
| expression K_CEQ expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('E', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-07 18:05:05 +01:00
|
|
|
}
|
1999-05-16 07:08:42 +02:00
|
|
|
| expression K_LE expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('L', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
|
|
|
|
| expression K_GE expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('G', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
1998-11-07 18:05:05 +01:00
|
|
|
| expression K_NE expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('n', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-07 18:05:05 +01:00
|
|
|
}
|
|
|
|
|
| expression K_CNE expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('N', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-07 18:05:05 +01:00
|
|
|
}
|
1999-03-15 03:43:32 +01:00
|
|
|
| expression K_LOR expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('o', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-03-15 03:43:32 +01:00
|
|
|
}
|
|
|
|
|
| expression K_LAND expression
|
1999-05-27 05:31:29 +02:00
|
|
|
{ PEBinary*tmp = new PEBinary('a', $1, $3);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-03-15 03:43:32 +01:00
|
|
|
}
|
1999-05-20 06:31:45 +02:00
|
|
|
| expression '?' expression ':' expression
|
1999-06-10 06:03:52 +02:00
|
|
|
{ PETernary*tmp = new PETernary($1, $3, $5);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-20 06:31:45 +02:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
2000-05-23 18:03:13 +02:00
|
|
|
/* Many contexts take a comma separated list of expressions. Null
|
|
|
|
|
expressions can happen anywhere in the list, so there are two
|
|
|
|
|
extra rules for parsing and installing those nulls. */
|
1998-11-04 00:28:49 +01:00
|
|
|
expression_list
|
|
|
|
|
: expression_list ',' expression
|
1999-05-10 02:16:57 +02:00
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(*$1, $3);
|
|
|
|
|
delete $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| expression
|
1999-05-10 02:16:57 +02:00
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
|
|
|
|
|
(*tmp)[0] = $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2000-05-23 18:03:13 +02:00
|
|
|
|
|
|
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
|
|
|
|
|
(*tmp)[0] = 0;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
| expression_list ','
|
1999-05-10 02:16:57 +02:00
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(*$1, 0);
|
|
|
|
|
delete $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
2000-10-14 04:23:02 +02:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
expr_primary
|
|
|
|
|
: NUMBER
|
1999-06-15 04:50:02 +02:00
|
|
|
{ assert($1);
|
|
|
|
|
PENumber*tmp = new PENumber($1);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| REALTIME
|
2001-01-15 00:04:55 +01:00
|
|
|
{ PEFNumber*tmp = new PEFNumber($1);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
| STRING
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEString*tmp = new PEString($1);
|
1999-05-27 05:31:29 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $1;
|
|
|
|
|
}
|
|
|
|
|
| identifier
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-04-19 03:59:36 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $1;
|
|
|
|
|
}
|
|
|
|
|
| SYSTEM_IDENTIFIER
|
2000-05-04 05:37:58 +02:00
|
|
|
{ PECallFunction*tmp = new PECallFunction($1);
|
1999-05-27 05:31:29 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
2000-05-04 05:37:58 +02:00
|
|
|
delete $1
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
| identifier '[' expression ']'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-04-19 03:59:36 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1998-11-04 00:28:49 +01:00
|
|
|
tmp->msb_ = $3;
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| identifier '[' expression ':' expression ']'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-04-19 03:59:36 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1998-11-04 00:28:49 +01:00
|
|
|
tmp->msb_ = $3;
|
|
|
|
|
tmp->lsb_ = $5;
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-06-16 05:13:29 +02:00
|
|
|
| identifier '(' expression_list ')'
|
1999-07-31 21:14:47 +02:00
|
|
|
{ PECallFunction*tmp = new PECallFunction($1, *$3);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-06-16 05:13:29 +02:00
|
|
|
}
|
|
|
|
|
| SYSTEM_IDENTIFIER '(' expression_list ')'
|
1999-09-25 04:57:29 +02:00
|
|
|
{ PECallFunction*tmp = new PECallFunction($1, *$3);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-06-16 05:13:29 +02:00
|
|
|
}
|
1999-06-09 05:00:05 +02:00
|
|
|
| '(' expression ')'
|
|
|
|
|
{ $$ = $2; }
|
1999-06-10 06:03:52 +02:00
|
|
|
| '{' expression_list '}'
|
|
|
|
|
{ PEConcat*tmp = new PEConcat(*$2);
|
2000-10-14 04:23:02 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-06-10 06:03:52 +02:00
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| '{' expression '{' expression_list '}' '}'
|
|
|
|
|
{ PExpr*rep = $2;
|
|
|
|
|
if (!pform_expression_is_constant($2)) {
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@2, "error: Repeat expression "
|
|
|
|
|
"must be constant.");
|
1999-06-10 06:03:52 +02:00
|
|
|
delete rep;
|
|
|
|
|
delete $2;
|
|
|
|
|
rep = 0;
|
|
|
|
|
}
|
|
|
|
|
PEConcat*tmp = new PEConcat(*$4, rep);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $4;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
1999-05-30 05:12:56 +02:00
|
|
|
|
1999-09-30 03:22:37 +02:00
|
|
|
/* A function_item is either a block item (i.e. a reg or integer
|
|
|
|
|
declaration) or an input declaration. There are no output or
|
|
|
|
|
inout ports. */
|
1999-05-30 05:12:56 +02:00
|
|
|
function_item
|
|
|
|
|
: K_input range_opt list_of_variables ';'
|
1999-07-31 21:14:47 +02:00
|
|
|
{ svector<PWire*>*tmp
|
1999-09-10 07:02:09 +02:00
|
|
|
= pform_make_task_ports(NetNet::PINPUT, $2, $3,
|
|
|
|
|
@1.text, @1.first_line);
|
1999-07-31 21:14:47 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-09-30 03:22:37 +02:00
|
|
|
| block_item_decl
|
1999-07-31 21:14:47 +02:00
|
|
|
{ $$ = 0; }
|
1999-05-30 05:12:56 +02:00
|
|
|
;
|
|
|
|
|
|
1999-09-30 02:48:04 +02:00
|
|
|
/* A function_item_list only lists the input/output/inout
|
|
|
|
|
declarations. The integer and reg declarations are handled in
|
|
|
|
|
place, so are not listed. The list builder needs to account for
|
|
|
|
|
the possibility that the various parts may be NULL. */
|
1999-05-30 05:12:56 +02:00
|
|
|
function_item_list
|
|
|
|
|
: function_item
|
1999-07-31 21:14:47 +02:00
|
|
|
{ $$ = $1; }
|
1999-05-30 05:12:56 +02:00
|
|
|
| function_item_list function_item
|
1999-09-30 02:48:04 +02:00
|
|
|
{ if ($1 && $2) {
|
|
|
|
|
svector<PWire*>*tmp = new svector<PWire*>(*$1, *$2);
|
|
|
|
|
delete $1;
|
|
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
} else if ($1) {
|
|
|
|
|
$$ = $1;
|
|
|
|
|
} else {
|
|
|
|
|
$$ = $2;
|
|
|
|
|
}
|
1999-07-31 21:14:47 +02:00
|
|
|
}
|
1999-05-30 05:12:56 +02:00
|
|
|
;
|
|
|
|
|
|
1999-05-08 22:19:20 +02:00
|
|
|
/* A gate_instance is a module instantiation or a built in part
|
|
|
|
|
type. In any case, the gate has a set of connections to ports. */
|
1998-11-04 00:28:49 +01:00
|
|
|
gate_instance
|
|
|
|
|
: IDENTIFIER '(' expression_list ')'
|
|
|
|
|
{ lgate*tmp = new lgate;
|
1999-08-02 01:25:51 +02:00
|
|
|
tmp->name = $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
tmp->parms = $3;
|
1999-01-25 06:45:56 +01:00
|
|
|
tmp->file = @1.text;
|
|
|
|
|
tmp->lineno = @1.first_line;
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2000-05-23 18:03:13 +02:00
|
|
|
|
1999-02-15 03:06:15 +01:00
|
|
|
| IDENTIFIER range '(' expression_list ')'
|
|
|
|
|
{ lgate*tmp = new lgate;
|
1999-05-10 02:16:57 +02:00
|
|
|
svector<PExpr*>*rng = $2;
|
1999-08-02 01:25:51 +02:00
|
|
|
tmp->name = $1;
|
1999-02-15 03:06:15 +01:00
|
|
|
tmp->parms = $4;
|
1999-05-10 02:16:57 +02:00
|
|
|
tmp->range[0] = (*rng)[0];
|
|
|
|
|
tmp->range[1] = (*rng)[1];
|
1999-02-15 03:06:15 +01:00
|
|
|
tmp->file = @1.text;
|
|
|
|
|
tmp->lineno = @1.first_line;
|
|
|
|
|
delete $1;
|
|
|
|
|
delete rng;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
| '(' expression_list ')'
|
|
|
|
|
{ lgate*tmp = new lgate;
|
|
|
|
|
tmp->name = "";
|
|
|
|
|
tmp->parms = $2;
|
1999-01-25 06:45:56 +01:00
|
|
|
tmp->file = @1.text;
|
|
|
|
|
tmp->lineno = @1.first_line;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2000-05-23 18:03:13 +02:00
|
|
|
|
|
|
|
|
/* Modules can also take ports by port-name expressions. */
|
|
|
|
|
|
1999-05-08 22:19:20 +02:00
|
|
|
| IDENTIFIER '(' port_name_list ')'
|
|
|
|
|
{ lgate*tmp = new lgate;
|
1999-08-02 01:25:51 +02:00
|
|
|
tmp->name = $1;
|
1999-05-29 04:36:17 +02:00
|
|
|
tmp->parms_by_name = $3;
|
1999-05-08 22:19:20 +02:00
|
|
|
tmp->file = @1.text;
|
|
|
|
|
tmp->lineno = @1.first_line;
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
gate_instance_list
|
|
|
|
|
: gate_instance_list ',' gate_instance
|
1999-05-06 06:37:17 +02:00
|
|
|
{ svector<lgate>*tmp1 = $1;
|
|
|
|
|
lgate*tmp2 = $3;
|
|
|
|
|
svector<lgate>*out = new svector<lgate> (*tmp1, *tmp2);
|
|
|
|
|
delete tmp1;
|
|
|
|
|
delete tmp2;
|
|
|
|
|
$$ = out;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
| gate_instance
|
1999-05-06 06:37:17 +02:00
|
|
|
{ svector<lgate>*tmp = new svector<lgate>(1);
|
|
|
|
|
(*tmp)[0] = *$1;
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
gatetype
|
|
|
|
|
: K_and { $$ = PGBuiltin::AND; }
|
|
|
|
|
| K_nand { $$ = PGBuiltin::NAND; }
|
|
|
|
|
| K_or { $$ = PGBuiltin::OR; }
|
|
|
|
|
| K_nor { $$ = PGBuiltin::NOR; }
|
|
|
|
|
| K_xor { $$ = PGBuiltin::XOR; }
|
|
|
|
|
| K_xnor { $$ = PGBuiltin::XNOR; }
|
|
|
|
|
| K_buf { $$ = PGBuiltin::BUF; }
|
|
|
|
|
| K_bufif0 { $$ = PGBuiltin::BUFIF0; }
|
|
|
|
|
| K_bufif1 { $$ = PGBuiltin::BUFIF1; }
|
|
|
|
|
| K_not { $$ = PGBuiltin::NOT; }
|
|
|
|
|
| K_notif0 { $$ = PGBuiltin::NOTIF0; }
|
|
|
|
|
| K_notif1 { $$ = PGBuiltin::NOTIF1; }
|
|
|
|
|
| K_nmos { $$ = PGBuiltin::NMOS; }
|
|
|
|
|
| K_rnmos { $$ = PGBuiltin::RNMOS; }
|
|
|
|
|
| K_pmos { $$ = PGBuiltin::PMOS; }
|
|
|
|
|
| K_rpmos { $$ = PGBuiltin::RPMOS; }
|
|
|
|
|
| K_cmos { $$ = PGBuiltin::CMOS; }
|
|
|
|
|
| K_rcmos { $$ = PGBuiltin::RCMOS; }
|
|
|
|
|
| K_tran { $$ = PGBuiltin::TRAN; }
|
|
|
|
|
| K_rtran { $$ = PGBuiltin::RTRAN; }
|
|
|
|
|
| K_tranif0 { $$ = PGBuiltin::TRANIF0; }
|
|
|
|
|
| K_tranif1 { $$ = PGBuiltin::TRANIF1; }
|
|
|
|
|
| K_rtranif0 { $$ = PGBuiltin::RTRANIF0; }
|
|
|
|
|
| K_rtranif1 { $$ = PGBuiltin::RTRANIF1; }
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
identifier
|
1999-06-16 05:13:29 +02:00
|
|
|
: IDENTIFIER
|
|
|
|
|
{ $$ = $1; }
|
|
|
|
|
| HIDENTIFIER
|
1999-11-15 05:43:52 +01:00
|
|
|
{ $$ = $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
list_of_ports
|
1999-09-17 04:06:25 +02:00
|
|
|
: port_opt
|
1999-08-03 06:14:49 +02:00
|
|
|
{ svector<Module::port_t*>*tmp
|
|
|
|
|
= new svector<Module::port_t*>(1);
|
1999-06-12 22:35:27 +02:00
|
|
|
(*tmp)[0] = $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-09-17 04:06:25 +02:00
|
|
|
| list_of_ports ',' port_opt
|
1999-08-03 06:14:49 +02:00
|
|
|
{ svector<Module::port_t*>*tmp
|
|
|
|
|
= new svector<Module::port_t*>(*$1, $3);
|
1999-06-12 22:35:27 +02:00
|
|
|
delete $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
list_of_ports_opt
|
|
|
|
|
: '(' list_of_ports ')' { $$ = $2; }
|
|
|
|
|
| { $$ = 0; }
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
list_of_variables
|
|
|
|
|
: IDENTIFIER
|
2000-10-31 18:00:04 +01:00
|
|
|
{ list<char*>*tmp = new list<char*>;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($1);
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| list_of_variables ',' IDENTIFIER
|
2000-10-31 18:00:04 +01:00
|
|
|
{ list<char*>*tmp = $1;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($3);
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
1999-05-07 06:26:49 +02:00
|
|
|
/* An lavalue is the expression that can go on the left side of a
|
|
|
|
|
continuous assign statement. This checks (where it can) that the
|
|
|
|
|
expression meets the constraints of continuous assignments. */
|
|
|
|
|
lavalue
|
1999-06-16 05:13:29 +02:00
|
|
|
: identifier
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-05-10 02:16:57 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-05-07 06:26:49 +02:00
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-06-16 05:13:29 +02:00
|
|
|
| identifier '[' expression ']'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-05-16 07:08:42 +02:00
|
|
|
PExpr*sel = $3;
|
|
|
|
|
if (! pform_expression_is_constant(sel)) {
|
2000-12-16 18:16:08 +01:00
|
|
|
yyerror(@2, "error: Bit select in lvalue must "
|
1999-05-16 07:08:42 +02:00
|
|
|
"contain a constant expression.");
|
|
|
|
|
delete sel;
|
|
|
|
|
} else {
|
|
|
|
|
tmp->msb_ = sel;
|
|
|
|
|
}
|
1999-05-10 02:16:57 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-05-07 06:26:49 +02:00
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-06-16 05:13:29 +02:00
|
|
|
| identifier range
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-06-13 01:16:37 +02:00
|
|
|
assert($2->count() == 2);
|
|
|
|
|
tmp->msb_ = (*$2)[0];
|
|
|
|
|
tmp->lsb_ = (*$2)[1];
|
1999-05-10 02:16:57 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-05-07 06:26:49 +02:00
|
|
|
delete $1;
|
|
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| '{' expression_list '}'
|
1999-07-10 04:19:26 +02:00
|
|
|
{ PEConcat*tmp = new PEConcat(*$2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-05-07 06:26:49 +02:00
|
|
|
delete $2;
|
1999-07-10 04:19:26 +02:00
|
|
|
$$ = tmp;
|
1999-05-07 06:26:49 +02:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
/* An lpvalue is the expression that can go on the left side of a
|
|
|
|
|
procedural assignment. This rule handles only procedural assignments. */
|
|
|
|
|
lpvalue
|
1999-05-10 02:16:57 +02:00
|
|
|
: identifier
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-05-10 02:16:57 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-05-06 06:09:28 +02:00
|
|
|
| identifier '[' expression ']'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-05-10 02:16:57 +02:00
|
|
|
tmp->msb_ = $3;
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $1;
|
|
|
|
|
|
|
|
|
|
$$ = tmp;
|
1999-05-06 06:09:28 +02:00
|
|
|
}
|
1999-05-16 07:08:42 +02:00
|
|
|
| identifier '[' expression ':' expression ']'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
1999-06-10 06:03:52 +02:00
|
|
|
tmp->msb_ = $3;
|
|
|
|
|
tmp->lsb_ = $5;
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-05-16 07:08:42 +02:00
|
|
|
delete $1;
|
1999-06-10 06:03:52 +02:00
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
1999-05-07 06:26:49 +02:00
|
|
|
| '{' expression_list '}'
|
1999-07-10 04:19:26 +02:00
|
|
|
{ PEConcat*tmp = new PEConcat(*$2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-05-07 06:26:49 +02:00
|
|
|
delete $2;
|
1999-07-10 04:19:26 +02:00
|
|
|
$$ = tmp;
|
1999-05-07 06:26:49 +02:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
1999-08-27 17:08:37 +02:00
|
|
|
assign
|
|
|
|
|
: lavalue '=' expression
|
|
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(2);
|
|
|
|
|
(*tmp)[0] = $1;
|
|
|
|
|
(*tmp)[1] = $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
assign_list
|
|
|
|
|
: assign_list ',' assign
|
|
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*>(*$1, *$3);
|
|
|
|
|
delete $1;
|
|
|
|
|
delete $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| assign
|
|
|
|
|
{ $$ = $1; }
|
|
|
|
|
;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
module
|
|
|
|
|
: K_module IDENTIFIER list_of_ports_opt ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_startmodule($2, $3);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
module_item_list
|
|
|
|
|
K_endmodule
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_endmodule($2);
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $2;
|
|
|
|
|
}
|
1999-06-16 05:13:29 +02:00
|
|
|
| K_module IDENTIFIER list_of_ports_opt ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_startmodule($2, $3);
|
1999-06-16 05:13:29 +02:00
|
|
|
}
|
|
|
|
|
K_endmodule
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_endmodule($2);
|
1999-06-16 05:13:29 +02:00
|
|
|
delete $2;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
module_item
|
|
|
|
|
: net_type range_opt list_of_variables ';'
|
2000-10-31 18:00:04 +01:00
|
|
|
{ pform_makewire(@1, $2, $3, $1);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-06-02 04:56:29 +02:00
|
|
|
| net_type range_opt net_decl_assigns ';'
|
2000-10-31 18:00:04 +01:00
|
|
|
{ pform_makewire(@1, $2, $3, $1);
|
1999-06-02 04:56:29 +02:00
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
| net_type drive_strength { decl_strength = $2;} net_decl_assigns ';'
|
2000-10-31 18:00:04 +01:00
|
|
|
{ pform_makewire(@1, 0, $4, $1);
|
2000-05-08 07:30:19 +02:00
|
|
|
/* The strengths are handled in the
|
|
|
|
|
net_decl_assigns using the decl_strength that I
|
|
|
|
|
set in the rule. Right here, just restore the
|
|
|
|
|
defaults for other rules. */
|
|
|
|
|
decl_strength.str0 = PGate::STRONG;
|
|
|
|
|
decl_strength.str1 = PGate::STRONG;
|
|
|
|
|
}
|
1999-12-31 04:24:30 +01:00
|
|
|
| K_trireg charge_strength_opt range_opt delay3_opt list_of_variables ';'
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@1, "sorry: trireg nets not supported.");
|
1999-06-15 04:50:02 +02:00
|
|
|
delete $3;
|
|
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
| port_type range_opt list_of_variables ';'
|
2000-10-31 18:00:04 +01:00
|
|
|
{ pform_set_port_type($3, $2, $1);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
2000-09-13 18:32:26 +02:00
|
|
|
| port_type range_opt error ';'
|
|
|
|
|
{ yyerror(@3, "error: Invalid variable list"
|
|
|
|
|
" in port declaration.");
|
|
|
|
|
if ($2) delete $2;
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
1999-09-10 07:02:09 +02:00
|
|
|
| block_item_decl
|
1999-06-16 05:13:29 +02:00
|
|
|
| K_defparam defparam_assign_list ';'
|
|
|
|
|
| K_event list_of_variables ';'
|
2000-04-01 21:31:57 +02:00
|
|
|
{ pform_make_events($2, @1.text, @1.first_line);
|
1999-06-16 05:13:29 +02:00
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
|
|
|
|
|
/* Most gate types have an optional drive strength and optional
|
|
|
|
|
three-value delay. These rules handle the different cases. */
|
|
|
|
|
|
|
|
|
|
| gatetype gate_instance_list ';'
|
|
|
|
|
{ pform_makegates($1, decl_strength, 0, $2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| gatetype delay3 gate_instance_list ';'
|
|
|
|
|
{ pform_makegates($1, decl_strength, $2, $3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| gatetype drive_strength gate_instance_list ';'
|
|
|
|
|
{ pform_makegates($1, $2, 0, $3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| gatetype drive_strength delay3 gate_instance_list ';'
|
|
|
|
|
{ pform_makegates($1, $2, $3, $4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Pullup and pulldown devices cannot have delays, and their
|
|
|
|
|
strengths are limited. */
|
|
|
|
|
|
|
|
|
|
| K_pullup gate_instance_list ';'
|
|
|
|
|
{ pform_makegates(PGBuiltin::PULLUP, decl_strength, 0, $2);
|
|
|
|
|
}
|
|
|
|
|
| K_pulldown gate_instance_list ';'
|
|
|
|
|
{ pform_makegates(PGBuiltin::PULLDOWN, decl_strength, 0, $2);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
|
|
|
|
|
/* This rule handles instantiations of modules and user defined
|
|
|
|
|
primitives. These devices to not have delay lists or strengths,
|
|
|
|
|
but then can have parameter lists. */
|
|
|
|
|
|
2000-01-02 00:47:58 +01:00
|
|
|
| IDENTIFIER parameter_value_opt gate_instance_list ';'
|
1999-08-23 18:48:39 +02:00
|
|
|
{ pform_make_modgates($1, $2, $3);
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $1;
|
|
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
|
|
|
|
|
/* Continuous assignment can have an optional drive strength, then
|
|
|
|
|
an optional delay3 that applies to all the assignments in the
|
|
|
|
|
assign_list. */
|
|
|
|
|
|
1999-12-31 04:24:30 +01:00
|
|
|
| K_assign drive_strength_opt delay3_opt assign_list ';'
|
2000-05-06 17:41:56 +02:00
|
|
|
{ pform_make_pgassign_list($4, $3, $2, @1.text, @1.first_line); }
|
1998-11-04 00:28:49 +01:00
|
|
|
| K_always statement
|
1999-01-25 06:45:56 +01:00
|
|
|
{ PProcess*tmp = pform_make_behavior(PProcess::PR_ALWAYS, $2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
| K_initial statement
|
1999-01-25 06:45:56 +01:00
|
|
|
{ PProcess*tmp = pform_make_behavior(PProcess::PR_INITIAL, $2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
|
|
|
|
|
/* The task declaration rule matches the task declaration
|
|
|
|
|
header, then pushes the function scope. This causes the
|
|
|
|
|
definitions in the task_body to take on the scope of the task
|
|
|
|
|
instead of the module. */
|
|
|
|
|
|
1999-07-03 04:12:51 +02:00
|
|
|
| K_task IDENTIFIER ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_push_scope($2); }
|
2001-01-13 23:20:08 +01:00
|
|
|
task_item_list_opt statement_opt
|
1999-07-03 04:12:51 +02:00
|
|
|
K_endtask
|
2001-01-13 23:20:08 +01:00
|
|
|
{ PTask*tmp = new PTask;
|
1999-07-03 04:12:51 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
2001-01-13 23:20:08 +01:00
|
|
|
tmp->set_ports($5);
|
|
|
|
|
tmp->set_statement($6);
|
|
|
|
|
pform_set_task($2, tmp);
|
|
|
|
|
pform_pop_scope();
|
1999-07-03 04:12:51 +02:00
|
|
|
delete $2;
|
1999-05-08 22:19:20 +02:00
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
|
|
|
|
|
/* The function declaration rule matches the function declaration
|
|
|
|
|
header, then pushes the function scope. This causes the
|
|
|
|
|
definitions in the func_body to take on the scope of the function
|
|
|
|
|
instead of the module. */
|
|
|
|
|
|
1999-07-31 21:14:47 +02:00
|
|
|
| K_function range_or_type_opt IDENTIFIER ';'
|
|
|
|
|
{ pform_push_scope($3); }
|
2001-01-13 23:20:08 +01:00
|
|
|
function_item_list statement
|
1999-07-31 21:14:47 +02:00
|
|
|
K_endfunction
|
2001-01-13 23:20:08 +01:00
|
|
|
{ PFunction *tmp = new PFunction;
|
1999-07-31 21:14:47 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
2001-01-13 23:20:08 +01:00
|
|
|
tmp->set_ports($6);
|
|
|
|
|
tmp->set_statement($7);
|
|
|
|
|
pform_set_function($3, $2, tmp);
|
|
|
|
|
pform_pop_scope();
|
1999-07-31 21:14:47 +02:00
|
|
|
delete $3;
|
1999-05-20 06:31:45 +02:00
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
|
|
|
|
|
/* specify blocks are parsed but ignored. */
|
|
|
|
|
|
1999-06-12 05:42:57 +02:00
|
|
|
| K_specify specify_item_list K_endspecify
|
|
|
|
|
{
|
|
|
|
|
}
|
2000-05-08 07:30:19 +02:00
|
|
|
|
2001-01-06 07:31:58 +01:00
|
|
|
/* These rules match various errors that the user can type into
|
|
|
|
|
module items. These rules try to catch them at a point where a
|
|
|
|
|
reasonable error message can be produced. */
|
2001-01-06 03:29:35 +01:00
|
|
|
|
|
|
|
|
| error
|
|
|
|
|
{ yyerror(@1, "error: invalid module item. "
|
|
|
|
|
"Did you forget an initial or always?");
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-06 07:31:58 +01:00
|
|
|
| K_assign error '=' expression ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error in left side "
|
|
|
|
|
"of continuous assignment.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| K_assign error ';'
|
|
|
|
|
{ yyerror(@1, "error: syntax error in "
|
|
|
|
|
"continuous assignment");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-13 23:20:08 +01:00
|
|
|
| K_function error K_endfunction
|
|
|
|
|
{ yyerror(@1, "error: I give up on this "
|
|
|
|
|
"function definition.");
|
|
|
|
|
yyerrok;
|
|
|
|
|
}
|
|
|
|
|
|
2000-05-08 07:30:19 +02:00
|
|
|
/* These rules are for the Icarus VErilog specific $attribute
|
|
|
|
|
extensions. Then catch the parameters of the $attribute keyword. */
|
|
|
|
|
|
1998-11-23 01:20:22 +01:00
|
|
|
| KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_set_attrib($3, $5, $7);
|
1998-11-23 01:20:22 +01:00
|
|
|
delete $3;
|
|
|
|
|
delete $5;
|
|
|
|
|
delete $7;
|
|
|
|
|
}
|
|
|
|
|
| KK_attribute '(' error ')' ';'
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@1, "error: Misformed $attribute parameter list."); }
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
2000-05-08 07:30:19 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
module_item_list
|
|
|
|
|
: module_item_list module_item
|
|
|
|
|
| module_item
|
|
|
|
|
;
|
|
|
|
|
|
2000-10-31 18:00:04 +01:00
|
|
|
|
1999-06-02 04:56:29 +02:00
|
|
|
/* A net declaration assignment allows the programmer to combine the
|
|
|
|
|
net declaration and the continuous assignment into a single
|
2000-10-31 18:00:04 +01:00
|
|
|
statement.
|
|
|
|
|
|
|
|
|
|
Note that the continuous assignment statement is generated as a
|
|
|
|
|
side effect, and all I pass up is the name of the l-value. */
|
|
|
|
|
|
1999-06-02 04:56:29 +02:00
|
|
|
net_decl_assign
|
|
|
|
|
: IDENTIFIER '=' expression
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*id = new PEIdent($1);
|
2000-05-08 07:30:19 +02:00
|
|
|
PGAssign*tmp = pform_make_pgassign(id, $3, 0, decl_strength);
|
1999-06-02 04:56:29 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = $1;
|
|
|
|
|
}
|
1999-12-31 04:24:30 +01:00
|
|
|
| delay1 IDENTIFIER '=' expression
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PEIdent*id = new PEIdent($2);
|
2000-05-08 07:30:19 +02:00
|
|
|
PGAssign*tmp = pform_make_pgassign(id, $4, $1,
|
|
|
|
|
decl_strength);
|
1999-06-12 05:42:57 +02:00
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
|
|
|
|
$$ = $2;
|
|
|
|
|
}
|
1999-06-02 04:56:29 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
net_decl_assigns
|
|
|
|
|
: net_decl_assigns ',' net_decl_assign
|
2000-10-31 18:00:04 +01:00
|
|
|
{ list<char*>*tmp = $1;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($3);
|
1999-06-02 04:56:29 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| net_decl_assign
|
2000-10-31 18:00:04 +01:00
|
|
|
{ list<char*>*tmp = new list<char*>;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($1);
|
1999-06-02 04:56:29 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
net_type
|
|
|
|
|
: K_wire { $$ = NetNet::WIRE; }
|
|
|
|
|
| K_tri { $$ = NetNet::TRI; }
|
|
|
|
|
| K_tri1 { $$ = NetNet::TRI1; }
|
|
|
|
|
| K_supply0 { $$ = NetNet::SUPPLY0; }
|
|
|
|
|
| K_wand { $$ = NetNet::WAND; }
|
|
|
|
|
| K_triand { $$ = NetNet::TRIAND; }
|
|
|
|
|
| K_tri0 { $$ = NetNet::TRI0; }
|
|
|
|
|
| K_supply1 { $$ = NetNet::SUPPLY1; }
|
|
|
|
|
| K_wor { $$ = NetNet::WOR; }
|
|
|
|
|
| K_trior { $$ = NetNet::TRIOR; }
|
|
|
|
|
;
|
|
|
|
|
|
1999-02-21 18:01:57 +01:00
|
|
|
parameter_assign
|
1999-05-16 07:08:42 +02:00
|
|
|
: IDENTIFIER '=' expression
|
|
|
|
|
{ PExpr*tmp = $3;
|
|
|
|
|
if (!pform_expression_is_constant(tmp)) {
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@3, "error: parameter value "
|
2000-06-30 17:50:20 +02:00
|
|
|
"must be a constant expression.");
|
1999-05-16 07:08:42 +02:00
|
|
|
delete tmp;
|
|
|
|
|
tmp = 0;
|
2000-06-30 17:50:20 +02:00
|
|
|
} else {
|
|
|
|
|
pform_set_parameter($1, tmp);
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
1999-02-21 18:01:57 +01:00
|
|
|
delete $1;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
parameter_assign_list
|
|
|
|
|
: parameter_assign
|
1999-05-16 07:08:42 +02:00
|
|
|
| range parameter_assign
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yywarn(@1, "Ranges in parameter definition "
|
1999-05-16 07:08:42 +02:00
|
|
|
"are not supported.");
|
|
|
|
|
delete $1;
|
|
|
|
|
}
|
1999-02-21 18:01:57 +01:00
|
|
|
| parameter_assign_list ',' parameter_assign
|
|
|
|
|
;
|
|
|
|
|
|
2000-01-02 00:47:58 +01:00
|
|
|
|
2000-03-12 18:09:40 +01:00
|
|
|
/* Localparam assignments and asignment lists are broken into
|
|
|
|
|
separate BNF so that I can call slightly different paramter
|
|
|
|
|
handling code. They parse the same as parameters, they just
|
|
|
|
|
behave differently when someone tries to override them. */
|
|
|
|
|
|
|
|
|
|
localparam_assign
|
|
|
|
|
: IDENTIFIER '=' expression
|
|
|
|
|
{ PExpr*tmp = $3;
|
|
|
|
|
if (!pform_expression_is_constant(tmp)) {
|
|
|
|
|
yyerror(@3, "error: parameter value "
|
|
|
|
|
"must be constant.");
|
|
|
|
|
delete tmp;
|
|
|
|
|
tmp = 0;
|
|
|
|
|
}
|
|
|
|
|
pform_set_localparam($1, tmp);
|
|
|
|
|
delete $1;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
localparam_assign_list
|
|
|
|
|
: localparam_assign
|
|
|
|
|
| range localparam_assign
|
|
|
|
|
{ yywarn(@1, "Ranges in localparam definition "
|
|
|
|
|
"are not supported.");
|
|
|
|
|
delete $1;
|
|
|
|
|
}
|
|
|
|
|
| localparam_assign_list ',' localparam_assign
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
2000-01-02 00:47:58 +01:00
|
|
|
/* The parameters of a module instance can be overridden by writing
|
|
|
|
|
a list of expressions in a syntax much line a delay list. (The
|
|
|
|
|
difference being the list can have any length.) The pform that
|
|
|
|
|
attaches the expression list to the module checks that the
|
2000-01-09 06:50:48 +01:00
|
|
|
expressions are constant.
|
|
|
|
|
|
|
|
|
|
Although the BNF in IEEE1364-1995 implies that parameter value
|
|
|
|
|
lists must be in parentheses, in practice most compilers will
|
|
|
|
|
accept simple expressions outside of parentheses if there is only
|
|
|
|
|
one value, so I'll accept simple numbers here.
|
|
|
|
|
|
|
|
|
|
The parameter value by name syntax is OVI enhancement BTF-B06 as
|
|
|
|
|
approved by WG1364 on 6/28/1998. */
|
2000-01-02 00:47:58 +01:00
|
|
|
|
|
|
|
|
parameter_value_opt
|
|
|
|
|
: '#' '(' expression_list ')'
|
2000-01-09 06:50:48 +01:00
|
|
|
{ struct parmvalue_t*tmp = new struct parmvalue_t;
|
|
|
|
|
tmp->by_order = $3;
|
|
|
|
|
tmp->by_name = 0;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| '#' '(' parameter_value_byname_list ')'
|
|
|
|
|
{ struct parmvalue_t*tmp = new struct parmvalue_t;
|
|
|
|
|
tmp->by_order = 0;
|
|
|
|
|
tmp->by_name = $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| '#' NUMBER
|
|
|
|
|
{ assert($2);
|
|
|
|
|
PENumber*tmp = new PENumber($2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
|
|
|
|
|
struct parmvalue_t*lst = new struct parmvalue_t;
|
|
|
|
|
lst->by_order = new svector<PExpr*>(1);
|
|
|
|
|
(*lst->by_order)[0] = tmp;
|
|
|
|
|
lst->by_name = 0;
|
|
|
|
|
$$ = lst;
|
|
|
|
|
}
|
2000-01-02 02:59:52 +01:00
|
|
|
| '#' error
|
|
|
|
|
{ yyerror(@1, "error: syntax error in parameter value "
|
|
|
|
|
"assignment list.");
|
|
|
|
|
$$ = 0;
|
|
|
|
|
}
|
2000-01-02 00:47:58 +01:00
|
|
|
|
|
|
|
|
|
{ $$ = 0; }
|
|
|
|
|
;
|
|
|
|
|
|
2000-01-09 06:50:48 +01:00
|
|
|
parameter_value_byname
|
|
|
|
|
: PORTNAME '(' expression ')'
|
|
|
|
|
{ portname_t*tmp = new portname_t;
|
|
|
|
|
tmp->name = $1;
|
|
|
|
|
tmp->parm = $3;
|
|
|
|
|
free($1);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| PORTNAME '(' ')'
|
|
|
|
|
{ portname_t*tmp = new portname_t;
|
|
|
|
|
tmp->name = $1;
|
|
|
|
|
tmp->parm = 0;
|
|
|
|
|
free($1);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
parameter_value_byname_list
|
|
|
|
|
: parameter_value_byname
|
|
|
|
|
{ svector<portname_t*>*tmp = new svector<portname_t*>(1);
|
|
|
|
|
(*tmp)[0] = $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| parameter_value_byname_list ',' parameter_value_byname
|
|
|
|
|
{ svector<portname_t*>*tmp = new svector<portname_t*>(*$1,$3);
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2000-05-16 06:05:15 +02:00
|
|
|
|
2000-01-09 06:50:48 +01:00
|
|
|
/* The port (of a module) is a fairly complex item. Each port is
|
1999-08-03 06:14:49 +02:00
|
|
|
handled as a Module::port_t object. A simple port reference has a
|
2000-05-16 06:05:15 +02:00
|
|
|
name and a PExpr object, but more complex constructs are possible
|
1999-08-03 06:14:49 +02:00
|
|
|
where the name can be attached to a list of PWire objects.
|
|
|
|
|
|
|
|
|
|
The port_reference returns a Module::port_t, and so does the
|
|
|
|
|
port_reference_list. The port_reference_list may have built up a
|
|
|
|
|
list of PWires in the port_t object, but it is still a single
|
|
|
|
|
Module::port_t object.
|
|
|
|
|
|
|
|
|
|
The port rule below takes the built up Module::port_t object and
|
|
|
|
|
tweaks its name as needed. */
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
port
|
1999-08-03 06:14:49 +02:00
|
|
|
: port_reference
|
|
|
|
|
{ $$ = $1; }
|
2000-05-16 06:05:15 +02:00
|
|
|
|
|
|
|
|
/* This syntax attaches an external name to the port reference so
|
|
|
|
|
that the caller can bind by name to non-trivial port
|
|
|
|
|
references. The port_t object gets its PWire from the
|
|
|
|
|
port_reference, but its name from the PORTNAME. */
|
|
|
|
|
|
1999-08-03 06:14:49 +02:00
|
|
|
| PORTNAME '(' port_reference ')'
|
|
|
|
|
{ Module::port_t*tmp = $3;
|
|
|
|
|
tmp->name = $1;
|
1999-08-03 06:48:51 +02:00
|
|
|
delete $1;
|
1999-08-03 06:14:49 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2000-05-16 06:05:15 +02:00
|
|
|
|
|
|
|
|
/* A port can also be a concatenation of port references. In this
|
|
|
|
|
case the port does not have a name available to the outside, only
|
|
|
|
|
positional parameter passing is possible here. */
|
|
|
|
|
|
1999-08-03 06:14:49 +02:00
|
|
|
| '{' port_reference_list '}'
|
|
|
|
|
{ Module::port_t*tmp = $2;
|
|
|
|
|
tmp->name = "";
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2000-05-16 06:05:15 +02:00
|
|
|
|
|
|
|
|
/* This attaches a name to a port reference contatenation list so
|
|
|
|
|
that parameter passing be name is possible. */
|
|
|
|
|
|
1999-08-03 06:14:49 +02:00
|
|
|
| PORTNAME '(' '{' port_reference_list '}' ')'
|
|
|
|
|
{ Module::port_t*tmp = $4;
|
|
|
|
|
tmp->name = $1;
|
1999-08-03 06:48:51 +02:00
|
|
|
delete $1;
|
1999-08-03 06:14:49 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
1999-09-17 04:06:25 +02:00
|
|
|
port_opt
|
|
|
|
|
: port { $$ = $1; }
|
|
|
|
|
| { $$ = 0; }
|
|
|
|
|
;
|
|
|
|
|
|
2000-05-16 06:05:15 +02:00
|
|
|
|
|
|
|
|
/* A port reference is an internal (to the module) name of the port,
|
|
|
|
|
possibly with a part of bit select to attach it to specific bits
|
|
|
|
|
of a signal fully declared inside the module.
|
|
|
|
|
|
|
|
|
|
The parser creates a PEIdent for every port reference, even if the
|
|
|
|
|
signal is bound to different ports. The elaboration figures out
|
|
|
|
|
the mess that this creates. The port_reference (and the
|
|
|
|
|
port_reference_list below) puts the port reference PEIdent into the
|
|
|
|
|
port_t object to pass it up to the module declaration code. */
|
|
|
|
|
|
1999-08-03 06:14:49 +02:00
|
|
|
port_reference
|
2000-05-16 06:05:15 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
: IDENTIFIER
|
2000-05-16 06:05:15 +02:00
|
|
|
{ Module::port_t*ptmp = new Module::port_t;
|
|
|
|
|
PEIdent*tmp = new PEIdent($1);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-08-03 06:14:49 +02:00
|
|
|
ptmp->name = $1;
|
2000-05-16 06:05:15 +02:00
|
|
|
ptmp->expr = svector<PEIdent*>(1);
|
|
|
|
|
ptmp->expr[0] = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $1;
|
1999-08-03 06:14:49 +02:00
|
|
|
$$ = ptmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
2000-05-16 06:05:15 +02:00
|
|
|
|
1999-05-16 07:08:42 +02:00
|
|
|
| IDENTIFIER '[' expression ':' expression ']'
|
2000-05-16 06:05:15 +02:00
|
|
|
{ PEIdent*wtmp = new PEIdent($1);
|
1999-08-03 06:14:49 +02:00
|
|
|
wtmp->set_file(@1.text);
|
|
|
|
|
wtmp->set_lineno(@1.first_line);
|
1999-05-16 07:08:42 +02:00
|
|
|
if (!pform_expression_is_constant($3)) {
|
2000-05-16 06:05:15 +02:00
|
|
|
yyerror(@3, "error: msb expression of "
|
|
|
|
|
"port part select must be constant.");
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
|
|
|
|
if (!pform_expression_is_constant($5)) {
|
2000-05-16 06:05:15 +02:00
|
|
|
yyerror(@5, "error: lsb expression of "
|
|
|
|
|
"port part select must be constant.");
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
2000-05-16 06:05:15 +02:00
|
|
|
wtmp->msb_ = $3;
|
|
|
|
|
wtmp->lsb_ = $5;
|
|
|
|
|
Module::port_t*ptmp = new Module::port_t;
|
|
|
|
|
ptmp->name = "";
|
|
|
|
|
ptmp->expr = svector<PEIdent*>(1);
|
|
|
|
|
ptmp->expr[0] = wtmp;
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = ptmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
| IDENTIFIER '[' expression ']'
|
|
|
|
|
{ PEIdent*tmp = new PEIdent($1);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
if (!pform_expression_is_constant($3)) {
|
|
|
|
|
yyerror(@3, "error: port bit select "
|
|
|
|
|
"must be constant.");
|
|
|
|
|
}
|
|
|
|
|
tmp->msb_ = $3;
|
|
|
|
|
Module::port_t*ptmp = new Module::port_t;
|
|
|
|
|
ptmp->name = "";
|
|
|
|
|
ptmp->expr = svector<PEIdent*>(1);
|
|
|
|
|
ptmp->expr[0] = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $1;
|
1999-08-03 06:14:49 +02:00
|
|
|
$$ = ptmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
2000-05-16 06:05:15 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
| IDENTIFIER '[' error ']'
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@1, "error: invalid port bit select");
|
2000-05-16 06:05:15 +02:00
|
|
|
Module::port_t*ptmp = new Module::port_t;
|
|
|
|
|
PEIdent*wtmp = new PEIdent($1);
|
1999-08-03 06:14:49 +02:00
|
|
|
wtmp->set_file(@1.text);
|
|
|
|
|
wtmp->set_lineno(@1.first_line);
|
|
|
|
|
ptmp->name = $1;
|
2000-05-16 06:05:15 +02:00
|
|
|
ptmp->expr = svector<PEIdent*>(1);
|
|
|
|
|
ptmp->expr[0] = wtmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
delete $1;
|
1999-08-03 06:14:49 +02:00
|
|
|
$$ = ptmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2000-05-16 06:05:15 +02:00
|
|
|
|
1999-08-03 06:14:49 +02:00
|
|
|
port_reference_list
|
|
|
|
|
: port_reference
|
|
|
|
|
{ $$ = $1; }
|
|
|
|
|
| port_reference_list ',' port_reference
|
|
|
|
|
{ Module::port_t*tmp = $1;
|
2000-05-16 06:05:15 +02:00
|
|
|
tmp->expr = svector<PEIdent*>(tmp->expr, $3->expr);
|
1999-08-03 06:14:49 +02:00
|
|
|
delete $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
/* The port_name rule is used with a module is being *instantiated*,
|
|
|
|
|
and not when it is being declared. See the port rule if you are
|
|
|
|
|
looking for the ports of a module declaration. */
|
|
|
|
|
|
1999-05-08 22:19:20 +02:00
|
|
|
port_name
|
1999-05-16 07:08:42 +02:00
|
|
|
: PORTNAME '(' expression ')'
|
1999-05-29 04:36:17 +02:00
|
|
|
{ portname_t*tmp = new portname_t;
|
1999-08-03 06:48:51 +02:00
|
|
|
tmp->name = $1;
|
1999-05-29 04:36:17 +02:00
|
|
|
tmp->parm = $3;
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
1999-05-08 22:19:20 +02:00
|
|
|
}
|
1999-05-16 07:08:42 +02:00
|
|
|
| PORTNAME '(' error ')'
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@3, "error: invalid port connection expression.");
|
1999-05-29 04:36:17 +02:00
|
|
|
portname_t*tmp = new portname_t;
|
1999-08-03 06:48:51 +02:00
|
|
|
tmp->name = $1;
|
1999-05-29 04:36:17 +02:00
|
|
|
tmp->parm = 0;
|
1999-05-16 07:08:42 +02:00
|
|
|
delete $1;
|
1999-05-29 04:36:17 +02:00
|
|
|
$$ = tmp;
|
1999-05-16 07:08:42 +02:00
|
|
|
}
|
1999-05-08 22:19:20 +02:00
|
|
|
| PORTNAME '(' ')'
|
1999-05-29 04:36:17 +02:00
|
|
|
{ portname_t*tmp = new portname_t;
|
1999-08-03 06:48:51 +02:00
|
|
|
tmp->name = $1;
|
1999-05-29 04:36:17 +02:00
|
|
|
tmp->parm = 0;
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
1999-05-08 22:19:20 +02:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
port_name_list
|
|
|
|
|
: port_name_list ',' port_name
|
1999-05-29 04:36:17 +02:00
|
|
|
{ svector<portname_t*>*tmp;
|
|
|
|
|
tmp = new svector<portname_t*>(*$1, $3);
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-05-08 22:19:20 +02:00
|
|
|
| port_name
|
1999-05-29 04:36:17 +02:00
|
|
|
{ svector<portname_t*>*tmp = new svector<portname_t*>(1);
|
|
|
|
|
(*tmp)[0] = $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-05-08 22:19:20 +02:00
|
|
|
;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
port_type
|
|
|
|
|
: K_input { $$ = NetNet::PINPUT; }
|
|
|
|
|
| K_output { $$ = NetNet::POUTPUT; }
|
|
|
|
|
| K_inout { $$ = NetNet::PINOUT; }
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
range
|
1999-05-16 07:08:42 +02:00
|
|
|
: '[' expression ':' expression ']'
|
1999-05-10 02:16:57 +02:00
|
|
|
{ svector<PExpr*>*tmp = new svector<PExpr*> (2);
|
1999-06-16 05:13:29 +02:00
|
|
|
if (!pform_expression_is_constant($2))
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@2, "error: msb of range must be constant.");
|
1999-06-16 05:13:29 +02:00
|
|
|
|
|
|
|
|
(*tmp)[0] = $2;
|
|
|
|
|
|
|
|
|
|
if (!pform_expression_is_constant($4))
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@4, "error: msb of range must be constant.");
|
1999-06-16 05:13:29 +02:00
|
|
|
|
|
|
|
|
(*tmp)[1] = $4;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
range_opt
|
|
|
|
|
: range
|
|
|
|
|
| { $$ = 0; }
|
|
|
|
|
;
|
|
|
|
|
|
2000-12-05 23:32:05 +01:00
|
|
|
/* This is used to express the retur type of a function. */
|
1999-05-20 06:31:45 +02:00
|
|
|
range_or_type_opt
|
1999-08-26 00:22:41 +02:00
|
|
|
: range { $$ = $1; }
|
|
|
|
|
| K_integer { $$ = 0; }
|
|
|
|
|
| K_real { $$ = 0; }
|
|
|
|
|
| K_realtime { $$ = 0; }
|
|
|
|
|
| K_time { $$ = 0; }
|
|
|
|
|
| { $$ = 0; }
|
1999-05-20 06:31:45 +02:00
|
|
|
;
|
2000-12-05 23:32:05 +01:00
|
|
|
|
1999-04-19 03:59:36 +02:00
|
|
|
/* The register_variable rule is matched only when I am parsing
|
|
|
|
|
variables in a "reg" definition. I therefore know that I am
|
|
|
|
|
creating registers and I do not need to let the containing rule
|
|
|
|
|
handle it. The register variable list simply packs them together
|
|
|
|
|
so that bit ranges can be assigned. */
|
1998-11-04 00:28:49 +01:00
|
|
|
register_variable
|
|
|
|
|
: IDENTIFIER
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_makewire(@1, $1, NetNet::REG);
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = $1;
|
|
|
|
|
}
|
1999-06-12 22:35:27 +02:00
|
|
|
| IDENTIFIER '=' expression
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_makewire(@1, $1, NetNet::REG);
|
1999-12-30 20:06:14 +01:00
|
|
|
if (! pform_expression_is_constant($3))
|
|
|
|
|
yyerror(@3, "error: register declaration assignment"
|
|
|
|
|
" value must be a constant expression.");
|
|
|
|
|
pform_make_reginit(@1, $1, $3);
|
1999-06-12 22:35:27 +02:00
|
|
|
$$ = $1;
|
|
|
|
|
}
|
1999-05-16 07:08:42 +02:00
|
|
|
| IDENTIFIER '[' expression ':' expression ']'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_makewire(@1, $1, NetNet::REG);
|
1999-05-16 07:08:42 +02:00
|
|
|
if (! pform_expression_is_constant($3))
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@3, "error: msb of register range must be constant.");
|
1999-05-16 07:08:42 +02:00
|
|
|
if (! pform_expression_is_constant($5))
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@3, "error: lsb of register range must be constant.");
|
1999-07-10 03:03:18 +02:00
|
|
|
pform_set_reg_idx($1, $3, $5);
|
1999-04-19 03:59:36 +02:00
|
|
|
$$ = $1;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
register_variable_list
|
|
|
|
|
: register_variable
|
2000-10-31 18:00:04 +01:00
|
|
|
{ list<char*>*tmp = new list<char*>;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($1);
|
1999-04-19 03:59:36 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| register_variable_list ',' register_variable
|
2000-10-31 18:00:04 +01:00
|
|
|
{ list<char*>*tmp = $1;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($3);
|
1999-04-19 03:59:36 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
;
|
|
|
|
|
|
1999-06-12 05:42:57 +02:00
|
|
|
specify_item
|
|
|
|
|
: K_specparam specparam_list ';'
|
2001-04-21 02:55:46 +02:00
|
|
|
| specify_simple_path '=' '(' specify_delay_value_list ')' ';'
|
2000-09-23 05:04:10 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
| specify_simple_path '=' delay_value_simple ';'
|
2000-06-27 18:00:40 +02:00
|
|
|
{
|
1999-06-19 05:21:21 +02:00
|
|
|
}
|
1999-06-12 05:42:57 +02:00
|
|
|
;
|
|
|
|
|
|
2001-04-21 02:55:46 +02:00
|
|
|
specify_delay_value_list
|
|
|
|
|
: delay_value { }
|
|
|
|
|
| specify_delay_value_list ',' delay_value { }
|
|
|
|
|
;
|
|
|
|
|
|
1999-06-12 05:42:57 +02:00
|
|
|
specify_item_list
|
|
|
|
|
: specify_item
|
|
|
|
|
| specify_item_list specify_item
|
|
|
|
|
;
|
|
|
|
|
|
1999-06-19 05:21:21 +02:00
|
|
|
specify_simple_path
|
2001-04-21 02:55:46 +02:00
|
|
|
: '(' specify_path_identifiers spec_polarity K_EG IDENTIFIER ')'
|
|
|
|
|
| '(' specify_path_identifiers spec_polarity K_SG IDENTIFIER ')'
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
specify_path_identifiers
|
|
|
|
|
: IDENTIFIER { }
|
|
|
|
|
| specify_path_identifiers ',' IDENTIFIER { }
|
1999-06-19 05:21:21 +02:00
|
|
|
;
|
|
|
|
|
|
1999-06-12 05:42:57 +02:00
|
|
|
specparam
|
|
|
|
|
: IDENTIFIER '=' expression
|
1999-09-29 23:16:32 +02:00
|
|
|
{ delete $1;
|
1999-06-12 05:42:57 +02:00
|
|
|
delete $3;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
specparam_list
|
|
|
|
|
: specparam
|
|
|
|
|
| specparam_list ',' specparam
|
|
|
|
|
;
|
|
|
|
|
|
1999-06-19 05:21:21 +02:00
|
|
|
spec_polarity: '+' | '-' | ;
|
|
|
|
|
|
2000-05-12 01:37:26 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
statement
|
2000-05-12 01:37:26 +02:00
|
|
|
|
|
|
|
|
/* assign and deassign statements are procedural code to do
|
|
|
|
|
structural assignments, and to turn that structural assignment
|
|
|
|
|
off. This stronger then any other assign, but weaker then the
|
|
|
|
|
force assignments. */
|
|
|
|
|
|
1999-05-30 05:12:56 +02:00
|
|
|
: K_assign lavalue '=' expression ';'
|
2000-05-12 01:37:26 +02:00
|
|
|
{ PCAssign*tmp = new PCAssign($2, $4);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
2000-12-06 07:31:09 +01:00
|
|
|
| K_deassign lavalue ';'
|
2000-05-12 01:37:26 +02:00
|
|
|
{ PDeassign*tmp = new PDeassign($2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Force and release statements are similar to assignments,
|
|
|
|
|
syntactically, but they will be elaborated differently. */
|
|
|
|
|
|
|
|
|
|
| K_force lavalue '=' expression ';'
|
|
|
|
|
{ PForce*tmp = new PForce($2, $4);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-30 05:12:56 +02:00
|
|
|
}
|
2000-05-12 01:37:26 +02:00
|
|
|
| K_release lavalue ';'
|
|
|
|
|
{ PRelease*tmp = new PRelease($2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* begin-end blocks come in a variety of forms, including named and
|
|
|
|
|
anonymous. The named blocks can also carry their own reg
|
|
|
|
|
variables, which are placed in the scope created by the block
|
|
|
|
|
name. These are handled by pushing the scope name then matching
|
|
|
|
|
the declarations. The scope is popped at the end of the block. */
|
|
|
|
|
|
1999-05-30 05:12:56 +02:00
|
|
|
| K_begin statement_list K_end
|
1999-06-24 06:24:18 +02:00
|
|
|
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ, *$2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_begin ':' IDENTIFIER
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_push_scope($3); }
|
1999-06-24 06:24:18 +02:00
|
|
|
block_item_decls_opt
|
|
|
|
|
statement_list K_end
|
|
|
|
|
{ pform_pop_scope();
|
1999-07-10 03:03:18 +02:00
|
|
|
PBlock*tmp = new PBlock($3, PBlock::BL_SEQ, *$6);
|
1999-06-24 06:24:18 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $3;
|
|
|
|
|
delete $6;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_begin K_end
|
|
|
|
|
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_begin ':' IDENTIFIER K_end
|
|
|
|
|
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-06-12 05:42:57 +02:00
|
|
|
}
|
|
|
|
|
| K_begin error K_end
|
|
|
|
|
{ yyerrok; }
|
2000-05-12 01:37:26 +02:00
|
|
|
|
|
|
|
|
/* fork-join blocks are very similar to begin-end blocks. In fact,
|
|
|
|
|
from the parser's perspective there is no real difference. All we
|
|
|
|
|
need to do is remember that this is a parallel block so that the
|
|
|
|
|
code generator can do the right thing. */
|
|
|
|
|
|
1999-09-22 06:30:04 +02:00
|
|
|
| K_fork ':' IDENTIFIER
|
|
|
|
|
{ pform_push_scope($3); }
|
|
|
|
|
block_item_decls_opt
|
|
|
|
|
statement_list K_join
|
|
|
|
|
{ pform_pop_scope();
|
|
|
|
|
PBlock*tmp = new PBlock($3, PBlock::BL_PAR, *$6);
|
1999-06-19 23:06:16 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-09-22 06:30:04 +02:00
|
|
|
delete $3;
|
|
|
|
|
delete $6;
|
1999-06-19 23:06:16 +02:00
|
|
|
$$ = tmp;
|
1999-06-12 22:35:27 +02:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
| K_fork K_join
|
1999-06-24 06:24:18 +02:00
|
|
|
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-09-22 06:30:04 +02:00
|
|
|
| K_fork ':' IDENTIFIER K_join
|
|
|
|
|
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
2000-07-26 07:08:07 +02:00
|
|
|
delete $3;
|
1999-09-22 06:30:04 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2000-05-12 01:37:26 +02:00
|
|
|
|
2000-07-26 07:08:07 +02:00
|
|
|
| K_disable identifier ';'
|
|
|
|
|
{ PDisable*tmp = new PDisable($2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
2000-05-12 01:37:26 +02:00
|
|
|
delete $2;
|
2000-07-26 07:08:07 +02:00
|
|
|
$$ = tmp;
|
2000-05-12 01:37:26 +02:00
|
|
|
}
|
|
|
|
|
| K_TRIGGER IDENTIFIER ';'
|
|
|
|
|
{ PTrigger*tmp = new PTrigger($2);
|
|
|
|
|
tmp->set_file(@2.text);
|
|
|
|
|
tmp->set_lineno(@2.first_line);
|
2000-07-26 07:08:07 +02:00
|
|
|
delete $2;
|
2000-05-12 01:37:26 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_forever statement
|
|
|
|
|
{ PForever*tmp = new PForever($2);
|
2000-04-22 06:20:19 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-09-22 06:30:04 +02:00
|
|
|
}
|
2000-05-12 01:37:26 +02:00
|
|
|
| K_fork statement_list K_join
|
|
|
|
|
{ PBlock*tmp = new PBlock(PBlock::BL_PAR, *$2);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-09-22 06:30:04 +02:00
|
|
|
| K_repeat '(' expression ')' statement
|
|
|
|
|
{ PRepeat*tmp = new PRepeat($3, $5);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-02-03 05:20:11 +01:00
|
|
|
| K_case '(' expression ')' case_items K_endcase
|
1999-09-29 20:36:02 +02:00
|
|
|
{ PCase*tmp = new PCase(NetCase::EQ, $3, $5);
|
1999-02-03 05:20:11 +01:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-06-10 06:03:52 +02:00
|
|
|
| K_casex '(' expression ')' case_items K_endcase
|
1999-09-29 20:36:02 +02:00
|
|
|
{ PCase*tmp = new PCase(NetCase::EQX, $3, $5);
|
1999-06-10 06:03:52 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_casez '(' expression ')' case_items K_endcase
|
1999-09-29 20:36:02 +02:00
|
|
|
{ PCase*tmp = new PCase(NetCase::EQZ, $3, $5);
|
1999-06-10 06:03:52 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-06-12 05:42:57 +02:00
|
|
|
| K_case '(' expression ')' error K_endcase
|
|
|
|
|
{ yyerrok; }
|
|
|
|
|
| K_casex '(' expression ')' error K_endcase
|
|
|
|
|
{ yyerrok; }
|
|
|
|
|
| K_casez '(' expression ')' error K_endcase
|
|
|
|
|
{ yyerrok; }
|
1999-09-30 00:56:31 +02:00
|
|
|
| K_if '(' expression ')' statement_opt %prec less_than_K_else
|
1998-11-07 18:05:05 +01:00
|
|
|
{ PCondit*tmp = new PCondit($3, $5, 0);
|
1999-06-10 06:03:52 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1998-11-07 18:05:05 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_if '(' expression ')' statement_opt K_else statement_opt
|
|
|
|
|
{ PCondit*tmp = new PCondit($3, $5, $7);
|
1999-06-10 06:03:52 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1998-11-07 18:05:05 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-09-30 00:56:31 +02:00
|
|
|
| K_if '(' error ')' statement_opt %prec less_than_K_else
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
1998-11-07 18:05:05 +01:00
|
|
|
$$ = $5;
|
|
|
|
|
}
|
|
|
|
|
| K_if '(' error ')' statement_opt K_else statement_opt
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
1998-11-07 18:05:05 +01:00
|
|
|
$$ = $5;
|
|
|
|
|
}
|
1999-05-07 06:26:49 +02:00
|
|
|
| K_for '(' lpvalue '=' expression ';' expression ';'
|
|
|
|
|
lpvalue '=' expression ')' statement
|
1999-06-10 06:03:52 +02:00
|
|
|
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11, $13);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-06-10 07:33:12 +02:00
|
|
|
$$ = tmp;
|
1998-11-09 19:55:33 +01:00
|
|
|
}
|
1999-05-07 06:26:49 +02:00
|
|
|
| K_for '(' lpvalue '=' expression ';' expression ';'
|
1998-11-09 19:55:33 +01:00
|
|
|
error ')' statement
|
|
|
|
|
{ $$ = 0;
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@9, "error: Error in for loop step assigment.");
|
1998-11-09 19:55:33 +01:00
|
|
|
}
|
1999-05-07 06:26:49 +02:00
|
|
|
| K_for '(' lpvalue '=' expression ';' error ';'
|
|
|
|
|
lpvalue '=' expression ')' statement
|
1998-11-09 19:55:33 +01:00
|
|
|
{ $$ = 0;
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@7, "error: Error in for loop condition expression.");
|
1998-11-09 19:55:33 +01:00
|
|
|
}
|
|
|
|
|
| K_for '(' error ')' statement
|
|
|
|
|
{ $$ = 0;
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@3, "error: Incomprehensible for loop.");
|
1998-11-09 19:55:33 +01:00
|
|
|
}
|
|
|
|
|
| K_while '(' expression ')' statement
|
1998-11-11 04:13:04 +01:00
|
|
|
{ PWhile*tmp = new PWhile($3, $5);
|
|
|
|
|
$$ = tmp;
|
1998-11-09 19:55:33 +01:00
|
|
|
}
|
|
|
|
|
| K_while '(' error ')' statement
|
|
|
|
|
{ $$ = 0;
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@3, "error: Error in while loop condition.");
|
1998-11-09 19:55:33 +01:00
|
|
|
}
|
1999-12-31 04:24:30 +01:00
|
|
|
| delay1 statement_opt
|
1999-08-01 18:34:50 +02:00
|
|
|
{ PExpr*del = (*$1)[0];
|
1999-12-31 04:24:30 +01:00
|
|
|
assert($1->count() == 1);
|
1999-08-01 18:34:50 +02:00
|
|
|
PDelayStatement*tmp = new PDelayStatement(del, $2);
|
1999-05-05 05:27:14 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| event_control statement_opt
|
|
|
|
|
{ PEventStatement*tmp = $1;
|
1999-04-29 04:16:26 +02:00
|
|
|
if (tmp == 0) {
|
1999-09-29 23:16:32 +02:00
|
|
|
yyerror(@1, "error: Invalid event control.");
|
1999-04-29 04:16:26 +02:00
|
|
|
$$ = 0;
|
|
|
|
|
} else {
|
|
|
|
|
tmp->set_statement($2);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-05-07 06:26:49 +02:00
|
|
|
| lpvalue '=' expression ';'
|
1999-05-10 02:16:57 +02:00
|
|
|
{ PAssign*tmp = new PAssign($1,$3);
|
1999-01-25 06:45:56 +01:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-05-07 06:26:49 +02:00
|
|
|
| lpvalue K_LE expression ';'
|
1999-06-06 22:45:38 +02:00
|
|
|
{ PAssignNB*tmp = new PAssignNB($1,$3);
|
1999-05-10 02:16:57 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-12-31 04:24:30 +01:00
|
|
|
| lpvalue '=' delay1 expression ';'
|
|
|
|
|
{ assert($3->count() == 1);
|
|
|
|
|
PExpr*del = (*$3)[0];
|
1999-08-01 18:34:50 +02:00
|
|
|
PAssign*tmp = new PAssign($1,del,$4);
|
1999-05-10 02:16:57 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
1999-05-08 22:19:20 +02:00
|
|
|
}
|
1999-12-31 04:24:30 +01:00
|
|
|
| lpvalue K_LE delay1 expression ';'
|
|
|
|
|
{ assert($3->count() == 1);
|
|
|
|
|
PExpr*del = (*$3)[0];
|
1999-09-02 03:59:27 +02:00
|
|
|
PAssignNB*tmp = new PAssignNB($1,del,$4);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-09-22 04:00:48 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| lpvalue '=' event_control expression ';'
|
|
|
|
|
{ PAssign*tmp = new PAssign($1,$3,$4);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-12-31 04:24:30 +01:00
|
|
|
| lpvalue '=' K_repeat '(' expression ')' event_control expression ';'
|
|
|
|
|
{ PAssign*tmp = new PAssign($1,$7,$8);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
yyerror(@3, "sorry: repeat event control not supported.");
|
|
|
|
|
delete $5;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-09-22 04:00:48 +02:00
|
|
|
| lpvalue K_LE event_control expression ';'
|
|
|
|
|
{ yyerror(@1, "sorry: Event controls not supported here.");
|
|
|
|
|
PAssignNB*tmp = new PAssignNB($1,$4);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-12-31 04:24:30 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| lpvalue K_LE K_repeat '(' expression ')' event_control expression ';'
|
|
|
|
|
{ yyerror(@1, "sorry: Event controls not supported here.");
|
|
|
|
|
delete $5;
|
|
|
|
|
PAssignNB*tmp = new PAssignNB($1,$8);
|
|
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
1999-09-02 03:59:27 +02:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-09 19:55:33 +01:00
|
|
|
| K_wait '(' expression ')' statement_opt
|
|
|
|
|
{ PEventStatement*tmp;
|
2000-04-12 06:23:57 +02:00
|
|
|
PEEvent*etmp = new PEEvent(PEEvent::POSITIVE, $3);
|
1999-04-29 04:16:26 +02:00
|
|
|
tmp = new PEventStatement(etmp);
|
1998-11-09 19:55:33 +01:00
|
|
|
tmp->set_statement($5);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
| SYSTEM_IDENTIFIER '(' expression_list ')' ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PCallTask*tmp = new PCallTask($1, *$3);
|
1999-07-03 04:12:51 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $1;
|
|
|
|
|
delete $3;
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
| SYSTEM_IDENTIFIER ';'
|
1999-07-03 04:12:51 +02:00
|
|
|
{ svector<PExpr*>pt (0);
|
1999-07-10 03:03:18 +02:00
|
|
|
PCallTask*tmp = new PCallTask($1, pt);
|
1999-07-03 04:12:51 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-06-16 05:13:29 +02:00
|
|
|
| identifier '(' expression_list ')' ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PCallTask*tmp = new PCallTask($1, *$3);
|
1999-07-03 04:12:51 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $1;
|
|
|
|
|
delete $3;
|
|
|
|
|
$$ = tmp;
|
1999-06-16 05:13:29 +02:00
|
|
|
}
|
|
|
|
|
| identifier ';'
|
1999-07-03 04:12:51 +02:00
|
|
|
{ svector<PExpr*>pt (0);
|
1999-07-10 03:03:18 +02:00
|
|
|
PCallTask*tmp = new PCallTask($1, pt);
|
1999-07-03 04:12:51 +02:00
|
|
|
tmp->set_file(@1.text);
|
|
|
|
|
tmp->set_lineno(@1.first_line);
|
|
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
1999-05-08 22:19:20 +02:00
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
| error ';'
|
1999-09-29 23:16:32 +02:00
|
|
|
{ yyerror(@1, "error: malformed statement");
|
1999-06-12 05:42:57 +02:00
|
|
|
yyerrok;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = new PNoop;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
statement_list
|
|
|
|
|
: statement_list statement
|
1999-06-24 06:24:18 +02:00
|
|
|
{ svector<Statement*>*tmp = new svector<Statement*>(*$1, $2);
|
|
|
|
|
delete $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| statement
|
1999-06-24 06:24:18 +02:00
|
|
|
{ svector<Statement*>*tmp = new svector<Statement*>(1);
|
|
|
|
|
(*tmp)[0] = $1;
|
1998-11-04 00:28:49 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
statement_opt
|
|
|
|
|
: statement
|
|
|
|
|
| ';' { $$ = 0; }
|
|
|
|
|
;
|
1998-11-23 01:20:22 +01:00
|
|
|
|
1999-05-30 05:12:56 +02:00
|
|
|
|
|
|
|
|
task_item
|
1999-06-24 06:24:18 +02:00
|
|
|
: block_item_decl
|
1999-09-10 07:02:09 +02:00
|
|
|
{ $$ = new svector<PWire*>(0); }
|
1999-06-24 06:24:18 +02:00
|
|
|
| K_input range_opt list_of_variables ';'
|
1999-07-24 04:11:19 +02:00
|
|
|
{ svector<PWire*>*tmp
|
1999-09-10 07:02:09 +02:00
|
|
|
= pform_make_task_ports(NetNet::PINPUT, $2,
|
|
|
|
|
$3, @1.text, @1.first_line);
|
1999-07-24 04:11:19 +02:00
|
|
|
$$ = tmp;
|
1999-07-03 04:12:51 +02:00
|
|
|
}
|
1999-05-30 05:12:56 +02:00
|
|
|
| K_output range_opt list_of_variables ';'
|
1999-07-24 04:11:19 +02:00
|
|
|
{ svector<PWire*>*tmp
|
1999-09-10 07:02:09 +02:00
|
|
|
= pform_make_task_ports(NetNet::POUTPUT, $2, $3,
|
|
|
|
|
@1.text, @1.first_line);
|
1999-07-24 04:11:19 +02:00
|
|
|
$$ = tmp;
|
1999-07-03 04:12:51 +02:00
|
|
|
}
|
1999-05-30 05:12:56 +02:00
|
|
|
| K_inout range_opt list_of_variables ';'
|
1999-07-24 04:11:19 +02:00
|
|
|
{ svector<PWire*>*tmp
|
1999-09-10 07:02:09 +02:00
|
|
|
= pform_make_task_ports(NetNet::PINOUT, $2, $3,
|
|
|
|
|
@1.text, @1.first_line);
|
1999-07-24 04:11:19 +02:00
|
|
|
$$ = tmp;
|
1999-07-03 04:12:51 +02:00
|
|
|
}
|
1999-05-30 05:12:56 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
task_item_list
|
|
|
|
|
: task_item_list task_item
|
1999-07-24 04:11:19 +02:00
|
|
|
{ svector<PWire*>*tmp = new svector<PWire*>(*$1, *$2);
|
|
|
|
|
delete $1;
|
|
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1999-05-30 05:12:56 +02:00
|
|
|
| task_item
|
1999-07-24 04:11:19 +02:00
|
|
|
{ $$ = $1; }
|
1999-05-30 05:12:56 +02:00
|
|
|
;
|
|
|
|
|
|
1999-06-12 05:42:57 +02:00
|
|
|
task_item_list_opt
|
|
|
|
|
: task_item_list
|
1999-07-24 04:11:19 +02:00
|
|
|
{ $$ = $1; }
|
1999-06-12 05:42:57 +02:00
|
|
|
|
|
1999-07-24 04:11:19 +02:00
|
|
|
{ $$ = 0; }
|
1999-06-12 05:42:57 +02:00
|
|
|
;
|
|
|
|
|
|
1998-11-23 01:20:22 +01:00
|
|
|
udp_body
|
|
|
|
|
: K_table { lex_start_table(); }
|
1998-11-25 03:35:53 +01:00
|
|
|
udp_entry_list
|
|
|
|
|
K_endtable { lex_end_table(); $$ = $3; }
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_entry_list
|
|
|
|
|
: udp_comb_entry_list
|
|
|
|
|
| udp_sequ_entry_list
|
1998-11-23 01:20:22 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_comb_entry
|
|
|
|
|
: udp_input_list ':' udp_output_sym ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ char*tmp = new char[strlen($1)+3];
|
|
|
|
|
strcpy(tmp, $1);
|
|
|
|
|
char*tp = tmp+strlen(tmp);
|
|
|
|
|
*tp++ = ':';
|
|
|
|
|
*tp++ = $3;
|
|
|
|
|
*tp++ = 0;
|
|
|
|
|
delete[]$1;
|
1998-11-25 03:35:53 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-23 01:20:22 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_comb_entry_list
|
|
|
|
|
: udp_comb_entry
|
1998-11-25 03:35:53 +01:00
|
|
|
{ list<string>*tmp = new list<string>;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($1);
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-23 01:20:22 +01:00
|
|
|
| udp_comb_entry_list udp_comb_entry
|
1998-11-25 03:35:53 +01:00
|
|
|
{ list<string>*tmp = $1;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($2);
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_sequ_entry_list
|
|
|
|
|
: udp_sequ_entry
|
|
|
|
|
{ list<string>*tmp = new list<string>;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($1);
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| udp_sequ_entry_list udp_sequ_entry
|
|
|
|
|
{ list<string>*tmp = $1;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($2);
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_sequ_entry
|
|
|
|
|
: udp_input_list ':' udp_input_sym ':' udp_output_sym ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ char*tmp = new char[strlen($1)+5];
|
|
|
|
|
strcpy(tmp, $1);
|
|
|
|
|
char*tp = tmp+strlen(tmp);
|
|
|
|
|
*tp++ = ':';
|
|
|
|
|
*tp++ = $3;
|
|
|
|
|
*tp++ = ':';
|
|
|
|
|
*tp++ = $5;
|
|
|
|
|
*tp++ = 0;
|
1998-11-25 03:35:53 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_initial
|
|
|
|
|
: K_initial IDENTIFIER '=' NUMBER ';'
|
|
|
|
|
{ PExpr*etmp = new PENumber($4);
|
1999-07-10 03:03:18 +02:00
|
|
|
PEIdent*itmp = new PEIdent($2);
|
1999-05-10 02:16:57 +02:00
|
|
|
PAssign*atmp = new PAssign(itmp, etmp);
|
1999-01-25 06:45:56 +01:00
|
|
|
atmp->set_file(@2.text);
|
|
|
|
|
atmp->set_lineno(@2.first_line);
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $2;
|
|
|
|
|
$$ = atmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_init_opt
|
|
|
|
|
: udp_initial { $$ = $1; }
|
|
|
|
|
| { $$ = 0; }
|
1998-11-23 01:20:22 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_input_list
|
|
|
|
|
: udp_input_sym
|
1999-07-10 03:03:18 +02:00
|
|
|
{ char*tmp = new char[2];
|
|
|
|
|
tmp[0] = $1;
|
|
|
|
|
tmp[1] = 0;
|
1998-11-25 03:35:53 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-23 01:20:22 +01:00
|
|
|
| udp_input_list udp_input_sym
|
1999-07-10 03:03:18 +02:00
|
|
|
{ char*tmp = new char[strlen($1)+2];
|
|
|
|
|
strcpy(tmp, $1);
|
|
|
|
|
char*tp = tmp+strlen(tmp);
|
|
|
|
|
*tp++ = $2;
|
|
|
|
|
*tp++ = 0;
|
|
|
|
|
delete[]$1;
|
1998-11-25 03:35:53 +01:00
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_input_sym
|
|
|
|
|
: '0' { $$ = '0'; }
|
|
|
|
|
| '1' { $$ = '1'; }
|
|
|
|
|
| 'x' { $$ = 'x'; }
|
|
|
|
|
| '?' { $$ = '?'; }
|
|
|
|
|
| 'b' { $$ = 'b'; }
|
|
|
|
|
| '*' { $$ = '*'; }
|
2000-03-05 19:26:51 +01:00
|
|
|
| '%' { $$ = '%'; }
|
1998-11-25 03:35:53 +01:00
|
|
|
| 'f' { $$ = 'f'; }
|
2000-03-05 19:26:51 +01:00
|
|
|
| 'F' { $$ = 'F'; }
|
1998-12-14 03:01:34 +01:00
|
|
|
| 'r' { $$ = 'r'; }
|
2000-03-05 19:26:51 +01:00
|
|
|
| 'R' { $$ = 'R'; }
|
1998-12-18 06:16:25 +01:00
|
|
|
| 'n' { $$ = 'n'; }
|
2000-03-05 19:26:51 +01:00
|
|
|
| 'N' { $$ = 'N'; }
|
1998-12-18 06:16:25 +01:00
|
|
|
| 'p' { $$ = 'p'; }
|
2000-03-05 19:26:51 +01:00
|
|
|
| 'P' { $$ = 'P'; }
|
1998-12-18 06:16:25 +01:00
|
|
|
| '_' { $$ = '_'; }
|
2000-03-05 19:26:51 +01:00
|
|
|
| '+' { $$ = '+'; }
|
1998-11-23 01:20:22 +01:00
|
|
|
;
|
|
|
|
|
|
1998-11-25 03:35:53 +01:00
|
|
|
udp_output_sym
|
|
|
|
|
: '0' { $$ = '0'; }
|
|
|
|
|
| '1' { $$ = '1'; }
|
|
|
|
|
| 'x' { $$ = 'x'; }
|
|
|
|
|
| '-' { $$ = '-'; }
|
|
|
|
|
;
|
1998-11-23 01:20:22 +01:00
|
|
|
|
|
|
|
|
udp_port_decl
|
|
|
|
|
: K_input list_of_variables ';'
|
1998-11-25 03:35:53 +01:00
|
|
|
{ $$ = pform_make_udp_input_ports($2); }
|
1998-11-23 01:20:22 +01:00
|
|
|
| K_output IDENTIFIER ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PWire*pp = new PWire($2, NetNet::IMPLICIT, NetNet::POUTPUT);
|
1999-06-12 22:35:27 +02:00
|
|
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
|
|
|
|
(*tmp)[0] = pp;
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| K_reg IDENTIFIER ';'
|
1999-07-10 03:03:18 +02:00
|
|
|
{ PWire*pp = new PWire($2, NetNet::REG, NetNet::PIMPLICIT);
|
1999-06-12 22:35:27 +02:00
|
|
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
|
|
|
|
(*tmp)[0] = pp;
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-23 01:20:22 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_port_decls
|
|
|
|
|
: udp_port_decl
|
1998-11-25 03:35:53 +01:00
|
|
|
{ $$ = $1; }
|
1998-11-23 01:20:22 +01:00
|
|
|
| udp_port_decls udp_port_decl
|
1999-06-12 22:35:27 +02:00
|
|
|
{ svector<PWire*>*tmp = new svector<PWire*>(*$1, *$2);
|
|
|
|
|
delete $1;
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $2;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-23 01:20:22 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_port_list
|
1998-11-25 03:35:53 +01:00
|
|
|
: IDENTIFIER
|
|
|
|
|
{ list<string>*tmp = new list<string>;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($1);
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $1;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
|
|
|
|
| udp_port_list ',' IDENTIFIER
|
|
|
|
|
{ list<string>*tmp = $1;
|
1999-07-10 03:03:18 +02:00
|
|
|
tmp->push_back($3);
|
1998-11-25 03:35:53 +01:00
|
|
|
delete $3;
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
1998-11-23 01:20:22 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
udp_primitive
|
|
|
|
|
: K_primitive IDENTIFIER '(' udp_port_list ')' ';'
|
|
|
|
|
udp_port_decls
|
1998-11-25 03:35:53 +01:00
|
|
|
udp_init_opt
|
1998-11-23 01:20:22 +01:00
|
|
|
udp_body
|
|
|
|
|
K_endprimitive
|
1999-07-10 03:03:18 +02:00
|
|
|
{ pform_make_udp($2, $4, $7, $9, $8);
|
|
|
|
|
delete[]$2;
|
|
|
|
|
}
|
1998-11-23 01:20:22 +01:00
|
|
|
;
|