Merge branch 'sdf'
This commit is contained in:
commit
ea70ae00aa
|
|
@ -39,6 +39,8 @@ CC = @CC@
|
|||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -I$(srcdir) -I.. @file64_support@ @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
|
|
@ -62,8 +64,9 @@ dep:
|
|||
|
||||
O = sys_table.o sys_convert.o sys_deposit.o sys_display.o sys_fileio.o \
|
||||
sys_finish.o sys_plusargs.o sys_random.o sys_random_mti.o \
|
||||
sys_readmem.o sys_readmem_lex.o sys_scanf.o \
|
||||
sys_time.o sys_vcd.o sys_vcdoff.o vcd_priv.o mt19937int.o priv.o stringheap.o
|
||||
sys_readmem.o sys_readmem_lex.o sys_scanf.o sys_sdf.o \
|
||||
sys_time.o sys_vcd.o sys_vcdoff.o vcd_priv.o \
|
||||
mt19937int.o priv.o sdf_lexor.o sdf_parse.o stringheap.o
|
||||
|
||||
ifeq (@HAVE_LIBZ@,yes)
|
||||
ifeq (@HAVE_LIBBZ2@,yes)
|
||||
|
|
@ -84,6 +87,12 @@ system.vpi: $O ../vvp/libvpi.a
|
|||
sys_readmem_lex.c: sys_readmem_lex.lex
|
||||
flex -t -Preadmem $(srcdir)/sys_readmem_lex.lex > sys_readmem_lex.c
|
||||
|
||||
sdf_lexor.c: sdf_lexor.lex
|
||||
flex -t -Psdf $(srcdir)/sdf_lexor.lex > sdf_lexor.c
|
||||
|
||||
sdf_parse.c sdf_parse.h: $(srcdir)/sdf_parse.y
|
||||
$(YACC) --verbose -d -p sdf -o sdf_parse.c $(srcdir)/sdf_parse.y
|
||||
|
||||
ifeq (@enable_vvp32@,yes)
|
||||
|
||||
all32: bin32 bin32/system.vpi
|
||||
|
|
|
|||
|
|
@ -15,6 +15,14 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(YACC,bison,none)
|
||||
if test "$YACC" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable bison found. ***"
|
||||
echo " Please install the 'bison' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_EXEEXT
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,127 @@
|
|||
|
||||
%option never-interactive
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2007 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
# include "sdf_priv.h"
|
||||
# include "sdf_parse_priv.h"
|
||||
# include "sdf_parse.h"
|
||||
# include <stdlib.h>
|
||||
# include <strings.h>
|
||||
# include <assert.h>
|
||||
|
||||
static void process_quoted_string(void);
|
||||
static int lookup_keyword(const char*text);
|
||||
const char*sdf_parse_path = 0;
|
||||
|
||||
static int yywrap(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
# define yylval sdflval
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
[ \m\t] { /* Skip white space. */; }
|
||||
|
||||
/* Count lines so that the parser can assign line numbers. */
|
||||
\n { sdflloc.first_line += 1; }
|
||||
|
||||
/* Real values */
|
||||
[0-9]+(\.[0-9]+)?([Ee][+-]?[0-9]+)? {
|
||||
yylval.real_val = strtod(yytext, 0);
|
||||
return REAL_NUMBER;
|
||||
}
|
||||
|
||||
[a-zA-Z]+ {
|
||||
return lookup_keyword(yytext);
|
||||
}
|
||||
|
||||
\"[^\"]*\" {
|
||||
process_quoted_string();
|
||||
return QSTRING;
|
||||
}
|
||||
|
||||
. { return yytext[0]; }
|
||||
|
||||
%%
|
||||
|
||||
static struct {
|
||||
const char*name;
|
||||
int code;
|
||||
} keywords[] = {
|
||||
{ "ABSOLUTE", K_ABSOLUTE },
|
||||
{ "CELL", K_CELL },
|
||||
{ "CELLTYPE", K_CELLTYPE },
|
||||
{ "DATE", K_DATE },
|
||||
{ "DELAY", K_DELAY },
|
||||
{ "DELAYFILE", K_DELAYFILE },
|
||||
{ "DESIGN", K_DESIGN },
|
||||
{ "DIVIDER", K_DIVIDER },
|
||||
{ "INCREMENT", K_INCREMENT },
|
||||
{ "INSTANCE", K_INSTANCE },
|
||||
{ "IOPATH", K_IOPATH },
|
||||
{ "PROCESS", K_PROCESS },
|
||||
{ "PROGRAM", K_PROGRAM },
|
||||
{ "SDFVERSION", K_SDFVERSION },
|
||||
{ "TEMPERATURE",K_TEMPERATURE },
|
||||
{ "TIMESCALE", K_TIMESCALE },
|
||||
{ "VENDOR", K_VENDOR },
|
||||
{ "VERSION", K_VERSION },
|
||||
{ "VOLTAGE", K_VOLTAGE },
|
||||
{ 0, IDENTIFIER }
|
||||
};
|
||||
|
||||
static int lookup_keyword(const char*text)
|
||||
{
|
||||
int idx;
|
||||
for (idx = 0 ; keywords[idx].name ; idx += 1) {
|
||||
if (strcasecmp(text, keywords[idx].name) == 0)
|
||||
return keywords[idx].code;
|
||||
}
|
||||
|
||||
yylval.string_val = strdup(yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a string witout the leading and trailing quotes.
|
||||
*/
|
||||
static void process_quoted_string(void)
|
||||
{
|
||||
yylval.string_val = strdup(yytext+1);
|
||||
char*endp = yylval.string_val+strlen(yylval.string_val);
|
||||
assert(endp[-1] == '"');
|
||||
endp[-1] = 0;
|
||||
}
|
||||
|
||||
extern int sdfparse(void);
|
||||
void sdf_process_file(FILE*fd, const char*path)
|
||||
{
|
||||
yyrestart(fd);
|
||||
|
||||
sdf_parse_path = path;
|
||||
sdfparse();
|
||||
sdf_parse_path = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
extern int sdflex(void);
|
||||
static void yyerror(const char*msg);
|
||||
# include "vpi_user.h"
|
||||
# include "sdf_parse_priv.h"
|
||||
# include "sdf_priv.h"
|
||||
# include <stdio.h>
|
||||
|
||||
/* This is the hierarchy separator to use. */
|
||||
static char use_hchar = '.';
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
unsigned long int_val;
|
||||
double real_val;
|
||||
char* string_val;
|
||||
|
||||
struct sdf_delval_list_s delval_list;
|
||||
};
|
||||
|
||||
%token K_ABSOLUTE K_CELL K_CELLTYPE K_DATE K_DELAYFILE K_DELAY K_DESIGN
|
||||
%token K_DIVIDER K_INCREMENT K_INSTANCE K_IOPATH
|
||||
%token K_PROCESS K_PROGRAM K_SDFVERSION K_TEMPERATURE K_TIMESCALE
|
||||
%token K_VENDOR K_VERSION K_VOLTAGE
|
||||
|
||||
%token <string_val> QSTRING IDENTIFIER
|
||||
%token <real_val> REAL_NUMBER
|
||||
%token <int_val> INTEGER
|
||||
|
||||
%type <string_val> celltype
|
||||
%type <string_val> cell_instance
|
||||
%type <string_val> hierarchical_identifier
|
||||
%type <string_val> port port_instance port_spec
|
||||
|
||||
%type <real_val> rvalue rtriple signed_real_number
|
||||
%type <real_val> delval
|
||||
|
||||
%type <delval_list> delval_list
|
||||
|
||||
%%
|
||||
|
||||
source_file
|
||||
: '(' K_DELAYFILE sdf_header_list cell_list ')'
|
||||
;
|
||||
|
||||
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 ')'
|
||||
{ free($3);
|
||||
}
|
||||
;
|
||||
|
||||
design_name
|
||||
: '(' K_DESIGN QSTRING ')'
|
||||
{ if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Design: %s\n",
|
||||
sdf_parse_path, @2.first_line, $3);
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
date
|
||||
: '(' K_DATE QSTRING ')'
|
||||
{ if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Date: %s\n",
|
||||
sdf_parse_path, @2.first_line, $3);
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
vendor
|
||||
: '(' K_VENDOR QSTRING ')'
|
||||
{ if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Vendor: %s\n",
|
||||
sdf_parse_path, @2.first_line, $3);
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
program_name
|
||||
: '(' K_PROGRAM QSTRING ')'
|
||||
{ if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Program: %s\n",
|
||||
sdf_parse_path, @2.first_line, $3);
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
program_version
|
||||
: '(' K_VERSION QSTRING ')'
|
||||
{ if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Program Version: %s\n",
|
||||
sdf_parse_path, @2.first_line, $3);
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
hierarchy_divider
|
||||
: '(' K_DIVIDER '.' ')' { use_hchar = '.'; }
|
||||
| '(' K_DIVIDER '/' ')' { use_hchar = '/'; }
|
||||
;
|
||||
|
||||
voltage
|
||||
: '(' K_VOLTAGE rtriple ')'
|
||||
| '(' K_VOLTAGE signed_real_number ')'
|
||||
;
|
||||
|
||||
process
|
||||
: '(' K_PROCESS QSTRING ')'
|
||||
{ if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Process: %s\n",
|
||||
sdf_parse_path, @2.first_line, $3);
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
temperature
|
||||
: '(' K_TEMPERATURE rtriple ')'
|
||||
| '(' K_TEMPERATURE signed_real_number ')'
|
||||
;
|
||||
|
||||
time_scale
|
||||
: '(' K_TIMESCALE REAL_NUMBER IDENTIFIER ')'
|
||||
{ if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: TIMESCALE : %f%s\n",
|
||||
sdf_parse_path, @2.first_line, $3, $4);
|
||||
free($4);
|
||||
}
|
||||
;
|
||||
|
||||
cell_list
|
||||
: cell_list cell
|
||||
| cell
|
||||
;
|
||||
|
||||
cell
|
||||
: '(' K_CELL celltype cell_instance
|
||||
{ sdf_select_instance($3, $4); /* find the instance in the design */}
|
||||
timing_spec_list
|
||||
')'
|
||||
{ free($3);
|
||||
free($4); }
|
||||
| '(' K_CELL error ')'
|
||||
{ vpi_printf("%s:%d: Syntax error in CELL\n",
|
||||
sdf_parse_path, @2.first_line); }
|
||||
;
|
||||
|
||||
celltype
|
||||
: '(' K_CELLTYPE QSTRING ')'
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
cell_instance
|
||||
: '(' K_INSTANCE hierarchical_identifier ')'
|
||||
{ $$ = $3; }
|
||||
| '(' K_INSTANCE '*' ')'
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
timing_spec_list
|
||||
: timing_spec_list timing_spec
|
||||
| timing_spec
|
||||
;
|
||||
|
||||
timing_spec
|
||||
: '(' K_DELAY deltype_list ')'
|
||||
| '(' K_DELAY error ')'
|
||||
{ vpi_printf("%s:%d: Syntax error in CELL DELAY SPEC\n",
|
||||
sdf_parse_path, @2.first_line); }
|
||||
;
|
||||
|
||||
deltype_list
|
||||
: deltype_list deltype
|
||||
| deltype
|
||||
;
|
||||
|
||||
deltype
|
||||
: '(' K_ABSOLUTE del_def_list ')'
|
||||
| '(' K_INCREMENT del_def_list ')'
|
||||
| '(' error ')'
|
||||
{ vpi_printf("%s:%d: Invalid/malformed delay type\n",
|
||||
sdf_parse_path, @1.first_line); }
|
||||
;
|
||||
|
||||
del_def_list
|
||||
: del_def_list del_def
|
||||
| del_def
|
||||
;
|
||||
|
||||
del_def
|
||||
: '(' K_IOPATH port_spec port_instance delval_list ')'
|
||||
{ sdf_iopath_delays($3, $4, &$5);
|
||||
free($3);
|
||||
free($4);
|
||||
}
|
||||
| '(' K_IOPATH error ')'
|
||||
{ vpi_printf("%s:%d: Invalid/malformed IOPATH\n",
|
||||
sdf_parse_path, @2.first_line); }
|
||||
;
|
||||
|
||||
port_spec
|
||||
: port_instance
|
||||
/* | port_edge */
|
||||
;
|
||||
|
||||
port_instance
|
||||
: port { $$ = $1; }
|
||||
;
|
||||
|
||||
port
|
||||
: hierarchical_identifier
|
||||
{ $$ = $1; }
|
||||
/* | hierarchical_identifier '[' INTEGER ']' */
|
||||
;
|
||||
|
||||
delval_list
|
||||
: delval_list delval
|
||||
{ int idx;
|
||||
$$.count = $1.count;
|
||||
for (idx = 0 ; idx < $$.count ; idx += 1)
|
||||
$$.val[idx] = $1.val[idx];
|
||||
if ($$.count < 12) {
|
||||
$$.val[$$.count] = $2;
|
||||
$$.count += 1;
|
||||
}
|
||||
}
|
||||
| delval
|
||||
{ $$.count = 1;
|
||||
$$.val[0] = $1;
|
||||
}
|
||||
;
|
||||
|
||||
delval
|
||||
: rvalue
|
||||
{ $$ = $1; }
|
||||
| '(' rvalue rvalue ')'
|
||||
{ $$ = $2;
|
||||
vpi_printf("%s:%d: SDF WARNING: Pulse rejection limits ignored\n",
|
||||
sdf_parse_path, @3.first_line);
|
||||
}
|
||||
| '(' rvalue rvalue rvalue ')'
|
||||
{ $$ = $2;
|
||||
vpi_printf("%s:%d: SDF WARNING: Pulse rejection limits ignored\n",
|
||||
sdf_parse_path, @3.first_line);
|
||||
}
|
||||
;
|
||||
|
||||
rvalue
|
||||
: '(' signed_real_number ')'
|
||||
{ $$ = $2; }
|
||||
| '(' rtriple ')'
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
hierarchical_identifier
|
||||
: IDENTIFIER
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
rtriple
|
||||
: signed_real_number ':' signed_real_number ':' signed_real_number
|
||||
{ $$ = $3; /* XXXX Assume typical value. */ }
|
||||
;
|
||||
|
||||
signed_real_number
|
||||
: REAL_NUMBER { $$ = $1; }
|
||||
| '+' REAL_NUMBER { $$ = $2; }
|
||||
| '-' REAL_NUMBER { $$ = -$2; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void yyerror(const char*msg)
|
||||
{
|
||||
fprintf(stderr, "SDF ERROR: %s\n", msg);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef _sdf_parse_priv_h
|
||||
#define _sdf_parse_priv_h
|
||||
/*
|
||||
* Copyright (c) 2007 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is only included by sdf_parse.y and sdf_lexor.lex. It is
|
||||
* used to share declarations between the parse and the lexor.
|
||||
*/
|
||||
|
||||
/* Path to source for error messages. */
|
||||
extern const char*sdf_parse_path;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef _sdf_priv_h
|
||||
#define _sdf_priv_h
|
||||
/*
|
||||
* Copyright (c) 2007 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
/*
|
||||
* Invoke the parser to parse the opened SDF file. The fd is the SDF
|
||||
* file already opened and ready for reading. The path is the path to
|
||||
* the file and is only used for error messages.
|
||||
*/
|
||||
extern void sdf_process_file(FILE*fd, const char*path);
|
||||
|
||||
extern int sdf_flag_warning;
|
||||
extern int sdf_flag_inform;
|
||||
|
||||
/* ****
|
||||
* These functions are called by the parser to process the SDF file as
|
||||
* it is parsed.
|
||||
*/
|
||||
|
||||
struct sdf_delval_list_s {
|
||||
int count;
|
||||
double val[12];
|
||||
};
|
||||
|
||||
extern void sdf_select_instance(const char*celltype, const char*inst);
|
||||
extern void sdf_iopath_delays(const char*src, const char*dst,
|
||||
const struct sdf_delval_list_s*delval);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
# include "vpi_config.h"
|
||||
|
||||
# include "vpi_user.h"
|
||||
# include "sdf_priv.h"
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* These are static context
|
||||
*/
|
||||
|
||||
int sdf_flag_warnings = 0;
|
||||
int sdf_flag_inform = 0;
|
||||
|
||||
/* Scope of the $sdf_annotate call. Annotation starts here. */
|
||||
static vpiHandle sdf_scope;
|
||||
/* The cell in process. */
|
||||
static vpiHandle sdf_cur_cell;
|
||||
|
||||
/*
|
||||
* These functions are called by the SDF parser during parsing to
|
||||
* handling items discovered in the parse.
|
||||
*/
|
||||
void sdf_select_instance(const char*celltype, const char*cellinst)
|
||||
{
|
||||
vpiHandle idx = vpi_iterate(vpiModule, sdf_scope);
|
||||
assert(idx);
|
||||
|
||||
vpiHandle cur;
|
||||
while ( (cur = vpi_scan(idx)) ) {
|
||||
|
||||
/* If we find the cell in this scope, then save it for
|
||||
future processing. */
|
||||
if ( strcmp(cellinst, vpi_get_str(vpiName,cur)) == 0) {
|
||||
sdf_cur_cell = cur;
|
||||
vpi_free_object(idx);
|
||||
|
||||
/* The scope that matches should be a module. */
|
||||
if (vpi_get(vpiType,sdf_cur_cell) != vpiModule) {
|
||||
vpi_printf("SDF ERROR: Scope %s in %s is not a module.\n",
|
||||
cellinst, vpi_get_str(vpiName,sdf_scope));
|
||||
}
|
||||
/* The matching scope (a module) should have the
|
||||
expected type. */
|
||||
if (strcmp(celltype,vpi_get_str(vpiDefName,sdf_cur_cell)) != 0) {
|
||||
vpi_printf("SDF ERROR: Module %s in %s is not a %s; "
|
||||
"it is an %s\n", cellinst,
|
||||
vpi_get_str(vpiName,sdf_scope), celltype,
|
||||
vpi_get_str(vpiDefName,sdf_cur_cell));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sdf_cur_cell = 0;
|
||||
vpi_printf("SDF WARNING: Unable to find %s in current scope\n", cellinst);
|
||||
}
|
||||
|
||||
void sdf_iopath_delays(const char*src, const char*dst,
|
||||
const struct sdf_delval_list_s*delval_list)
|
||||
{
|
||||
assert(sdf_cur_cell);
|
||||
|
||||
vpiHandle iter = vpi_iterate(vpiModPath, sdf_cur_cell);
|
||||
assert(iter);
|
||||
|
||||
/* Search for the modpath that matches the IOPATH by looking
|
||||
for the modpath that uses the same ports as the ports that
|
||||
the parser has found. */
|
||||
vpiHandle path;
|
||||
while ( (path = vpi_scan(iter)) ) {
|
||||
vpiHandle path_in = vpi_handle(vpiModPathIn,path);
|
||||
vpiHandle path_out = vpi_handle(vpiModPathOut,path);
|
||||
|
||||
path_in = vpi_handle(vpiExpr,path_in);
|
||||
path_out = vpi_handle(vpiExpr,path_out);
|
||||
assert(vpi_get(vpiType,path_in) == vpiNet);
|
||||
assert(vpi_get(vpiType,path_out) == vpiNet);
|
||||
|
||||
/* If the src name doesn't match, go on. */
|
||||
if (strcmp(src,vpi_get_str(vpiName,path_in)) != 0)
|
||||
continue;
|
||||
|
||||
/* If the dst name doesn't match, go on. */
|
||||
if (strcmp(dst,vpi_get_str(vpiName,path_out)) != 0)
|
||||
continue;
|
||||
|
||||
/* Ah, this must be a match! */
|
||||
break;
|
||||
}
|
||||
|
||||
if (path == 0) {
|
||||
vpi_printf("SDF ERROR: Unable to find ModPath %s -> %s in %s\n",
|
||||
src, dst, vpi_get_str(vpiName,sdf_cur_cell));
|
||||
return;
|
||||
}
|
||||
|
||||
/* No longer need the iterator. */
|
||||
vpi_free_object(iter);
|
||||
|
||||
struct t_vpi_time delay_vals[12];
|
||||
int idx;
|
||||
for (idx = 0 ; idx < delval_list->count ; idx += 1) {
|
||||
delay_vals[idx].type = vpiScaledRealTime;
|
||||
delay_vals[idx].real = delval_list->val[idx];
|
||||
}
|
||||
|
||||
s_vpi_delay delays;
|
||||
delays.da = delay_vals;
|
||||
delays.no_of_delays = delval_list->count;
|
||||
delays.time_type = vpiScaledRealTime;
|
||||
delays.mtm_flag = 0;
|
||||
delays.append_flag = 0;
|
||||
delays.plusere_flag = 0;
|
||||
|
||||
vpi_put_delays(path, &delays);
|
||||
}
|
||||
|
||||
static void check_command_line_args(void)
|
||||
{
|
||||
struct t_vpi_vlog_info vlog_info;
|
||||
int idx;
|
||||
|
||||
static int sdf_command_line_done = 0;
|
||||
if (sdf_command_line_done)
|
||||
return;
|
||||
|
||||
vpi_get_vlog_info(&vlog_info);
|
||||
|
||||
for (idx = 0 ; idx < vlog_info.argc ; idx += 1) {
|
||||
if (strcmp(vlog_info.argv[idx],"-sdf-warn") == 0) {
|
||||
sdf_flag_warnings = 1;
|
||||
|
||||
} else if (strcmp(vlog_info.argv[idx],"-sdf-info") == 0) {
|
||||
sdf_flag_inform = 1;
|
||||
|
||||
} else if (strcmp(vlog_info.argv[idx],"-sdf-verbose") == 0) {
|
||||
sdf_flag_warnings = 1;
|
||||
sdf_flag_inform = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sdf_command_line_done = 1;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_sdf_annotate_compiletf(PLI_BYTE8*name)
|
||||
{
|
||||
check_command_line_args();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_sdf_annotate_calltf(PLI_BYTE8*name)
|
||||
{
|
||||
s_vpi_value value;
|
||||
vpiHandle sys = vpi_handle(vpiSysTfCall,0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
||||
|
||||
vpiHandle path = vpi_scan(argv);
|
||||
assert(path);
|
||||
|
||||
vpi_free_object(argv);
|
||||
|
||||
value.format = vpiStringVal;
|
||||
vpi_get_value(path, &value);
|
||||
|
||||
if ((value.format != vpiStringVal) || !value.value.str) {
|
||||
vpi_printf("ERROR: %s: File name argument (type=%d)"
|
||||
" does not have a string value\n",
|
||||
name, vpi_get(vpiType, path));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char*path_str = strdup(value.value.str);
|
||||
FILE*sdf_fd = fopen(path_str, "r");
|
||||
assert(sdf_fd);
|
||||
|
||||
sdf_scope = vpi_handle(vpiScope,sys);
|
||||
sdf_cur_cell = 0;
|
||||
|
||||
sdf_process_file(sdf_fd, path_str);
|
||||
|
||||
fclose(sdf_fd);
|
||||
free(path_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_sdf_register()
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$sdf_annotate";
|
||||
tf_data.calltf = sys_sdf_annotate_calltf;
|
||||
tf_data.compiletf = sys_sdf_annotate_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$sdf_annotate";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ extern void sys_random_register();
|
|||
extern void sys_random_mti_register();
|
||||
extern void sys_readmem_register();
|
||||
extern void sys_scanf_register();
|
||||
extern void sys_sdf_register();
|
||||
extern void sys_time_register();
|
||||
extern void sys_vcd_register();
|
||||
extern void sys_vcdoff_register();
|
||||
|
|
@ -176,6 +177,7 @@ void (*vlog_startup_routines[])() = {
|
|||
sys_scanf_register,
|
||||
sys_time_register,
|
||||
sys_lxt_or_vcd_register,
|
||||
sys_sdf_register,
|
||||
0
|
||||
};
|
||||
|
||||
|
|
|
|||
44
vvp/delay.cc
44
vvp/delay.cc
|
|
@ -576,19 +576,53 @@ static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays )
|
|||
|
||||
vvp_fun_modpath_src *fun = dynamic_cast<vvp_fun_modpath_src*>(src->net->fun);
|
||||
assert( fun );
|
||||
assert(delays->no_of_delays == 12);
|
||||
|
||||
typedef unsigned char map_array_t[12];
|
||||
static const map_array_t map_2 = {0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0};
|
||||
static const map_array_t map12 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
|
||||
const map_array_t*use_map = 0;
|
||||
switch (delays->no_of_delays) {
|
||||
case 2:
|
||||
use_map = &map_2;
|
||||
break;
|
||||
case 12:
|
||||
use_map = &map12;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (delays->time_type == vpiSimTime) {
|
||||
for (idx = 0 ; idx < delays->no_of_delays ; idx += 1) {
|
||||
tmp[idx] = vpip_timestruct_to_time(delays->da+idx);
|
||||
for (idx = 0 ; idx < 12 ; idx += 1) {
|
||||
tmp[idx] = vpip_timestruct_to_time(delays->da+use_map[0][idx]);
|
||||
}
|
||||
} else {
|
||||
for (idx = 0 ; idx < delays->no_of_delays ; idx += 1) {
|
||||
tmp[idx] = vpip_scaled_real_to_time64(delays->da[idx].real,
|
||||
for (idx = 0 ; idx < 12 ; idx += 1) {
|
||||
tmp[idx] = vpip_scaled_real_to_time64(delays->da[use_map[0][idx]].real,
|
||||
src->dest->scope);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now clean up any to-from-x delays to me the min/max based on
|
||||
the rules for selecting X delays. This only needs to happen
|
||||
if the X delays are not already explicitly given. */
|
||||
if (delays->no_of_delays <= 6) {
|
||||
vvp_time64_t t_max = tmp[0];
|
||||
vvp_time64_t t_min = tmp[1];
|
||||
for (idx = 1 ; idx < delays->no_of_delays ; idx += 1) {
|
||||
if (tmp[idx] > t_max) t_max = tmp[idx];
|
||||
if (tmp[idx] < t_min) t_min = tmp[idx];
|
||||
}
|
||||
tmp[DELAY_EDGE_0x] = t_min;
|
||||
tmp[DELAY_EDGE_x1] = t_max;
|
||||
tmp[DELAY_EDGE_1x] = t_min;
|
||||
tmp[DELAY_EDGE_x0] = t_max;
|
||||
tmp[DELAY_EDGE_xz] = t_max;
|
||||
tmp[DELAY_EDGE_zx] = t_min;
|
||||
}
|
||||
|
||||
fun->put_delay12(tmp);
|
||||
}
|
||||
|
||||
|
|
|
|||
14
vvp/vvp.man
14
vvp/vvp.man
|
|
@ -96,6 +96,20 @@ space, and is written out incrementally. Thus, you can view lxt2 files
|
|||
while a simulation is still running (or paused) or if your simulation
|
||||
crashes or is killed, you still have a useful dump.
|
||||
|
||||
.TP 8
|
||||
.B -sdf-warn
|
||||
When loading an SDF annnotation file, this option causes the annotator
|
||||
to print warnings for questionable but non-fatal issues.
|
||||
|
||||
.TP 8
|
||||
.B -sdf-info
|
||||
When loading an SDF annnotation file, this option causes the annotator
|
||||
to print information about the annotation.
|
||||
|
||||
.TP 8
|
||||
.B -sdf-verbose
|
||||
This is shorthand for -sdf-info -sdf-warn.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.PP
|
||||
The vvp command also accepts some environment variables that control
|
||||
|
|
|
|||
Loading…
Reference in New Issue