Merge branch 'work3'
This commit is contained in:
commit
591c35cd7c
|
|
@ -43,6 +43,13 @@ dep
|
|||
|
||||
/ivlpp/lexor.c
|
||||
|
||||
/vhdlpp/lexor.cc
|
||||
/vhdlpp/lexor_keyword.cc
|
||||
/vhdlpp/parse.cc
|
||||
/vhdlpp/parse.h
|
||||
/vhdlpp/vhdlpp_config.h
|
||||
/vhdlpp/vhdlpp
|
||||
|
||||
/lexor.cc
|
||||
/lexor_keyword.cc
|
||||
/parse.cc
|
||||
|
|
|
|||
19
Makefile.in
19
Makefile.in
|
|
@ -38,7 +38,7 @@ exec_prefix = @exec_prefix@
|
|||
srcdir = @srcdir@
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
SUBDIRS = ivlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
|
||||
SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
|
||||
tgt-vhdl tgt-vlog95 driver
|
||||
# Only run distclean for these directories.
|
||||
NOTUSED = tgt-fpga tgt-pal tgt-verilog
|
||||
|
|
@ -80,9 +80,9 @@ PS2PDF = @PS2PDF@
|
|||
GIT = @GIT@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I.
|
||||
INCLUDE_PATH = -I. -Ilibmisc
|
||||
else
|
||||
INCLUDE_PATH = -I. -I$(srcdir)
|
||||
INCLUDE_PATH = -I. -Ilibmisc -I$(srcdir) -I$(srcdir)/libmisc
|
||||
endif
|
||||
|
||||
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
|
||||
|
|
@ -91,6 +91,9 @@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
|||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
|
||||
# Source files in the libmisc directory
|
||||
M = LineInfo.o StringHeap.o
|
||||
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
|
||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
|
||||
|
||||
|
|
@ -104,9 +107,9 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
|||
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
||||
pform_disciplines.o pform_dump.o pform_types.o set_width.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o PExpr.o PGate.o \
|
||||
Attrib.o HName.o Module.o PDelays.o PEvent.o PExpr.o PGate.o \
|
||||
PGenerate.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
|
||||
Statement.o AStatement.o StringHeap.o $(FF) $(TT)
|
||||
Statement.o AStatement.o $M $(FF) $(TT)
|
||||
|
||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
|
|
@ -197,7 +200,7 @@ ifeq (@WIN32@,yes)
|
|||
# The first step makes an ivl.exe that dlltool can use to make an
|
||||
# export and import library, and the last link makes a, ivl.exe
|
||||
# that really exports the things that the import library imports.
|
||||
ivl@EXEEXT@: $O $(srcdir)/ivl.def
|
||||
ivl@EXEEXT@: $O $(srcdir)/ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
||||
dlltool --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
|
||||
--output-lib libivl.a --output-exp ivl.exp
|
||||
|
|
@ -229,6 +232,10 @@ version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
|
|||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
%.o: $(srcdir)/libmisc/%.cc
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
# Here are some explicit dependencies needed to get things going.
|
||||
main.o: main.cc version_tag.h
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
|
|||
AC_INIT(netlist.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADER(_pli_types.h)
|
||||
AC_CONFIG_HEADER(vhdlpp/vhdlpp_config.h)
|
||||
AC_CONFIG_HEADER(vvp/config.h)
|
||||
AC_CONFIG_HEADER(vpi/vpi_config.h)
|
||||
AC_CONFIG_HEADER(libveriuser/config.h)
|
||||
|
|
@ -295,4 +296,4 @@ AC_MSG_RESULT(ok)
|
|||
|
||||
# XXX disable tgt-fpga for the moment
|
||||
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile)
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile)
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ const char sep = '/';
|
|||
extern void cfreset(FILE*fd, const char*path);
|
||||
|
||||
const char*base = 0;
|
||||
const char*pbase = 0;
|
||||
const char*ivlpp_dir = 0;
|
||||
const char*vhdlpp_dir= 0;
|
||||
const char*mtm = 0;
|
||||
const char*opath = "a.out";
|
||||
const char*npath = 0;
|
||||
|
|
@ -304,7 +305,7 @@ static int t_version_only(void)
|
|||
free(source_path);
|
||||
|
||||
fflush(0);
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp -V", pbase, sep);
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp -V", ivlpp_dir, sep);
|
||||
rc = system(tmp);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
|
||||
|
|
@ -333,7 +334,7 @@ static int t_version_only(void)
|
|||
static void build_preprocess_command(int e_flag)
|
||||
{
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\" ",
|
||||
pbase, sep, verbose_flag?" -v":"",
|
||||
ivlpp_dir, sep, verbose_flag?" -v":"",
|
||||
e_flag?"":" -L", defines_path, source_path,
|
||||
compiled_defines_path);
|
||||
}
|
||||
|
|
@ -875,14 +876,20 @@ int main(int argc, char **argv)
|
|||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
/* Undocumented feature: The preprocessor itself
|
||||
may be located at a different location. If the
|
||||
base starts with a 'P', set this special base
|
||||
instead of the main base. */
|
||||
if (optarg[0] == 'P') {
|
||||
pbase = optarg+1;
|
||||
} else {
|
||||
/* The individual components can be located by a
|
||||
single base, or by individual bases. The first
|
||||
character of the path indicates which path the
|
||||
user is specifying. */
|
||||
switch (optarg[0]) {
|
||||
case 'P': /* Path for the ivlpp preprocessor */
|
||||
ivlpp_dir = optarg+1;
|
||||
break;
|
||||
case 'V': /* Path for the vhdlpp VHDL processor */
|
||||
vhdlpp_dir = optarg+1;
|
||||
break;
|
||||
default: /* Otherwise, this is a default base. */
|
||||
base=optarg;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
|
|
@ -995,8 +1002,10 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (pbase == 0)
|
||||
pbase = base;
|
||||
if (ivlpp_dir == 0)
|
||||
ivlpp_dir = base;
|
||||
if (vhdlpp_dir == 0)
|
||||
vhdlpp_dir = base;
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
||||
|
|
@ -1017,6 +1026,8 @@ int main(int argc, char **argv)
|
|||
snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
|
||||
base, sep, targ, synth_flag? "-s" : "");
|
||||
|
||||
fprintf(defines_file, "vhdlpp:%s%cvhdlpp\n", vhdlpp_dir, sep);
|
||||
|
||||
/* Write values to the iconfig file. */
|
||||
fprintf(iconfig_file, "basedir:%s\n", base);
|
||||
|
||||
|
|
@ -1143,7 +1154,7 @@ int main(int argc, char **argv)
|
|||
single file. This may be used to preprocess library
|
||||
files. */
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F\"%s\" -P\"%s\"\n",
|
||||
pbase, sep, defines_path, compiled_defines_path);
|
||||
ivlpp_dir, sep, defines_path, compiled_defines_path);
|
||||
|
||||
/* Done writing to the iconfig file. Close it now. */
|
||||
fclose(iconfig_file);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ extern void dump_precompiled_defines(FILE*out);
|
|||
an include directive in encountered. */
|
||||
extern char**include_dir;
|
||||
extern unsigned include_cnt;
|
||||
/* Program to use for VHDL processing. */
|
||||
extern char*vhdlpp_path;
|
||||
|
||||
extern int relative_include;
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,15 @@ valid options include:
|
|||
This option does *not* override existing `define
|
||||
directives in the source file.
|
||||
|
||||
-F <path>
|
||||
Read ivlpp options from a FLAGS FILE. This is not the same
|
||||
as a file list. This file contains flags, not source
|
||||
files. There may be multiple flags files.
|
||||
|
||||
-f <path>
|
||||
Read ivlpp input files from a file list. There can be no
|
||||
more then one file list.
|
||||
|
||||
-I <dir>
|
||||
Add a directory to the include path. Normally, only "." is
|
||||
in the search path. The -I flag causes other directories
|
||||
|
|
@ -59,8 +68,42 @@ valid options include:
|
|||
output.
|
||||
|
||||
-v
|
||||
Print version and copyright information
|
||||
Print version and copyright information before processing
|
||||
input files.
|
||||
|
||||
-V
|
||||
Print version and copyright information, then exit WITHOUT
|
||||
processing any input files.
|
||||
|
||||
FLAGS FILE
|
||||
|
||||
A flags file contains flags for use by ivlpp. This is a convenient way
|
||||
for programs to pass complex sets of flags to the ivlpp program.
|
||||
|
||||
Blank lines and lines that start with "#" are ignored. The latter can
|
||||
be used as comment lines. All other lines are flag lines. Leading and
|
||||
trailing white space are removed before the lines are interpreted.
|
||||
|
||||
Other lines have the simple format:
|
||||
|
||||
<key>:<value>
|
||||
|
||||
The colon character separates a key from the value. The supported
|
||||
keys, with their corresponding values, are:
|
||||
|
||||
D:name=<value>
|
||||
This is exactly the same as the "-Dname=<value>" described above.
|
||||
|
||||
I:<dir>
|
||||
This is exctly the same as "-I<dir>".
|
||||
|
||||
relative include:<flag>
|
||||
The <flag> can be "true" or "false". This enables "relative
|
||||
includes" nesting behavior.
|
||||
|
||||
vhdlpp:<path>
|
||||
Give the path to the vhdlpp program. This program is used to
|
||||
process VHDL input files.
|
||||
|
||||
LOCATING INCLUDED FILES
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ struct include_stack_t
|
|||
|
||||
/* If the current input is from a file, this member is set. */
|
||||
FILE* file;
|
||||
int (*file_close)(FILE*);
|
||||
|
||||
/* If we are reparsing a macro expansion, file is 0 and this
|
||||
* member points to the string in progress
|
||||
|
|
@ -1614,8 +1615,10 @@ static void do_include()
|
|||
{
|
||||
/* standby is defined by include_filename() */
|
||||
if (standby->path[0] == '/') {
|
||||
if ((standby->file = fopen(standby->path, "r")))
|
||||
if ((standby->file = fopen(standby->path, "r"))) {
|
||||
standby->file_close = fclose;
|
||||
goto code_that_switches_buffers;
|
||||
}
|
||||
} else {
|
||||
unsigned idx, start = 1;
|
||||
char path[4096];
|
||||
|
|
@ -1644,6 +1647,7 @@ static void do_include()
|
|||
sprintf(path, "%s/%s", include_dir[idx], standby->path);
|
||||
|
||||
if ((standby->file = fopen(path, "r"))) {
|
||||
standby->file_close = fclose;
|
||||
/* Free the original path before we overwrite it. */
|
||||
free(standby->path);
|
||||
standby->path = strdup(path);
|
||||
|
|
@ -1750,6 +1754,58 @@ static void lexor_done()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this function to open a source file that is to be
|
||||
* processed. Do NOT use this function for opening include files,
|
||||
* instead only use this file for opening base source files.
|
||||
*/
|
||||
static void open_input_file(struct include_stack_t*isp)
|
||||
{
|
||||
char*cp;
|
||||
int is_vhdl = 0;
|
||||
|
||||
isp->file = 0;
|
||||
|
||||
/* look for a suffix for the input file. If the suffix
|
||||
indicates that this is a VHDL source file, then invoke
|
||||
vhdlpp to get a data stream. */
|
||||
cp = strrchr(isp->path, '.');
|
||||
if (cp && vhdlpp_path) {
|
||||
if (strcmp(cp, ".vhd") == 0) {
|
||||
is_vhdl = 1;
|
||||
} else if (strcmp(cp, ".vhdl") == 0) {
|
||||
is_vhdl = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_vhdl == 0) {
|
||||
isp->file = fopen(isp->path, "r");
|
||||
isp->file_close = fclose;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t cmdlen = strlen(vhdlpp_path);
|
||||
cmdlen += strlen(isp->path);
|
||||
cmdlen += 32;
|
||||
|
||||
char*cmd = malloc(cmdlen);
|
||||
snprintf(cmd, cmdlen, "%s %s", vhdlpp_path, isp->path);
|
||||
|
||||
isp->file = popen(cmd, "r");
|
||||
isp->file_close = pclose;
|
||||
|
||||
free(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The load_next_input() function is called by the lexical analyzer
|
||||
* when the current file runs out. When the EOF of the current input
|
||||
* file is matched, this function figures out if this is the end of an
|
||||
* included file (in which case the including file is resumed) or the
|
||||
* end of a base file, in which case the next base source file is
|
||||
* opened.
|
||||
*/
|
||||
static int load_next_input()
|
||||
{
|
||||
int line_mask_flag = 0;
|
||||
|
|
@ -1773,7 +1829,8 @@ static int load_next_input()
|
|||
if (isp->file)
|
||||
{
|
||||
free(isp->path);
|
||||
fclose(isp->file);
|
||||
assert(isp->file_close);
|
||||
isp->file_close(isp->file);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1813,7 +1870,7 @@ static int load_next_input()
|
|||
|
||||
istack->next = 0;
|
||||
istack->lineno = 0;
|
||||
istack->file = fopen(istack->path, "r");
|
||||
open_input_file(istack);
|
||||
|
||||
if (istack->file == 0)
|
||||
{
|
||||
|
|
@ -1966,7 +2023,7 @@ void reset_lexor(FILE* out, char* paths[])
|
|||
isp = malloc(sizeof(struct include_stack_t));
|
||||
isp->next = 0;
|
||||
isp->path = strdup(paths[0]);
|
||||
isp->file = fopen(paths[0], "r");
|
||||
open_input_file(isp);
|
||||
isp->str = 0;
|
||||
isp->lineno = 0;
|
||||
isp->stringify_flag = 0;
|
||||
|
|
|
|||
10
ivlpp/main.c
10
ivlpp/main.c
|
|
@ -57,7 +57,8 @@ extern const char*optarg;
|
|||
char *dep_path = NULL;
|
||||
/* Dependency file output mode */
|
||||
char dep_mode = 'a';
|
||||
|
||||
/* Path to vhdlpp */
|
||||
char *vhdlpp_path = 0;
|
||||
|
||||
/*
|
||||
* Keep in source_list an array of pointers to file names. The array
|
||||
|
|
@ -166,6 +167,13 @@ static int flist_read_flags(const char*path)
|
|||
relative_include = 0;
|
||||
}
|
||||
|
||||
} else if (strcmp(cp,"vhdlpp") == 0) {
|
||||
if (vhdlpp_path) {
|
||||
fprintf(stderr, "Ignore multiple vhdlpp flags\n");
|
||||
} else {
|
||||
vhdlpp_path = strdup(arg);
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "%s: Invalid keyword %s\n", path, cp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
LineInfo::LineInfo()
|
||||
: lineno_(0)
|
||||
{
|
||||
|
|
@ -21,7 +21,6 @@
|
|||
# include <cstdlib>
|
||||
# include <cstring>
|
||||
# include <cassert>
|
||||
# include "ivl_alloc.h"
|
||||
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
static char **string_pool = NULL;
|
||||
|
|
@ -19,7 +19,6 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
# include <string>
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library 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 Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library 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
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
ifeq (.,.)
|
||||
INCLUDE_PATH = -I. -I.. -I../libmisc
|
||||
else
|
||||
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/../libmisc
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@ @EXTRALIBS@
|
||||
|
||||
M = StringHeap.o LineInfo.o
|
||||
|
||||
O = main.o compiler.o entity.o entity_elaborate.o \
|
||||
lexor.o lexor_keyword.o parse.o $M
|
||||
|
||||
all: dep vhdlpp@EXEEXT@
|
||||
|
||||
clean:
|
||||
rm -f *.o *~
|
||||
rm -rf dep vhdlpp@EXEEXT@
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
rm -f stamp-vhdlpp_config-h vhdlpp_config.h
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in
|
||||
cd ..; ./config.status --file=vhdlpp/$@
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
vhdlpp@EXEEXT@: $O
|
||||
$(CXX) -o vhdlpp@EXEEXT@ $(LDFLAGS) $O $(LIBS)
|
||||
|
||||
%.o: $(srcdir)/../libmisc/%.cc
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
|
||||
%.o: %.cc vhdlpp_config.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
lexor.o: lexor.cc parse.h
|
||||
|
||||
parse.o: parse.cc
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
$(LEX) -s -olexor.cc $(srcdir)/lexor.lex
|
||||
|
||||
parse.cc parse.h: $(srcdir)/parse.y
|
||||
$(YACC) --verbose -t -d -o parse.cc $(srcdir)/parse.y
|
||||
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
|
||||
|
||||
lexor_keyword.o: lexor_keyword.cc parse.h
|
||||
|
||||
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
|
||||
gperf -o -i 7 --ignore-case -C -k 1-4,6,9,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||
|
||||
install: all installdirs $(libdir)/ivl$(suffix)/vhdlpp@EXEEXT@
|
||||
|
||||
$(libdir)/ivl$(suffix)/vhdlpp@EXEEXT@: vhdlpp@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./vhdlpp@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdlpp@EXEEXT@"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)"
|
||||
|
||||
uninstall:
|
||||
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivhdlpp@EXEEXT@"
|
||||
|
||||
stamp-vhdlpp_config-h: $(srcdir)/vhdlpp_config.h.in ../config.status
|
||||
@rm -f $@
|
||||
cd ..; ./config.status --header=vhdlpp/vhdlpp_config.h
|
||||
vhplpp_config.h: stamp-vhdlpp_config-h
|
||||
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2011 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 "compiler.h"
|
||||
|
||||
StringHeapLex lex_strings;
|
||||
|
||||
StringHeapLex filename_strings;
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
/*
|
||||
* Copyright (c) 2011 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 "StringHeap.h"
|
||||
|
||||
const int GN_KEYWORD_2008 = 0x0001;
|
||||
|
||||
// TRUE if processing is supposed to dump progress to stderr.
|
||||
extern bool verbose_flag;
|
||||
|
||||
extern StringHeapLex lex_strings;
|
||||
|
||||
extern StringHeapLex filename_strings;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2011 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 "entity.h"
|
||||
# include <fstream>
|
||||
# include <iomanip>
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::map<perm_string,Entity*> design_entities;
|
||||
|
||||
static ostream& operator << (ostream&out, port_mode_t that)
|
||||
{
|
||||
switch (that) {
|
||||
case PORT_NONE:
|
||||
out << "NO-PORT";
|
||||
break;
|
||||
case PORT_IN:
|
||||
out << "IN";
|
||||
break;
|
||||
case PORT_OUT:
|
||||
out << "OUT";
|
||||
break;
|
||||
default:
|
||||
out << "PORT-????";
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void dump_design_entity(ostream&out, Entity*obj)
|
||||
{
|
||||
out << "entity " << obj->name << " file=" << obj->get_fileline() << endl;
|
||||
if (obj->ports.size() == 0) {
|
||||
out << " No ports" << endl;
|
||||
} else {
|
||||
out << " PORTS:" << endl;
|
||||
for (vector<InterfacePort*>::iterator cur = obj->ports.begin()
|
||||
; cur != obj->ports.end() ; ++cur) {
|
||||
InterfacePort*item = *cur;
|
||||
out << setw(6) << "" << item->name
|
||||
<< " : " << item->mode
|
||||
<< ", type=" << item->type_name
|
||||
<< ", file=" << item->get_fileline() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_design_entities(const char*path)
|
||||
{
|
||||
ofstream file (path);
|
||||
for (map<perm_string,Entity*>::iterator cur = design_entities.begin()
|
||||
; cur != design_entities.end() ; ++cur) {
|
||||
dump_design_entity(file, cur->second);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#ifndef __entity_H
|
||||
#define __entity_H
|
||||
/*
|
||||
* Copyright (c) 2011 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 <map>
|
||||
# include <vector>
|
||||
# include "StringHeap.h"
|
||||
# include "LineInfo.h"
|
||||
|
||||
typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT } port_mode_t;
|
||||
|
||||
class InterfacePort : public LineInfo {
|
||||
public:
|
||||
// Port direction from the source code.
|
||||
port_mode_t mode;
|
||||
// Name of the port from the source code
|
||||
perm_string name;
|
||||
// Name of interface type as given in the source code.
|
||||
perm_string type_name;
|
||||
};
|
||||
|
||||
class Entity : public LineInfo {
|
||||
|
||||
public:
|
||||
int elaborate();
|
||||
|
||||
public:
|
||||
perm_string name;
|
||||
std::vector<InterfacePort*> ports;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* As the parser parses entities, it puts them into this map. It uses
|
||||
* a map because sometimes it needs to look back at an entity by name.
|
||||
*/
|
||||
extern std::map<perm_string,Entity*> design_entities;
|
||||
|
||||
/*
|
||||
* Elaborate the collected entities, and return the number of
|
||||
* elaboration errors.
|
||||
*/
|
||||
extern int elaborate_entities(void);
|
||||
|
||||
/*
|
||||
* Use this function to dump a description of the design entities to a
|
||||
* file. This is for debug, not for any useful purpose.
|
||||
*/
|
||||
extern void dump_design_entities(const char*path);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2011 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 "entity.h"
|
||||
# include "compiler.h"
|
||||
# include <iostream>
|
||||
# include <fstream>
|
||||
# include <iomanip>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int elaborate_entities(void)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
for (map<perm_string,Entity*>::iterator cur = design_entities.begin()
|
||||
; cur != design_entities.end() ; ++cur) {
|
||||
errors += cur->second->elaborate();
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int Entity::elaborate()
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
if (verbose_flag)
|
||||
cerr << "Elaborate entity " << name << "..." << endl;
|
||||
|
||||
cout << "module " << name;
|
||||
|
||||
// If there are ports, emit them.
|
||||
if (ports.size() > 0) {
|
||||
cout << "(";
|
||||
const char*sep = 0;
|
||||
for (vector<InterfacePort*>::iterator cur = ports.begin()
|
||||
; cur != ports.end() ; ++cur) {
|
||||
InterfacePort*port = *cur;
|
||||
|
||||
// FIXME: this is a stub. This port handling code
|
||||
// currently only supports std_logic signal tyes,
|
||||
// so just assert that the user asked for std_logic.
|
||||
if (port->type_name != "std_logic") {
|
||||
cerr << "sorry: VHDL only supports std_logic ports."
|
||||
<< " Expecting std_logic, but got \""
|
||||
<< port->type_name << "\"" << endl;
|
||||
errors += 1;
|
||||
}
|
||||
|
||||
if (sep) cout << sep;
|
||||
else sep = ", ";
|
||||
|
||||
switch (port->mode) {
|
||||
case PORT_NONE: // Should not happen
|
||||
cout << "NO_PORT " << port->name;
|
||||
break;
|
||||
case PORT_IN:
|
||||
cout << "input " << port->name;
|
||||
break;
|
||||
case PORT_OUT:
|
||||
cout << "output " << port->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cout << ")";
|
||||
}
|
||||
|
||||
cout << ";" << endl;
|
||||
|
||||
cout << "endmodule" << endl;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
%option never-interactive
|
||||
%option nounput
|
||||
%option noyywrap
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2011 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 "parse_api.h"
|
||||
# include "lexor_keyword.h"
|
||||
# include "parse_wrap.h"
|
||||
|
||||
extern int lexor_keyword_code (const char*str, unsigned len);
|
||||
|
||||
/*
|
||||
* Lexical location information is passed in the yylloc variable to th
|
||||
* parser. The file names, strings, are kept in a list so that I can
|
||||
* re-use them. The set_file_name function will return a pointer to
|
||||
* the name as it exists in the list (and delete the passed string.)
|
||||
* If the name is new, it will be added to the list.
|
||||
*/
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
static char* strdupnew(char const *str)
|
||||
{
|
||||
return str ? strcpy(new char [strlen(str)+1], str) : 0;
|
||||
}
|
||||
|
||||
static int comment_enter;
|
||||
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
%x LCOMMENT
|
||||
|
||||
W [ \t\b\f\r]+
|
||||
|
||||
%%
|
||||
|
||||
[ \t\b\f\r] { ; }
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
||||
/* Single-line comments start with - - and run to the end of the
|
||||
current line. These are very easy to handle. */
|
||||
|
||||
"--".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
<LCOMMENT>. { yymore(); }
|
||||
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
||||
|
||||
|
||||
|
||||
/* The contents of C-style comments are ignored, like white space. */
|
||||
|
||||
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
|
||||
<CCOMMENT>. { ; }
|
||||
<CCOMMENT>\n { yylloc.first_line += 1; }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
[a-zA-Z_][a-zA-Z0-9_]* {
|
||||
int rc = lexor_keyword_code(yytext, yyleng);
|
||||
switch (rc) {
|
||||
case IDENTIFIER:
|
||||
yylval.text = strdupnew(yytext);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Compound symbols */
|
||||
"<=" { return LEQ; }
|
||||
">=" { return GEQ; }
|
||||
":=" { return VASSIGN; }
|
||||
|
||||
. { return yytext[0]; }
|
||||
|
||||
%%
|
||||
|
||||
extern void yyparse_set_filepath(const char*path);
|
||||
|
||||
void reset_lexor(FILE*fd, const char*path)
|
||||
{
|
||||
yylloc.text = path;
|
||||
yylloc.first_line = 1;
|
||||
yyrestart(fd);
|
||||
|
||||
yyparse_set_filepath(path);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* We need this to prevent -Wextra (-W) from complaining that the mask and
|
||||
* tokenType values are not initialized for the empty table entries.
|
||||
*/
|
||||
%define initializer-suffix ,0,0
|
||||
|
||||
%{
|
||||
/* Command-line: gperf -o -i 1 --ignore-case -C -k 1-3,$ -L C -H keyword_hash -N check_identifier -tT lexor_keyword.gperf */
|
||||
|
||||
#include "vhdlpp_config.h"
|
||||
#include <cstring>
|
||||
#include "compiler.h"
|
||||
#include "parse_api.h"
|
||||
#include "parse_wrap.h"
|
||||
|
||||
%}
|
||||
struct lexor_keyword { const char*name; int mask; int tokenType; };
|
||||
%%
|
||||
abs, GN_KEYWORD_2008, K_abs
|
||||
access, GN_KEYWORD_2008, K_access
|
||||
all, GN_KEYWORD_2008, K_all
|
||||
and, GN_KEYWORD_2008, K_and
|
||||
architecture, GN_KEYWORD_2008, K_architecture
|
||||
begin, GN_KEYWORD_2008, K_begin
|
||||
end, GN_KEYWORD_2008, K_end
|
||||
entity, GN_KEYWORD_2008, K_entity
|
||||
in, GN_KEYWORD_2008, K_in
|
||||
is, GN_KEYWORD_2008, K_is
|
||||
library, GN_KEYWORD_2008, K_library
|
||||
of, GN_KEYWORD_2008, K_of
|
||||
out, GN_KEYWORD_2008, K_out
|
||||
port, GN_KEYWORD_2008, K_port
|
||||
use, GN_KEYWORD_2008, K_use
|
||||
%%
|
||||
|
||||
int lexor_keyword_mask = GN_KEYWORD_2008;
|
||||
|
||||
int lexor_keyword_code(const char*str, unsigned nstr)
|
||||
{
|
||||
const struct lexor_keyword*rc = check_identifier(str, nstr);
|
||||
if (rc == 0)
|
||||
return IDENTIFIER;
|
||||
else if ((rc->mask & lexor_keyword_mask) == 0)
|
||||
return IDENTIFIER;
|
||||
else
|
||||
return rc->tokenType;
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
|
||||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 2011 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 "vhdlpp_config.h"
|
||||
# include "version_base.h"
|
||||
# include "version_tag.h"
|
||||
|
||||
const char NOTICE[] =
|
||||
" This program is free software; you can redistribute it and/or modify\n"
|
||||
" it under the terms of the GNU General Public License as published by\n"
|
||||
" the Free Software Foundation; either version 2 of the License, or\n"
|
||||
" (at your option) any later version.\n"
|
||||
"\n"
|
||||
" This program is distributed in the hope that it will be useful,\n"
|
||||
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
" GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
" You should have received a copy of the GNU General Public License along\n"
|
||||
" with this program; if not, write to the Free Software Foundation, Inc.,\n"
|
||||
" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
|
||||
;
|
||||
|
||||
# include "compiler.h"
|
||||
# include "parse_api.h"
|
||||
# include <cstdio>
|
||||
# include <cstdlib>
|
||||
# include <cstring>
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
|
||||
bool verbose_flag = false;
|
||||
// Where to dump design entities
|
||||
const char*dump_design_entities_path = 0;
|
||||
|
||||
static void process_debug_token(const char*word)
|
||||
{
|
||||
if (strcmp(word, "yydebug") == 0) {
|
||||
yydebug = 1;
|
||||
} else if (strcmp(word, "no-yydebug") == 0) {
|
||||
yydebug = 0;
|
||||
} else if (strncmp(word, "entities=", 9) == 0) {
|
||||
dump_design_entities_path = strdup(word+9);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
int opt;
|
||||
int rc;
|
||||
|
||||
while ( (opt=getopt(argc, argv, "D:vV")) != EOF) switch (opt) {
|
||||
|
||||
case 'D':
|
||||
process_debug_token(optarg);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
fprintf(stderr, "Icarus Verilog VHDL Parse version "
|
||||
VERSION " (" VERSION_TAG ")\n\n");
|
||||
fprintf(stderr, "%s\n\n", COPYRIGHT);
|
||||
fputs(NOTICE, stderr);
|
||||
verbose_flag = true;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
fprintf(stdout, "Icarus Verilog VHDL Parse version "
|
||||
VERSION " (" VERSION_TAG ")\n\n");
|
||||
fprintf(stdout, "%s\n\n", COPYRIGHT);
|
||||
fputs(NOTICE, stdout);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
for (int idx = optind ; idx < argc ; idx += 1) {
|
||||
parse_errors = 0;
|
||||
FILE*fd = fopen(argv[idx], "r");
|
||||
if (fd == 0) {
|
||||
perror(argv[idx]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
reset_lexor(fd, argv[idx]);
|
||||
rc = yyparse();
|
||||
if (verbose_flag)
|
||||
fprintf(stderr, "yyparse() returns %d, parse_errors=%d\n", rc, parse_errors);
|
||||
|
||||
if (parse_errors > 0) {
|
||||
fprintf(stderr, "%d errors parsing %s\n", parse_errors, argv[idx]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
if (dump_design_entities_path)
|
||||
dump_design_entities(dump_design_entities_path);
|
||||
|
||||
int elaborate_errors = 0;
|
||||
elaborate_errors = elaborate_entities();
|
||||
if (elaborate_errors > 0) {
|
||||
fprintf(stderr, "%d errors elaborating design.\n", elaborate_errors);
|
||||
return 3;
|
||||
}
|
||||
|
||||
lex_strings.cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2011 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 "vhdlpp_config.h"
|
||||
# include "compiler.h"
|
||||
# include "parse_api.h"
|
||||
# include <cstdarg>
|
||||
# include <list>
|
||||
|
||||
inline void FILE_NAME(LineInfo*tmp, const struct yyltype&where)
|
||||
{
|
||||
tmp->set_lineno(where.first_line);
|
||||
tmp->set_file(filename_strings.make(where.text));
|
||||
}
|
||||
|
||||
|
||||
static void yyerror(const char*msg);
|
||||
|
||||
static void errormsg(const YYLTYPE&loc, const char*msg, ...);
|
||||
int parse_errors = 0;
|
||||
%}
|
||||
|
||||
%union {
|
||||
port_mode_t port_mode;
|
||||
char*text;
|
||||
|
||||
InterfacePort*interface_element;
|
||||
std::list<InterfacePort*>* interface_list;
|
||||
};
|
||||
|
||||
/* The keywords are all tokens. */
|
||||
%token K_abs K_access K_after K_alias K_all K_and K_architecture
|
||||
%token K_array K_assert K_assume K_assume_guarantee K_attribute
|
||||
%token K_begin K_block K_body K_buffer K_bus
|
||||
%token K_case K_component K_configuration K_constant K_context K_cover
|
||||
%token K_default K_disconect K_downto
|
||||
%token K_else K_elsif K_end K_entity K_exit
|
||||
%token K_fairness K_file K_for K_force K_function
|
||||
%token K_generate K_generic K_group K_guarded
|
||||
%token K_if K_impure K_in K_internal K_inout K_is
|
||||
%token K_label K_library K_linkage K_literal K_loop
|
||||
%token K_map K_mod
|
||||
%token K_nand K_new K_next K_nor K_not K_null
|
||||
%token K_of K_on K_open K_or K_others K_out
|
||||
%token K_package K_parameter K_port K_postponed K_procedure K_process
|
||||
%token K_property K_protected K_pure
|
||||
%token K_range K_record K_register K_reject K_release K_rem K_report
|
||||
%token K_restrict K_restrict_guarantee K_return K_rol K_ror
|
||||
%token K_select K_sequence K_seerity K_signal K_shared
|
||||
%token K_sla K_sll K_sra K_srl K_string K_subtype
|
||||
%token K_then K_to K_transport K_type
|
||||
%token K_unaffected K_units K_until K_use
|
||||
%token K_variable K_vmode K_vprop K_vunit
|
||||
%token K_wait K_when K_while K_with
|
||||
%token K_xnor K_xor
|
||||
/* Identifiers that are not keywords are identifiers. */
|
||||
%token <text> IDENTIFIER
|
||||
/* compound symbols */
|
||||
%token LEQ GEQ VASSIGN
|
||||
|
||||
/* The rules may have types. */
|
||||
%type <interface_element> interface_element
|
||||
%type <interface_list> interface_list entity_header port_clause
|
||||
%type <port_mode> mode
|
||||
|
||||
%%
|
||||
|
||||
/* The design_file is the root for the VHDL parse. */
|
||||
design_file : design_units ;
|
||||
|
||||
architecture_body
|
||||
: K_architecture IDENTIFIER
|
||||
K_of IDENTIFIER
|
||||
K_is
|
||||
K_begin architecture_statement_part K_end K_architecture_opt ';'
|
||||
| K_architecture IDENTIFIER
|
||||
K_of IDENTIFIER
|
||||
K_is
|
||||
K_begin error K_end K_architecture_opt ';'
|
||||
{ errormsg(@1, "Syntax error in architecture statement.\n"); yyerrok; }
|
||||
| K_architecture error ';'
|
||||
{ errormsg(@1, "Syntax error in architecture body.\n"); yyerrok; }
|
||||
;
|
||||
|
||||
/* The architecture_statement_part is a list of concurrent
|
||||
statements. */
|
||||
architecture_statement_part
|
||||
: architecture_statement_part concurrent_statement
|
||||
| concurrent_statement
|
||||
;
|
||||
|
||||
concurrent_signal_assignment_statement
|
||||
: IDENTIFIER LEQ waveform ';'
|
||||
;
|
||||
|
||||
concurrent_statement
|
||||
: concurrent_signal_assignment_statement
|
||||
;
|
||||
|
||||
context_clause : context_items | ;
|
||||
|
||||
context_item
|
||||
: library_clause
|
||||
| use_clause
|
||||
;
|
||||
|
||||
context_items
|
||||
: context_items context_item
|
||||
| context_item
|
||||
;
|
||||
|
||||
|
||||
design_unit
|
||||
: context_clause library_unit
|
||||
| error { errormsg(@1, "Invalid design_unit\n"); }
|
||||
;
|
||||
|
||||
design_units
|
||||
: design_units design_unit
|
||||
| design_unit
|
||||
;
|
||||
|
||||
/* As an entity is declared, add it to the map of design entities. */
|
||||
entity_declaration
|
||||
: K_entity IDENTIFIER K_is entity_header K_end K_entity ';'
|
||||
{ Entity*tmp = new Entity;
|
||||
FILE_NAME(tmp, @1);
|
||||
// Store the name
|
||||
tmp->name = lex_strings.make($2);
|
||||
delete[]$2;
|
||||
// Transfer the ports
|
||||
std::list<InterfacePort*>*ports = $4;
|
||||
while (ports->size() > 0) {
|
||||
tmp->ports.push_back(ports->front());
|
||||
ports->pop_front();
|
||||
}
|
||||
delete ports;
|
||||
// Save the entity in the entity map.
|
||||
design_entities[tmp->name] = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
entity_header
|
||||
: port_clause
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
expression
|
||||
: expression_logical
|
||||
;
|
||||
|
||||
expression_logical
|
||||
: relation K_and relation
|
||||
| relation K_or relation
|
||||
;
|
||||
|
||||
factor : primary ;
|
||||
|
||||
/* The interface_element is also an interface_declaration */
|
||||
interface_element
|
||||
: IDENTIFIER ':' mode IDENTIFIER
|
||||
{ InterfacePort*tmp = new InterfacePort;
|
||||
FILE_NAME(tmp, @1);
|
||||
tmp->mode = $3;
|
||||
tmp->name = lex_strings.make($1);
|
||||
tmp->type_name = lex_strings.make($4);
|
||||
delete[]$1;
|
||||
delete[]$4;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
interface_list
|
||||
: interface_list ';' interface_element
|
||||
{ std::list<InterfacePort*>*tmp = $1;
|
||||
tmp->push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
| interface_element
|
||||
{ std::list<InterfacePort*>*tmp = new std::list<InterfacePort*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
library_clause
|
||||
: K_library logical_name_list ';'
|
||||
| K_library error ';'
|
||||
{ errormsg(@1, "Syntax error in library clause.\n"); yyerrok; }
|
||||
;
|
||||
|
||||
/* Collapse the primary_unit and secondary_unit of the library_unit
|
||||
into this single set of rules. */
|
||||
library_unit
|
||||
: entity_declaration
|
||||
| architecture_body
|
||||
;
|
||||
|
||||
logical_name : IDENTIFIER ;
|
||||
|
||||
logical_name_list
|
||||
: logical_name_list ',' logical_name
|
||||
| logical_name
|
||||
;
|
||||
|
||||
mode
|
||||
: K_in { $$ = PORT_IN; }
|
||||
| K_out { $$ = PORT_OUT; }
|
||||
;
|
||||
|
||||
port_clause
|
||||
: K_port '(' interface_list ')' ';'
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
primary
|
||||
: IDENTIFIER
|
||||
;
|
||||
|
||||
relation : shift_expression ;
|
||||
|
||||
selected_name
|
||||
: IDENTIFIER '.' K_all
|
||||
| IDENTIFIER '.' IDENTIFIER '.' K_all
|
||||
;
|
||||
|
||||
selected_names
|
||||
: selected_names ',' selected_name
|
||||
| selected_name
|
||||
;
|
||||
|
||||
shift_expression : simple_expression ;
|
||||
|
||||
simple_expression : term ;
|
||||
|
||||
term : factor ;
|
||||
|
||||
use_clause
|
||||
: K_use selected_names ';'
|
||||
| K_use error ';'
|
||||
{ errormsg(@1, "Syntax error in use clause.\n"); yyerrok; }
|
||||
;
|
||||
|
||||
waveform
|
||||
: waveform_elements
|
||||
| K_unaffected
|
||||
;
|
||||
|
||||
waveform_elements
|
||||
: waveform_elements ',' waveform_element
|
||||
| waveform_element
|
||||
;
|
||||
|
||||
waveform_element
|
||||
: expression
|
||||
| K_null
|
||||
;
|
||||
|
||||
/* Some keywords are optional in some contexts. In all such cases, a
|
||||
similar rule is used, as described here. */
|
||||
K_architecture_opt : K_architecture | ;
|
||||
|
||||
%%
|
||||
|
||||
static void yyerror(const char*msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
parse_errors += 1;
|
||||
}
|
||||
|
||||
static const char*file_path = "";
|
||||
|
||||
static void errormsg(const YYLTYPE&loc, const char*fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
fprintf(stderr, "%s:%d: ", file_path, loc.first_line);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
parse_errors += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used only by the lexor, to set the file path used in error
|
||||
* messages.
|
||||
*/
|
||||
void yyparse_set_filepath(const char*path)
|
||||
{
|
||||
file_path = path;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef __parse_api_H
|
||||
#define __parse_api_H
|
||||
/*
|
||||
* Copyright (c) 2011 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 <cstdio>
|
||||
# include "entity.h"
|
||||
|
||||
/*
|
||||
* The vlltype supports the passing of detailed source file location
|
||||
* information between the lexical analyzer and the parser. Defining
|
||||
* YYLTYPE compels the lexor to use this type and not something other.
|
||||
*/
|
||||
struct yyltype {
|
||||
unsigned first_line;
|
||||
unsigned first_column;
|
||||
unsigned last_line;
|
||||
unsigned last_column;
|
||||
const char*text;
|
||||
};
|
||||
# define YYLTYPE struct yyltype
|
||||
|
||||
/*
|
||||
* The reset_lexor function takes the fd and makes it the input file
|
||||
* for the lexor. The path argument is used in lexor/parser error messages.
|
||||
*/
|
||||
extern void reset_lexor(FILE*fd, const char*path);
|
||||
|
||||
extern int yylex(void);
|
||||
|
||||
extern int yyparse(void);
|
||||
|
||||
/*
|
||||
* Set this to a non-zero value to enable parser debug output.
|
||||
*/
|
||||
extern int yydebug;
|
||||
|
||||
/*
|
||||
* The parser counts the errors that is handed in the parse_errors
|
||||
* variable. For a clean compile, this value should not change. (The
|
||||
* caller sets its initial value.)
|
||||
*/
|
||||
extern int parse_errors;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef __parse_wrap_H
|
||||
#define __parse_wrap_H
|
||||
/*
|
||||
* Copyright (c) 2011 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 header wraps the parse.h header file that is generated from
|
||||
* the parse.y source file. This is used to include definitions that
|
||||
* are needed by the parse type, etc.
|
||||
*/
|
||||
|
||||
# include <list>
|
||||
# include "parse.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __vhdlpp_config_H /* -*- c++ -*- */
|
||||
#define __vhdlpp_config_H
|
||||
/*
|
||||
* Copyright (c) 2011 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
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# if !defined(__GNUC__)
|
||||
using namespace std;
|
||||
# elif (__GNUC__ == 3)
|
||||
using namespace std;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# undef HAVE_GETOPT_H
|
||||
# undef HAVE_INTTYPES_H
|
||||
# undef HAVE_LIBIBERTY_H
|
||||
# undef HAVE_FCHMOD
|
||||
# undef HAVE_SYS_WAIT_H
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#endif /* __config_H */
|
||||
Loading…
Reference in New Issue