2007-11-19 02:36:03 +01:00
|
|
|
|
|
|
|
|
%{
|
|
|
|
|
/*
|
2023-06-26 05:11:38 +02:00
|
|
|
* Copyright (c) 1998-2023 Stephen Williams (steve@icarus.com)
|
2007-11-19 02:36:03 +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
|
2012-08-29 03:41:23 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2007-11-19 02:36:03 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
extern int sdflex(void);
|
|
|
|
|
static void yyerror(const char*msg);
|
|
|
|
|
# include "vpi_user.h"
|
|
|
|
|
# include "sdf_parse_priv.h"
|
2007-11-21 07:20:22 +01:00
|
|
|
# include "sdf_priv.h"
|
2007-11-19 02:36:03 +01:00
|
|
|
# include <stdio.h>
|
2007-11-28 05:53:48 +01:00
|
|
|
# include <string.h>
|
2007-11-30 19:20:30 +01:00
|
|
|
# include <stdlib.h>
|
2010-10-24 00:52:56 +02:00
|
|
|
# include "ivl_alloc.h"
|
2007-11-21 07:20:22 +01:00
|
|
|
|
|
|
|
|
/* This is the hierarchy separator to use. */
|
2007-11-28 05:53:48 +01:00
|
|
|
char sdf_use_hchar = '.';
|
2007-11-21 07:20:22 +01:00
|
|
|
|
2007-11-19 02:36:03 +01:00
|
|
|
%}
|
|
|
|
|
|
|
|
|
|
%union {
|
|
|
|
|
unsigned long int_val;
|
|
|
|
|
double real_val;
|
|
|
|
|
char* string_val;
|
2007-11-23 02:34:51 +01:00
|
|
|
|
2009-02-10 04:21:50 +01:00
|
|
|
struct sdf_delay_s delay;
|
2007-12-14 05:42:06 +01:00
|
|
|
struct port_with_edge_s port_with_edge;
|
2007-11-23 02:34:51 +01:00
|
|
|
struct sdf_delval_list_s delval_list;
|
2023-07-13 12:32:49 +02:00
|
|
|
struct interconnect_port_s interconnect_port;
|
2007-11-19 02:36:03 +01:00
|
|
|
};
|
|
|
|
|
|
2014-04-27 05:55:21 +02:00
|
|
|
%token K_ABSOLUTE K_CELL K_CELLTYPE K_COND K_CONDELSE K_DATE K_DELAYFILE
|
|
|
|
|
%token K_DELAY K_DESIGN K_DIVIDER K_HOLD K_INCREMENT K_INSTANCE
|
2019-08-24 01:23:29 +02:00
|
|
|
%token K_INTERCONNECT K_IOPATH K_NEGEDGE K_PATHPULSE K_PATHPULSEPERCENT
|
|
|
|
|
%token K_PERIOD K_POSEDGE K_PROCESS K_PROGRAM
|
2014-04-27 05:55:21 +02:00
|
|
|
%token K_RECREM K_RECOVERY K_REMOVAL K_SDFVERSION K_SETUP K_SETUPHOLD
|
|
|
|
|
%token K_TEMPERATURE K_TIMESCALE K_TIMINGCHECK K_VENDOR K_VERSION
|
|
|
|
|
%token K_VOLTAGE K_WIDTH
|
2009-02-10 05:13:05 +01:00
|
|
|
%token K_01 K_10 K_0Z K_Z1 K_1Z K_Z0
|
2010-11-14 01:54:55 +01:00
|
|
|
%token K_EQ K_NE K_CEQ K_CNE K_LOGICAL_ONE K_LOGICAL_ZERO
|
2014-04-27 05:55:21 +02:00
|
|
|
%token K_LAND K_LOR
|
2007-11-19 02:36:03 +01:00
|
|
|
|
2007-11-28 05:53:48 +01:00
|
|
|
%token HCHAR
|
2007-11-19 02:36:03 +01:00
|
|
|
%token <string_val> QSTRING IDENTIFIER
|
|
|
|
|
%token <real_val> REAL_NUMBER
|
|
|
|
|
%token <int_val> INTEGER
|
|
|
|
|
|
2007-11-21 07:20:22 +01:00
|
|
|
%type <string_val> celltype
|
|
|
|
|
%type <string_val> cell_instance
|
|
|
|
|
%type <string_val> hierarchical_identifier
|
2023-07-13 12:32:49 +02:00
|
|
|
%type <string_val> port port_instance
|
|
|
|
|
|
|
|
|
|
%type <interconnect_port> port_interconnect
|
2007-11-21 07:20:22 +01:00
|
|
|
|
2010-03-18 22:19:52 +01:00
|
|
|
%type <real_val> signed_real_number
|
2019-08-24 01:23:29 +02:00
|
|
|
%type <delay> delval rvalue_opt rvalue rtriple signed_real_number_opt
|
2007-11-23 02:34:51 +01:00
|
|
|
|
2007-12-14 05:42:06 +01:00
|
|
|
%type <int_val> edge_identifier
|
|
|
|
|
%type <port_with_edge> port_edge port_spec
|
|
|
|
|
|
2007-11-23 02:34:51 +01:00
|
|
|
%type <delval_list> delval_list
|
|
|
|
|
|
2014-04-27 05:55:21 +02:00
|
|
|
%left K_LOR
|
|
|
|
|
%left K_LAND
|
|
|
|
|
%left K_EQ K_NE K_CEQ K_CNE
|
|
|
|
|
|
2007-11-19 02:36:03 +01:00
|
|
|
%%
|
|
|
|
|
|
|
|
|
|
source_file
|
|
|
|
|
: '(' K_DELAYFILE sdf_header_list cell_list ')'
|
2007-11-27 02:59:53 +01:00
|
|
|
| '(' K_DELAYFILE error ')'
|
2023-06-15 09:18:41 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Invalid DELAYFILE format\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line);
|
2007-11-27 02:59:53 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
sdf_header_list
|
|
|
|
|
: sdf_header_list sdf_header_item
|
|
|
|
|
| sdf_header_item
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
sdf_header_item
|
|
|
|
|
: sdfversion
|
|
|
|
|
| design_name
|
|
|
|
|
| date
|
|
|
|
|
| vendor
|
|
|
|
|
| program_name
|
|
|
|
|
| program_version
|
|
|
|
|
| hierarchy_divider
|
|
|
|
|
| voltage
|
|
|
|
|
| process
|
|
|
|
|
| temperature
|
|
|
|
|
| time_scale
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
sdfversion
|
|
|
|
|
: '(' K_SDFVERSION QSTRING ')'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Version: %s\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3);
|
|
|
|
|
}
|
|
|
|
|
free($3);
|
2023-03-08 17:04:16 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
design_name
|
|
|
|
|
: '(' K_DESIGN QSTRING ')'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Design: %s\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3);
|
|
|
|
|
}
|
|
|
|
|
free($3);
|
2007-11-23 03:22:46 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
date
|
|
|
|
|
: '(' K_DATE QSTRING ')'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Date: %s\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3);
|
|
|
|
|
}
|
|
|
|
|
free($3);
|
2007-11-23 03:22:46 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
2007-11-23 03:22:46 +01:00
|
|
|
vendor
|
|
|
|
|
: '(' K_VENDOR QSTRING ')'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Vendor: %s\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3);
|
|
|
|
|
}
|
|
|
|
|
free($3);
|
2007-11-23 03:22:46 +01:00
|
|
|
}
|
2012-08-01 23:01:44 +02:00
|
|
|
;
|
2007-11-19 02:36:03 +01:00
|
|
|
|
2007-11-23 03:22:46 +01:00
|
|
|
program_name
|
|
|
|
|
: '(' K_PROGRAM QSTRING ')'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Program: %s\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3);
|
|
|
|
|
}
|
|
|
|
|
free($3);
|
2007-11-23 03:22:46 +01:00
|
|
|
}
|
|
|
|
|
;
|
2007-11-19 02:36:03 +01:00
|
|
|
|
2007-11-23 03:22:46 +01:00
|
|
|
program_version
|
|
|
|
|
: '(' K_VERSION QSTRING ')'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Program Version: %s\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3);
|
|
|
|
|
}
|
2007-11-23 03:22:46 +01:00
|
|
|
free($3);
|
|
|
|
|
}
|
|
|
|
|
;
|
2007-11-19 02:36:03 +01:00
|
|
|
|
|
|
|
|
hierarchy_divider
|
2023-03-08 20:51:44 +01:00
|
|
|
: '(' K_DIVIDER '.' ')'
|
|
|
|
|
{ sdf_use_hchar = '.';
|
2023-09-04 14:27:46 +02:00
|
|
|
if (sdf_flag_inform) vpi_printf("SDF INFO: %s:%d: Divider: \"%c\"\n",
|
|
|
|
|
sdf_parse_path, @1.first_line, sdf_use_hchar);
|
2023-03-08 20:51:44 +01:00
|
|
|
}
|
|
|
|
|
| '(' K_DIVIDER '/' ')'
|
|
|
|
|
{ sdf_use_hchar = '/';
|
2023-09-04 14:27:46 +02:00
|
|
|
if (sdf_flag_inform) vpi_printf("SDF INFO: %s:%d: Divider: \"%c\"\n",
|
|
|
|
|
sdf_parse_path, @1.first_line, sdf_use_hchar);
|
2023-03-08 20:51:44 +01:00
|
|
|
}
|
|
|
|
|
| '(' K_DIVIDER HCHAR ')'
|
|
|
|
|
{ /* sdf_use_hchar no-change */
|
2023-09-04 14:27:46 +02:00
|
|
|
if (sdf_flag_inform) vpi_printf("SDF INFO: %s:%d: Divider: \"%c\"\n",
|
|
|
|
|
sdf_parse_path, @1.first_line, sdf_use_hchar);
|
2023-03-08 20:51:44 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
voltage
|
|
|
|
|
: '(' K_VOLTAGE rtriple ')'
|
2023-03-08 17:04:16 +01:00
|
|
|
{ /* The value must be defined. */
|
2023-09-04 14:27:46 +02:00
|
|
|
if (! $3.defined) {
|
|
|
|
|
vpi_printf("SDF ERROR: %s:%d: Chosen value not defined.\n",
|
|
|
|
|
sdf_parse_path, @1.first_line);
|
|
|
|
|
} else if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Voltage: %f\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3.value);
|
|
|
|
|
}
|
2023-03-08 17:04:16 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' K_VOLTAGE signed_real_number ')'
|
2023-04-19 18:35:32 +02:00
|
|
|
{ if (sdf_flag_inform) vpi_printf("SDF INFO: %s:%d: Voltage: %f\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line, $3);
|
2023-03-08 17:04:16 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
2007-11-23 03:22:46 +01:00
|
|
|
process
|
|
|
|
|
: '(' K_PROCESS QSTRING ')'
|
2023-04-19 18:35:32 +02:00
|
|
|
{ if (sdf_flag_inform) vpi_printf("SDF INFO: %s:%d: Process: %s\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line, $3);
|
2007-11-23 03:22:46 +01:00
|
|
|
free($3);
|
|
|
|
|
}
|
|
|
|
|
;
|
2007-11-19 02:36:03 +01:00
|
|
|
|
|
|
|
|
temperature
|
|
|
|
|
: '(' K_TEMPERATURE rtriple ')'
|
2023-03-08 17:04:16 +01:00
|
|
|
{ /* The value must be defined. */
|
2023-09-04 14:27:46 +02:00
|
|
|
if (! $3.defined) {
|
|
|
|
|
vpi_printf("SDF ERROR: %s:%d: Chosen value not defined.\n",
|
|
|
|
|
sdf_parse_path, @1.first_line);
|
|
|
|
|
} else if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Temperature: %f\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3.value);
|
|
|
|
|
}
|
2023-03-08 17:04:16 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' K_TEMPERATURE signed_real_number ')'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: Temperature: %f\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3);
|
|
|
|
|
}
|
2023-03-08 17:04:16 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
time_scale
|
|
|
|
|
: '(' K_TIMESCALE REAL_NUMBER IDENTIFIER ')'
|
2023-04-19 18:35:32 +02:00
|
|
|
{ if (sdf_flag_inform) vpi_printf("SDF INFO: %s:%d: Timescale: %f%s\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line, $3, $4);
|
2007-11-23 03:22:46 +01:00
|
|
|
free($4);
|
|
|
|
|
}
|
2010-03-05 06:17:36 +01:00
|
|
|
| '(' K_TIMESCALE INTEGER IDENTIFIER ')'
|
2023-04-19 18:35:32 +02:00
|
|
|
{ if (sdf_flag_inform) vpi_printf("SDF INFO: %s:%d: Timescale: %lu%s\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line, $3, $4);
|
2010-03-05 06:17:36 +01:00
|
|
|
free($4);
|
|
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
cell_list
|
|
|
|
|
: cell_list cell
|
|
|
|
|
| cell
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
cell
|
2007-11-21 07:20:22 +01:00
|
|
|
: '(' K_CELL celltype cell_instance
|
2023-06-26 05:11:38 +02:00
|
|
|
{ sdf_select_instance($3, $4, @4.first_line); /* find the instance in the design */}
|
2010-03-30 19:51:18 +02:00
|
|
|
timing_spec_list_opt
|
2007-11-21 07:20:22 +01:00
|
|
|
')'
|
|
|
|
|
{ free($3);
|
2007-11-28 05:53:48 +01:00
|
|
|
if ($4) free($4);
|
|
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' K_CELL error ')'
|
2023-06-15 09:18:41 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Syntax error in CELL\n",
|
2007-11-21 07:20:22 +01:00
|
|
|
sdf_parse_path, @2.first_line); }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
celltype
|
|
|
|
|
: '(' K_CELLTYPE QSTRING ')'
|
2007-11-21 07:20:22 +01:00
|
|
|
{ $$ = $3; }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
cell_instance
|
|
|
|
|
: '(' K_INSTANCE hierarchical_identifier ')'
|
2007-11-21 07:20:22 +01:00
|
|
|
{ $$ = $3; }
|
2007-11-28 05:53:48 +01:00
|
|
|
| '(' K_INSTANCE ')'
|
|
|
|
|
{ $$ = strdup(""); }
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' K_INSTANCE '*' ')'
|
2007-11-21 07:20:22 +01:00
|
|
|
{ $$ = 0; }
|
2007-11-28 06:42:20 +01:00
|
|
|
| '(' K_INSTANCE error ')'
|
2023-06-15 09:18:41 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Invalid/malformed INSTANCE argument\n",
|
2007-11-28 06:42:20 +01:00
|
|
|
sdf_parse_path, @2.first_line);
|
|
|
|
|
$$ = strdup(""); }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
2010-03-30 19:51:18 +02:00
|
|
|
timing_spec_list_opt
|
|
|
|
|
: /* Empty */
|
|
|
|
|
| timing_spec_list_opt timing_spec
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
timing_spec
|
|
|
|
|
: '(' K_DELAY deltype_list ')'
|
|
|
|
|
| '(' K_DELAY error ')'
|
2023-06-15 09:18:41 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Syntax error in CELL DELAY SPEC\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line); }
|
2007-11-28 05:53:48 +01:00
|
|
|
| '(' K_TIMINGCHECK tchk_def_list ')'
|
2023-06-15 09:18:41 +02:00
|
|
|
{ vpi_printf("SDF WARNING: %s:%d: TIMINGCHECK not supported.\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line); }
|
2007-11-28 05:53:48 +01:00
|
|
|
| '(' K_TIMINGCHECK error ')'
|
2023-06-15 09:18:41 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Syntax error in TIMINGCHECK SPEC\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line); }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
deltype_list
|
|
|
|
|
: deltype_list deltype
|
|
|
|
|
| deltype
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
deltype
|
2019-08-24 01:23:29 +02:00
|
|
|
: '(' K_PATHPULSE input_output_path_opt rvalue rvalue_opt ')'
|
|
|
|
|
| '(' K_PATHPULSEPERCENT input_output_path_opt rvalue rvalue_opt ')'
|
|
|
|
|
| '(' K_ABSOLUTE del_def_list ')'
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' K_INCREMENT del_def_list ')'
|
|
|
|
|
| '(' error ')'
|
2023-04-19 19:30:23 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Invalid/malformed delay type\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @1.first_line); }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
del_def_list
|
|
|
|
|
: del_def_list del_def
|
|
|
|
|
| del_def
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
del_def
|
|
|
|
|
: '(' K_IOPATH port_spec port_instance delval_list ')'
|
2023-06-26 05:11:38 +02:00
|
|
|
{ sdf_iopath_delays($3.vpi_edge, $3.string_val, $4, &$5, @2.first_line);
|
2007-12-14 05:42:06 +01:00
|
|
|
free($3.string_val);
|
2007-11-21 07:20:22 +01:00
|
|
|
free($4);
|
|
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' K_IOPATH error ')'
|
2023-04-19 19:30:23 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Invalid/malformed IOPATH\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line); }
|
2014-04-27 05:55:21 +02:00
|
|
|
| '(' K_COND conditional_port_expr
|
|
|
|
|
'(' K_IOPATH port_spec port_instance delval_list ')' ')'
|
2023-04-19 19:30:23 +02:00
|
|
|
{ if (sdf_flag_warning) vpi_printf("SDF WARNING: %s:%d: "
|
2023-09-04 14:27:46 +02:00
|
|
|
"COND not supported.\n",
|
|
|
|
|
sdf_parse_path, @2.first_line);
|
2014-04-28 02:25:47 +02:00
|
|
|
free($6.string_val);
|
|
|
|
|
free($7);
|
2014-04-27 05:55:21 +02:00
|
|
|
}
|
2014-04-27 05:58:29 +02:00
|
|
|
| '(' K_COND QSTRING conditional_port_expr
|
2014-04-27 05:55:21 +02:00
|
|
|
'(' K_IOPATH port_spec port_instance delval_list ')' ')'
|
2023-04-19 19:30:23 +02:00
|
|
|
{ if (sdf_flag_warning) vpi_printf("SDF WARNING: %s:%d: "
|
2023-09-04 14:27:46 +02:00
|
|
|
"COND not supported.\n",
|
|
|
|
|
sdf_parse_path, @2.first_line);
|
2014-04-28 02:56:48 +02:00
|
|
|
free($3);
|
2014-04-28 02:25:47 +02:00
|
|
|
free($7.string_val);
|
|
|
|
|
free($8);
|
2014-04-27 05:55:21 +02:00
|
|
|
}
|
|
|
|
|
| '(' K_COND error ')'
|
2023-04-19 19:30:23 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Invalid/malformed COND\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line); }
|
2014-04-27 05:55:21 +02:00
|
|
|
| '(' K_CONDELSE '(' K_IOPATH port_spec port_instance delval_list ')' ')'
|
2023-04-19 19:30:23 +02:00
|
|
|
{ if (sdf_flag_warning) vpi_printf("SDF WARNING: %s:%d: "
|
2023-09-04 14:27:46 +02:00
|
|
|
"CONDELSE not supported.\n",
|
|
|
|
|
sdf_parse_path, @2.first_line);
|
2014-04-28 02:25:47 +02:00
|
|
|
free($5.string_val);
|
|
|
|
|
free($6);
|
2014-04-27 05:55:21 +02:00
|
|
|
}
|
|
|
|
|
| '(' K_CONDELSE error ')'
|
2023-04-19 19:30:23 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Invalid/malformed CONDELSE\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line); }
|
2010-03-05 06:17:36 +01:00
|
|
|
/* | '(' K_INTERCONNECT port_instance port_instance delval_list ')' */
|
|
|
|
|
| '(' K_INTERCONNECT port_interconnect port_interconnect delval_list ')'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ if (sdf_flag_inform) {
|
|
|
|
|
vpi_printf("SDF INFO: %s:%d: INTERCONNECT with "
|
|
|
|
|
"port1 = %s index = %d, port2 = %s index = %d\n",
|
|
|
|
|
sdf_parse_path, @2.first_line, $3.name, $3.index, $4.name, $4.index);
|
|
|
|
|
}
|
|
|
|
|
sdf_interconnect_delays($3, $4, &$5, @2.first_line);
|
|
|
|
|
free($3.name);
|
|
|
|
|
free($4.name);
|
2007-11-28 05:53:48 +01:00
|
|
|
}
|
|
|
|
|
| '(' K_INTERCONNECT error ')'
|
2023-04-19 19:30:23 +02:00
|
|
|
{ vpi_printf("SDF ERROR: %s:%d: Invalid/malformed INTERCONNECT\n",
|
2023-09-04 14:27:46 +02:00
|
|
|
sdf_parse_path, @2.first_line);
|
2023-08-17 16:09:20 +02:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
2007-11-28 05:53:48 +01:00
|
|
|
tchk_def_list
|
|
|
|
|
: tchk_def_list tchk_def
|
|
|
|
|
| tchk_def
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
/* Timing checks are ignored. */
|
|
|
|
|
tchk_def
|
|
|
|
|
: '(' K_SETUP port_tchk port_tchk rvalue ')'
|
|
|
|
|
| '(' K_HOLD port_tchk port_tchk rvalue ')'
|
|
|
|
|
| '(' K_SETUPHOLD port_tchk port_tchk rvalue rvalue ')'
|
|
|
|
|
| '(' K_RECOVERY port_tchk port_tchk rvalue ')'
|
2010-03-18 22:19:52 +01:00
|
|
|
| '(' K_RECREM port_tchk port_tchk rvalue rvalue ')'
|
2010-11-14 02:24:51 +01:00
|
|
|
| '(' K_REMOVAL port_tchk port_tchk rvalue ')'
|
2007-11-28 05:53:48 +01:00
|
|
|
| '(' K_WIDTH port_tchk rvalue ')'
|
2019-08-24 01:23:29 +02:00
|
|
|
| '(' K_PERIOD port_tchk rvalue ')'
|
2007-11-28 05:53:48 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
port_tchk
|
2010-11-14 01:54:55 +01:00
|
|
|
: port_instance
|
2014-04-28 02:56:48 +02:00
|
|
|
{ free($1); }
|
2010-11-14 01:54:55 +01:00
|
|
|
/* This must only be an edge. For now we just accept everything. */
|
|
|
|
|
| cond_edge_start port_instance ')'
|
2014-04-28 02:56:48 +02:00
|
|
|
{ free($2); }
|
2010-11-14 01:54:55 +01:00
|
|
|
/* These must only be a cond. For now we just accept everything. */
|
|
|
|
|
| cond_edge_start timing_check_condition port_spec ')'
|
2014-04-28 02:56:48 +02:00
|
|
|
{ free($3.string_val); }
|
2010-11-14 01:54:55 +01:00
|
|
|
| cond_edge_start QSTRING timing_check_condition port_spec ')'
|
2014-04-28 02:56:48 +02:00
|
|
|
{ free($2);
|
|
|
|
|
free($4.string_val);
|
|
|
|
|
}
|
2010-11-14 01:54:55 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
cond_edge_start
|
|
|
|
|
: '(' { start_edge_id(1); } cond_edge_identifier { stop_edge_id(); }
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
cond_edge_identifier
|
|
|
|
|
: K_POSEDGE
|
|
|
|
|
| K_NEGEDGE
|
|
|
|
|
| K_01
|
|
|
|
|
| K_10
|
|
|
|
|
| K_0Z
|
|
|
|
|
| K_Z1
|
|
|
|
|
| K_1Z
|
|
|
|
|
| K_Z0
|
|
|
|
|
| K_COND
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
timing_check_condition
|
|
|
|
|
: port_interconnect
|
2023-07-13 12:32:49 +02:00
|
|
|
{ free($1.name); }
|
2010-11-14 01:54:55 +01:00
|
|
|
| '~' port_interconnect
|
2023-07-13 12:32:49 +02:00
|
|
|
{ free($2.name); }
|
2010-11-14 01:54:55 +01:00
|
|
|
| '!' port_interconnect
|
2023-07-13 12:32:49 +02:00
|
|
|
{ free($2.name); }
|
2010-11-14 01:54:55 +01:00
|
|
|
| port_interconnect equality_operator scalar_constant
|
2023-07-13 12:32:49 +02:00
|
|
|
{ free($1.name); }
|
2010-11-14 01:54:55 +01:00
|
|
|
;
|
|
|
|
|
|
2014-04-27 05:55:21 +02:00
|
|
|
/* This is not complete! */
|
|
|
|
|
conditional_port_expr
|
|
|
|
|
: port
|
2014-04-28 02:56:48 +02:00
|
|
|
{ free($1); }
|
2014-04-27 05:55:21 +02:00
|
|
|
| scalar_constant
|
|
|
|
|
| '(' conditional_port_expr ')'
|
|
|
|
|
| conditional_port_expr K_LAND conditional_port_expr
|
|
|
|
|
| conditional_port_expr K_LOR conditional_port_expr
|
|
|
|
|
| conditional_port_expr K_EQ conditional_port_expr
|
|
|
|
|
| conditional_port_expr K_NE conditional_port_expr
|
|
|
|
|
| conditional_port_expr K_CEQ conditional_port_expr
|
|
|
|
|
| conditional_port_expr K_CNE conditional_port_expr
|
|
|
|
|
;
|
|
|
|
|
|
2010-11-14 01:54:55 +01:00
|
|
|
equality_operator
|
|
|
|
|
: K_EQ
|
|
|
|
|
| K_NE
|
|
|
|
|
| K_CEQ
|
|
|
|
|
| K_CNE
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
scalar_constant
|
|
|
|
|
: K_LOGICAL_ONE
|
|
|
|
|
| K_LOGICAL_ZERO
|
2007-11-28 05:53:48 +01:00
|
|
|
;
|
|
|
|
|
|
2019-08-24 01:23:29 +02:00
|
|
|
input_output_path_opt
|
|
|
|
|
: input_output_path
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
input_output_path
|
|
|
|
|
: port_instance port_instance
|
|
|
|
|
;
|
|
|
|
|
|
2007-11-19 02:36:03 +01:00
|
|
|
port_spec
|
2007-12-14 05:42:06 +01:00
|
|
|
: port_instance { $$.vpi_edge = vpiNoEdge; $$.string_val = $1; }
|
|
|
|
|
| port_edge { $$ = $1; }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
port_instance
|
2007-11-21 07:20:22 +01:00
|
|
|
: port { $$ = $1; }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
port
|
|
|
|
|
: hierarchical_identifier
|
2007-11-21 07:20:22 +01:00
|
|
|
{ $$ = $1; }
|
|
|
|
|
/* | hierarchical_identifier '[' INTEGER ']' */
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
2010-03-05 06:17:36 +01:00
|
|
|
port_interconnect
|
|
|
|
|
: hierarchical_identifier
|
2023-09-04 14:27:46 +02:00
|
|
|
{ struct interconnect_port_s tmp = {$1, false, 0};
|
|
|
|
|
$$ = tmp;
|
2023-07-13 12:32:49 +02:00
|
|
|
}
|
2010-03-05 06:17:36 +01:00
|
|
|
| hierarchical_identifier '[' INTEGER ']'
|
2023-09-04 14:27:46 +02:00
|
|
|
{ struct interconnect_port_s tmp = {$1, true, $3};
|
|
|
|
|
$$ = tmp;
|
2023-07-13 12:32:49 +02:00
|
|
|
}
|
2010-03-05 06:17:36 +01:00
|
|
|
;
|
|
|
|
|
|
2007-12-14 05:42:06 +01:00
|
|
|
port_edge
|
2010-11-14 01:54:55 +01:00
|
|
|
: '(' {start_edge_id(0);} edge_identifier {stop_edge_id();} port_instance ')'
|
2009-02-10 05:13:05 +01:00
|
|
|
{ $$.vpi_edge = $3; $$.string_val = $5; }
|
2007-12-14 05:42:06 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
edge_identifier
|
|
|
|
|
: K_POSEDGE { $$ = vpiPosedge; }
|
|
|
|
|
| K_NEGEDGE { $$ = vpiNegedge; }
|
2009-02-10 05:13:05 +01:00
|
|
|
| K_01 { $$ = vpiEdge01; }
|
|
|
|
|
| K_10 { $$ = vpiEdge10; }
|
|
|
|
|
| K_0Z { $$ = vpiEdge0x; }
|
|
|
|
|
| K_Z1 { $$ = vpiEdgex1; }
|
|
|
|
|
| K_1Z { $$ = vpiEdge1x; }
|
|
|
|
|
| K_Z0 { $$ = vpiEdgex0; }
|
2007-12-14 05:42:06 +01:00
|
|
|
;
|
|
|
|
|
|
2007-11-19 02:36:03 +01:00
|
|
|
delval_list
|
|
|
|
|
: delval_list delval
|
2007-11-23 02:34:51 +01:00
|
|
|
{ int idx;
|
|
|
|
|
$$.count = $1.count;
|
|
|
|
|
for (idx = 0 ; idx < $$.count ; idx += 1)
|
|
|
|
|
$$.val[idx] = $1.val[idx];
|
2009-02-10 04:21:50 +01:00
|
|
|
// Is this correct?
|
2007-11-23 02:34:51 +01:00
|
|
|
if ($$.count < 12) {
|
|
|
|
|
$$.val[$$.count] = $2;
|
|
|
|
|
$$.count += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
| delval
|
2007-11-23 02:34:51 +01:00
|
|
|
{ $$.count = 1;
|
|
|
|
|
$$.val[0] = $1;
|
|
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
delval
|
|
|
|
|
: rvalue
|
2007-11-23 02:34:51 +01:00
|
|
|
{ $$ = $1; }
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' rvalue rvalue ')'
|
2007-11-23 02:34:51 +01:00
|
|
|
{ $$ = $2;
|
2023-04-19 19:30:23 +02:00
|
|
|
vpi_printf("SDF WARNING: %s:%d: Pulse rejection limits ignored\n",
|
2007-11-23 02:34:51 +01:00
|
|
|
sdf_parse_path, @3.first_line);
|
|
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' rvalue rvalue rvalue ')'
|
2007-11-23 02:34:51 +01:00
|
|
|
{ $$ = $2;
|
2023-04-19 19:30:23 +02:00
|
|
|
vpi_printf("SDF WARNING: %s:%d: Pulse rejection limits ignored\n",
|
2007-11-23 02:34:51 +01:00
|
|
|
sdf_parse_path, @3.first_line);
|
|
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
2019-08-24 01:23:29 +02:00
|
|
|
rvalue_opt
|
|
|
|
|
: /* When missing. */
|
|
|
|
|
{ $$.value = 0.0;
|
|
|
|
|
$$.defined = 0;
|
|
|
|
|
}
|
|
|
|
|
| rvalue
|
|
|
|
|
;
|
|
|
|
|
|
2007-11-19 02:36:03 +01:00
|
|
|
rvalue
|
|
|
|
|
: '(' signed_real_number ')'
|
2009-02-10 04:21:50 +01:00
|
|
|
{ $$.defined = 1;
|
|
|
|
|
$$.value = $2; }
|
2007-11-19 02:36:03 +01:00
|
|
|
| '(' rtriple ')'
|
2010-03-18 22:19:52 +01:00
|
|
|
{ $$ = $2; }
|
2009-02-10 04:21:50 +01:00
|
|
|
| '(' ')'
|
|
|
|
|
{ $$.defined = 0;
|
|
|
|
|
$$.value = 0.0; }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
hierarchical_identifier
|
|
|
|
|
: IDENTIFIER
|
2007-11-28 05:53:48 +01:00
|
|
|
{ $$ = $1; }
|
|
|
|
|
| hierarchical_identifier HCHAR IDENTIFIER
|
|
|
|
|
{ int len = strlen($1) + strlen($3) + 2;
|
|
|
|
|
char*tmp = realloc($1, len);
|
|
|
|
|
strcat(tmp, ".");
|
|
|
|
|
strcat(tmp, $3);
|
|
|
|
|
free($3);
|
|
|
|
|
$$ = tmp;
|
|
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
rtriple
|
2010-03-18 22:19:52 +01:00
|
|
|
: signed_real_number_opt ':' signed_real_number_opt ':' signed_real_number_opt
|
2010-03-18 02:48:11 +01:00
|
|
|
{ switch(sdf_min_typ_max) {
|
|
|
|
|
case _vpiDelaySelMinimum:
|
|
|
|
|
$$ = $1;
|
|
|
|
|
break;
|
|
|
|
|
case _vpiDelaySelTypical:
|
|
|
|
|
$$ = $3;
|
|
|
|
|
break;
|
|
|
|
|
case _vpiDelaySelMaximum:
|
|
|
|
|
$$ = $5;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-03-18 22:19:52 +01:00
|
|
|
/* At least one of the values must be defined. */
|
|
|
|
|
if (! ($1.defined || $3.defined || $5.defined)) {
|
2023-04-19 19:30:23 +02:00
|
|
|
vpi_printf("SDF ERROR: %s:%d: rtriple must have at least one "
|
2010-03-18 22:19:52 +01:00
|
|
|
"defined value.\n", sdf_parse_path, @1.first_line);
|
|
|
|
|
}
|
2010-03-18 02:48:11 +01:00
|
|
|
}
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
2010-03-18 22:19:52 +01:00
|
|
|
signed_real_number_opt
|
|
|
|
|
: /* When missing. */
|
|
|
|
|
{ $$.value = 0.0;
|
|
|
|
|
$$.defined = 0;
|
|
|
|
|
}
|
|
|
|
|
| signed_real_number
|
|
|
|
|
{ $$.value = $1;
|
|
|
|
|
$$.defined = 1;
|
|
|
|
|
}
|
2010-11-14 02:24:51 +01:00
|
|
|
;
|
2010-03-18 22:19:52 +01:00
|
|
|
|
2007-11-19 02:36:03 +01:00
|
|
|
signed_real_number
|
2007-11-23 02:34:51 +01:00
|
|
|
: REAL_NUMBER { $$ = $1; }
|
|
|
|
|
| '+' REAL_NUMBER { $$ = $2; }
|
|
|
|
|
| '-' REAL_NUMBER { $$ = -$2; }
|
2010-03-05 06:17:36 +01:00
|
|
|
| INTEGER { $$ = $1; }
|
|
|
|
|
| '+' INTEGER { $$ = $2; }
|
|
|
|
|
| '-' INTEGER { $$ = -$2; }
|
2007-11-19 02:36:03 +01:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
|
|
void yyerror(const char*msg)
|
|
|
|
|
{
|
2023-06-15 09:18:41 +02:00
|
|
|
vpi_printf("SDF ERROR: %s: Too many errors: %s\n", sdf_parse_path, msg);
|
2007-11-19 02:36:03 +01:00
|
|
|
}
|