mirror of
https://github.com/verilator/verilator.git
synced 2026-10-05 17:43:31 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f21385e41 | ||
|
|
94fed93f54 | ||
|
|
a950e4816d | ||
|
|
c87c66efb1 | ||
|
|
5a5a0006fe | ||
|
|
60b48a6830 | ||
|
|
5e41350588 | ||
|
|
ff9f5b62ac | ||
|
|
882913f0ca | ||
|
|
2062f7e97b | ||
|
|
445c83a60d | ||
|
|
1891cfd79a | ||
|
|
06d5a7b2bf | ||
|
|
5af8a8aa4c | ||
|
|
dc6b085d8b | ||
|
|
00759f777e | ||
|
|
95ac0e61b2 | ||
|
|
6c5884853f | ||
|
|
7578ef889f | ||
|
|
da254af8d5 | ||
|
|
98123dc422 | ||
|
|
466909b3d9 | ||
|
|
0d4305192a | ||
|
|
9e61b9f696 | ||
|
|
491539ff32 | ||
|
|
4c29a13a6e | ||
|
|
b66e1bdb9e | ||
|
|
7312de6bc2 | ||
|
|
1d6bcda014 | ||
|
|
5a747bad7d | ||
|
|
9542783a7e | ||
|
|
a59639413d | ||
|
|
d5eb92a071 | ||
|
|
994cde57af | ||
|
|
238a5809bf | ||
|
|
49fa65c0dd | ||
|
|
49123f169c | ||
|
|
4dc64c387f | ||
|
|
98a63711dd | ||
|
|
cb95cf4745 | ||
|
|
acd48fa61d | ||
|
|
cb7abcbaea |
@@ -24,3 +24,4 @@ internals.txt
|
||||
verilator.txt
|
||||
verilator_bin*
|
||||
verilator_coverage_bin*
|
||||
verilator.pc
|
||||
|
||||
@@ -3,6 +3,60 @@ Revision history for Verilator
|
||||
The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.876 2015-08-12
|
||||
|
||||
*** Add tracing_on, etc to vlt files, bug932. [Frederic Requin]
|
||||
|
||||
**** Support extraction of enum bits, bug951. [Jonathon Donaldson]
|
||||
|
||||
**** Fix MinGW compiler error, bug927, bug929. [Hans Tichelaar]
|
||||
|
||||
**** Fix .c files to be treated as .cpp, bug930. [Jonathon Donaldson]
|
||||
|
||||
**** Fix string-to-int space conversion, bug931. [Fabrizio Ferrandi]
|
||||
|
||||
**** Fix dpi imports inside generates. [Michael Tresidder]
|
||||
|
||||
**** Fix rounding in trace $timescale, bug946. [Frederic Requin]
|
||||
|
||||
**** Fix $fopen with SV string, bug947. [Sven Stucki]
|
||||
|
||||
**** Fix hashed error with typedef inside block, bug948. [Sven Stucki]
|
||||
|
||||
**** Fix makefile with --coverage, bug953. [Eivind Liland]
|
||||
|
||||
**** Fix coverage documentation, bug954. [Thomas J Whatson]
|
||||
|
||||
**** Fix parameters with function parameter arguments, bug952. [Jie Xu]
|
||||
|
||||
**** Fix size casts as second argument of cast item, bug950. [Jonathon Donaldson]
|
||||
|
||||
|
||||
* Verilator 3.874 2015-06-06
|
||||
|
||||
*** Add pkg-config .pc file, bug919. [Stefan Wallentowitz]
|
||||
|
||||
**** Fix installing missing manpages, bug908. [Ahmed El-Mahmoudy]
|
||||
|
||||
**** Fix sign extension in large localparams, bug910. [Mike Thyer]
|
||||
|
||||
**** Fix core dump in sync-async warnings, bug911. [Sebastian Dressler]
|
||||
|
||||
**** Fix truncation warning with -pins-bv, bug912. [Alfonso Martinez]
|
||||
|
||||
**** Fix Cygwin uint32 compile, bug914. [Matthew Barr]
|
||||
|
||||
**** Fix preprocessing stringified newline escapes, bug915. [Anton Rapp]
|
||||
|
||||
**** Fix part-select in constant function, bug916. [Andrew Bardsley]
|
||||
|
||||
**** Fix width extension on mis-width ports, bug918. [Patrick Maupin]
|
||||
|
||||
**** Fix width propagation on sized casts, bug925. [Jonathon Donaldson]
|
||||
|
||||
**** Fix MSVC++ compiler error, bug927. [Hans Tichelaar]
|
||||
|
||||
|
||||
* Verilator 3.872 2015-04-05
|
||||
|
||||
*** Add VerilatedVcdFile to allow real-time waveforms, bug890. [HyungKi Jeong]
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
.*\.tex
|
||||
.*\.key
|
||||
.*\.vcd
|
||||
.*\.1
|
||||
/obj_dir/
|
||||
/obj_dbg/
|
||||
/obj_opt/
|
||||
@@ -27,6 +28,7 @@ config.cache$
|
||||
config.status$
|
||||
verilator.log
|
||||
verilator.tex
|
||||
verilator.pc$
|
||||
verilator_bin.*
|
||||
verilator_coverage_bin.*
|
||||
.vcsmx_rebuild$
|
||||
|
||||
+14
-9
@@ -84,6 +84,10 @@ infodir = @infodir@
|
||||
# Generally ${prefix}/share/verilator
|
||||
pkgdatadir = @pkgdatadir@
|
||||
|
||||
# Directory in which to install pkgconfig file
|
||||
# Generall ${prefix}/share/pkgconfig
|
||||
pkgconfigdir = @pkgconfigdir@
|
||||
|
||||
# Directory in which to install data across multiple architectures
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
@@ -101,8 +105,8 @@ SHELL = /bin/sh
|
||||
SUBDIRS = src test_verilated test_c test_sc test_regress
|
||||
|
||||
INFOS = README README.html README.pdf internals.txt internals.html \
|
||||
internals.pdf verilator.txt verilator.html verilator.1 verilator.pdf \
|
||||
verilator_coverage.1
|
||||
internals.pdf verilator.txt verilator.html verilator.pdf \
|
||||
$(VL_INST_MAN_FILES)
|
||||
|
||||
# Files that can be generated, but should be up to date for a distribution.
|
||||
DISTDEP = info Makefile
|
||||
@@ -207,10 +211,7 @@ test_regress: all_nomsg
|
||||
info: $(INFOS)
|
||||
|
||||
# Use --no-split to avoid creating filenames > 14 chars.
|
||||
verilator.1: ${srcdir}/bin/verilator
|
||||
pod2man $< $@
|
||||
|
||||
verilator_coverage.1: ${srcdir}/bin/verilator_coverage
|
||||
%.1: ${srcdir}/bin/%
|
||||
pod2man $< $@
|
||||
|
||||
verilator.txt: ${srcdir}/bin/verilator
|
||||
@@ -267,7 +268,7 @@ VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage
|
||||
# so they can be found by the user, and under $VERILATOR_ROOT.
|
||||
|
||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_profcfunc.1
|
||||
|
||||
VL_INST_INC_BLDDIR_FILES = \
|
||||
include/verilated.mk \
|
||||
@@ -297,7 +298,7 @@ installbin:
|
||||
# So important we use $< so VPATH is searched
|
||||
installman: $(VL_INST_MAN_FILES)
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
|
||||
for p in $< ; do \
|
||||
for p in $^ ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||
done
|
||||
|
||||
@@ -317,6 +318,8 @@ installdata:
|
||||
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/examples/$$p; \
|
||||
done
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgconfigdir)
|
||||
$(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
|
||||
uninstall:
|
||||
@@ -326,6 +329,7 @@ uninstall:
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_BLDDIR_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir)/examples && rm -f $(VL_INST_DATA_SRCDIR_FILES)
|
||||
-rm $(DESTDIR)$(pkgconfigdir)/verilator.pc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/bin
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include
|
||||
@@ -335,6 +339,7 @@ uninstall:
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_v
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)
|
||||
-rmdir $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
install: all_nomsg install-all
|
||||
install-all: installbin installman installdata install-msg
|
||||
@@ -420,7 +425,7 @@ ftp: info
|
||||
install-msg:
|
||||
@echo "Installed!"
|
||||
@echo
|
||||
@echo "Fod documentation see 'man verilator' or 'verilator --help'"
|
||||
@echo "For documentation see 'man verilator' or 'verilator --help'"
|
||||
@echo "For forums and to report bugs see http://www.veripool.org/verilator"
|
||||
@echo
|
||||
|
||||
|
||||
+34
-14
@@ -1359,6 +1359,7 @@ And link with SystemC. Note your path to the libraries may vary,
|
||||
depending on the operating system.
|
||||
|
||||
export SYSTEMC_LIBDIR=/path/to/where/libsystemc.a/exists
|
||||
export LD_LIBRARY_PATH=$SYSTEMC_LIBDIR:$LD_LIBRARY_PATH
|
||||
# Might be needed if SystemC 2.3.0
|
||||
export SYSTEMC_CXX_FLAGS=-pthread
|
||||
|
||||
@@ -1498,6 +1499,12 @@ After running Make, the C++ compiler should produce the following:
|
||||
|
||||
=over 4
|
||||
|
||||
=item LD_LIBRARY_PATH
|
||||
|
||||
A generic Linux/OS variable specifying what directories have shared object
|
||||
(.so) files. This path should include SystemC and any other shared objects
|
||||
needed at runtime.
|
||||
|
||||
=item OBJCACHE
|
||||
|
||||
Optionally specifies a caching or distribution program to place in front of
|
||||
@@ -1916,30 +1923,40 @@ The grammar of configuration commands is as follows:
|
||||
Take remaining text up the the next `verilog mode switch and treat it as
|
||||
Verilator configuration commands.
|
||||
|
||||
=item coverage_on [-file "<filename>" [-lines <line> [ - <line> ]]]
|
||||
|
||||
=item coverage_off [-file "<filename>" [-lines <line> [ - <line> ]]]
|
||||
|
||||
Disable coverage for the specified filename (or wildcard with '*' or '?',
|
||||
or all files if omitted) and range of line numbers (or all lines if
|
||||
Enable/disable coverage for the specified filename (or wildcard with '*' or
|
||||
'?', or all files if omitted) and range of line numbers (or all lines if
|
||||
omitted). Often used to ignore an entire module for coverage analysis
|
||||
purposes.
|
||||
|
||||
=item lint_on [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
|
||||
|
||||
=item lint_off [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
|
||||
|
||||
Disables the specified lint warning, in the specified filename (or wildcard
|
||||
with '*' or '?', or all files if omitted) and range of line numbers (or all
|
||||
lines if omitted).
|
||||
Enable/disables the specified lint warning, in the specified filename (or
|
||||
wildcard with '*' or '?', or all files if omitted) and range of line
|
||||
numbers (or all lines if omitted).
|
||||
|
||||
Using '*' will override any lint_on directives in the source, i.e. the
|
||||
warning will still not be printed.
|
||||
With lint_off using '*' will override any lint_on directives in the source,
|
||||
i.e. the warning will still not be printed.
|
||||
|
||||
If the -msg is omitted, all lint warnings are disabled. This will override
|
||||
all later lint warning enables for the specified region.
|
||||
If the -msg is omitted, all lint warnings are enabled/disabled. This will
|
||||
override all later lint warning enables for the specified region.
|
||||
|
||||
=item tracing_on [-file "<filename>" [-lines <line> [ - <line> ]]]
|
||||
|
||||
=item tracing_off [-file "<filename>" [-lines <line> [ - <line> ]]]
|
||||
|
||||
Disable waveform tracing for all future signals declared in the specified
|
||||
filename (or wildcard with '*' or '?', or all files if omitted) and range
|
||||
of line numbers (or all lines if omitted).
|
||||
Enable/disable waveform tracing for all future signals declared in the
|
||||
specified filename (or wildcard with '*' or '?', or all files if omitted)
|
||||
and range of line numbers (or all lines if omitted).
|
||||
|
||||
For tracing_off, cells below any module in the files/ranges specified will
|
||||
also not be traced.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
@@ -2887,7 +2904,7 @@ this warning is enabled only if user has explicitly marked some signal as
|
||||
clocker using command line option or in-source meta comment (see C<--clk>).
|
||||
|
||||
The warning can be disabled without affecting the simulation result. But it
|
||||
is recommanded to check the warning as this may degrade the performance of
|
||||
is recommended to check the warning as this may degrade the performance of
|
||||
the Verilated model.
|
||||
|
||||
=item CMPCONST
|
||||
@@ -3556,7 +3573,10 @@ First, run verilator with the --coverage option. If you're using your own
|
||||
makefile, compile the model with the GCC flag -DVM_COVERAGE (if using
|
||||
Verilator's, it will do this for you.)
|
||||
|
||||
Run your tests in different directories. Each test will create a
|
||||
At the end of your test, call VerilatedCov::write passing the name of the
|
||||
coverage data file (typically "logs/coverage.dat").
|
||||
|
||||
Run each of your tests in different directories. Each test will create a
|
||||
logs/coverage.pl file.
|
||||
|
||||
After running all of your tests, verilator_coverage is executed.
|
||||
|
||||
+6
-2
@@ -6,9 +6,11 @@
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.872 2015-04-05])
|
||||
AC_INIT([Verilator],[3.876 2015-08-12])
|
||||
# When releasing, also update header of Changes file
|
||||
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc)
|
||||
|
||||
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||
|
||||
@@ -161,6 +163,8 @@ AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
|
||||
# Other install directories
|
||||
pkgdatadir=${datadir}/verilator
|
||||
AC_SUBST(pkgdatadir)
|
||||
pkgconfigdir=${datadir}/pkgconfig
|
||||
AC_SUBST(pkgconfigdir)
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
@@ -708,8 +708,8 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
|
||||
start = false; // Drop leading 0s
|
||||
}
|
||||
}
|
||||
*destp++ = '\0'; // Terminate
|
||||
while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
|
||||
*destp = '\0'; // Terminate
|
||||
if (!start) while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
|
||||
}
|
||||
|
||||
void _VL_STRING_TO_VINT(int obits, void* destp, int srclen, const char* srcp) {
|
||||
@@ -750,6 +750,11 @@ IData VL_FGETS_IXI(int obits, void* destp, IData fpi) {
|
||||
return got;
|
||||
}
|
||||
|
||||
IData VL_FOPEN_NI(const string& filename, IData mode) {
|
||||
char modez[5];
|
||||
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
|
||||
return VL_FOPEN_S(filename.c_str(), modez);
|
||||
}
|
||||
IData VL_FOPEN_QI(QData filename, IData mode) {
|
||||
IData fnw[2]; VL_SET_WQ(fnw, filename);
|
||||
return VL_FOPEN_WI(2, fnw, mode);
|
||||
|
||||
+4
-3
@@ -357,6 +357,7 @@ extern IData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||
extern IData VL_FOPEN_QI(QData ofilename, IData mode);
|
||||
inline IData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
||||
|
||||
|
||||
extern void VL_FCLOSE_I(IData fdi);
|
||||
|
||||
extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
@@ -594,13 +595,13 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
|
||||
|
||||
#define VL_ASSIGN_SWI(obits,svar,rd) { \
|
||||
sc_bv<obits> _bvtemp; \
|
||||
_bvtemp.set_word(0,rd); \
|
||||
_bvtemp.set_word(0,(rd)); \
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_SWQ(obits,svar,rd) { \
|
||||
sc_bv<obits> _bvtemp; \
|
||||
_bvtemp.set_word(0,rd); \
|
||||
_bvtemp.set_word(1,rd>>VL_WORDSIZE); \
|
||||
_bvtemp.set_word(0,(IData)(rd)); \
|
||||
_bvtemp.set_word(1,(IData)((rd)>>VL_WORDSIZE)); \
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_SWW(obits,svar,rwp) { \
|
||||
|
||||
@@ -120,10 +120,6 @@ ifeq ($(VM_SP),1)
|
||||
$(SP_PREPROC) -M sp_preproc.d --tree $(VM_PREFIX).sp_tree \
|
||||
--preproc $(VK_CLASSES_SP)
|
||||
else
|
||||
ifeq ($(VM_COVERAGE),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
endif
|
||||
preproc:
|
||||
endif
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ inline string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const string& lhs
|
||||
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
|
||||
}
|
||||
|
||||
extern IData VL_FOPEN_NI(const string& filename, IData mode);
|
||||
extern IData VL_SSCANF_INX(int lbits, const string& ld, const char* formatp, ...);
|
||||
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
|
||||
extern string VL_SFORMATF_NX(const char* formatp, ...);
|
||||
|
||||
@@ -378,7 +378,7 @@ string VerilatedVcd::doubleToTimescale (double value) {
|
||||
else if (value>=1e-12) { suffixp="ps"; value *= 1e12; }
|
||||
else if (value>=1e-15) { suffixp="fs"; value *= 1e15; }
|
||||
else if (value>=1e-18) { suffixp="as"; value *= 1e18; }
|
||||
char valuestr[100]; sprintf(valuestr,"%d%s",(int)(value), suffixp);
|
||||
char valuestr[100]; sprintf(valuestr,"%3.0f%s", value, suffixp);
|
||||
return valuestr; // Gets converted to string, so no ref to stack
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ public:
|
||||
do { \
|
||||
va_list args; \
|
||||
va_start(args, message); \
|
||||
vsnprintf(m_buff, sizeof(m_buff), message.c_str(), args); \
|
||||
VL_VSNPRINTF(m_buff, sizeof(m_buff), message.c_str(), args); \
|
||||
va_end(args); \
|
||||
} while (0)
|
||||
|
||||
@@ -920,10 +920,10 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
|
||||
value_p->value.str = outStr;
|
||||
switch (vop->varp()->vltype()) {
|
||||
// outStrSz does not include NULL termination so add one
|
||||
case VLVT_UINT8 : snprintf(outStr, outStrSz+1, "%hhu", (unsigned char )*((CData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT16: snprintf(outStr, outStrSz+1, "%hu", (unsigned short)*((SData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT32: snprintf(outStr, outStrSz+1, "%u", (unsigned int )*((IData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT64: snprintf(outStr, outStrSz+1, "%llu", (unsigned long long)*((QData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT8 : VL_SNPRINTF(outStr, outStrSz+1, "%hhu", (unsigned char )*((CData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT16: VL_SNPRINTF(outStr, outStrSz+1, "%hu", (unsigned short)*((SData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT32: VL_SNPRINTF(outStr, outStrSz+1, "%u", (unsigned int )*((IData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT64: VL_SNPRINTF(outStr, outStrSz+1, "%llu", (unsigned long long)*((QData*)(vop->varDatap()))); return;
|
||||
default:
|
||||
strcpy(outStr, "-1");
|
||||
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s, maximum limit is 64 bits",
|
||||
|
||||
+13
-1
@@ -139,7 +139,7 @@ typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward comp
|
||||
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||
# ifdef __uint32_t_defined // Newer Cygwin uint32_t in stdint.h as an unsigned int
|
||||
# if defined(__uint32_t_defined) || defined(___int32_t_defined) // Newer Cygwin uint32_t in stdint.h as an unsigned int
|
||||
typedef int32_t vlsint32_t; ///< 32-bit signed type
|
||||
typedef uint32_t vluint32_t; ///< 32-bit unsigned type
|
||||
# else // Older Cygwin has long==uint32_t
|
||||
@@ -207,6 +207,18 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
# if (_MSC_VER < 1900)
|
||||
# define VL_SNPRINTF _snprintf
|
||||
# else
|
||||
# define VL_SNPRINTF snprintf
|
||||
# endif
|
||||
# define VL_VSNPRINTF vsnprintf
|
||||
#else
|
||||
# define VL_SNPRINTF snprintf
|
||||
# define VL_VSNPRINTF vsnprintf
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// File system functions
|
||||
|
||||
|
||||
+3
-1
@@ -239,6 +239,7 @@ public:
|
||||
//
|
||||
DT_PUBLIC, // V3LinkParse moves to AstTypedef::attrPublic
|
||||
//
|
||||
ENUM_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
|
||||
ENUM_FIRST, // V3Width processes
|
||||
ENUM_LAST, // V3Width processes
|
||||
ENUM_NUM, // V3Width processes
|
||||
@@ -268,7 +269,7 @@ public:
|
||||
"DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT",
|
||||
"DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS",
|
||||
"DT_PUBLIC",
|
||||
"ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME",
|
||||
"ENUM_BASE", "ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME",
|
||||
"MEMBER_BASE",
|
||||
"VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
|
||||
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
|
||||
@@ -1079,6 +1080,7 @@ public:
|
||||
//TODO stomp these width functions out, and call via dtypep() instead
|
||||
int width() const;
|
||||
int widthMin() const;
|
||||
int widthMinV() const { return v3Global.widthMinUsage()==VWidthMinUsage::VERILOG_WIDTH ? widthMin() : width(); }
|
||||
int widthWords() const { return VL_WORDS_I(width()); }
|
||||
bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); }
|
||||
bool isWide() const { return (width()>VL_QUADSIZE); }
|
||||
|
||||
+4
-22
@@ -506,9 +506,9 @@ string AstScope::nameDotless() const {
|
||||
return out;
|
||||
}
|
||||
|
||||
string AstScopeName::scopePrettyName() const {
|
||||
string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
|
||||
string out;
|
||||
for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) {
|
||||
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
|
||||
out += textp->text();
|
||||
}
|
||||
// TOP will be replaced by top->name()
|
||||
@@ -518,27 +518,9 @@ string AstScopeName::scopePrettyName() const {
|
||||
return AstNode::prettyName(out);
|
||||
}
|
||||
|
||||
string AstScopeName::scopeSymName() const {
|
||||
string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
|
||||
string out;
|
||||
for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) {
|
||||
out += textp->text();
|
||||
}
|
||||
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
|
||||
if (out.substr(0,7) == "__DOT__") out.replace(0,7,"");
|
||||
if (out.substr(0,1) == ".") out.replace(0,1,"");
|
||||
string::size_type pos;
|
||||
while ((pos=out.find(".")) != string::npos) {
|
||||
out.replace(pos, 1, "__");
|
||||
}
|
||||
while ((pos=out.find("__DOT__")) != string::npos) {
|
||||
out.replace(pos, 7, "__");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
string AstScopeName::scopeDpiName() const {
|
||||
string out;
|
||||
for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) {
|
||||
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
|
||||
out += textp->text();
|
||||
}
|
||||
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
|
||||
|
||||
+11
-6
@@ -103,7 +103,7 @@ public:
|
||||
return num().isCaseEq(samep->castConst()->num()); }
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
bool isEqAllOnes() const { return num().isEqAllOnes(width()); }
|
||||
bool isEqAllOnesV() const { return num().isEqAllOnes(widthMin()); }
|
||||
bool isEqAllOnesV() const { return num().isEqAllOnes(widthMinV()); }
|
||||
};
|
||||
|
||||
class AstRange : public AstNode {
|
||||
@@ -3067,6 +3067,8 @@ class AstScopeName : public AstNodeMath {
|
||||
// Children: TEXT
|
||||
private:
|
||||
bool m_dpiExport; // Is for dpiExport
|
||||
string scopeNameFormatter(AstText* textp) const;
|
||||
string scopePrettyNameFormatter(AstText* textp) const;
|
||||
public:
|
||||
AstScopeName(FileLine* fl) : AstNodeMath(fl), m_dpiExport(false) {
|
||||
dtypeSetUInt64(); }
|
||||
@@ -3080,9 +3082,10 @@ public:
|
||||
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
|
||||
AstText* scopeEntrp() const { return op2p()->castText(); }
|
||||
void scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
|
||||
string scopeSymName() const; // Name for __Vscope variable including children
|
||||
string scopeDpiName() const; // Name for DPI import scope
|
||||
string scopePrettyName() const; // Name for __Vscope printing
|
||||
string scopeSymName() const { return scopeNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
|
||||
string scopeDpiName() const { return scopeNameFormatter(scopeEntrp()); } // Name for DPI import scope
|
||||
string scopePrettySymName() const { return scopePrettyNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
|
||||
string scopePrettyDpiName() const { return scopePrettyNameFormatter(scopeEntrp()); } // Name for __Vscope variable including children
|
||||
bool dpiExport() const { return m_dpiExport; }
|
||||
void dpiExport(bool flag) { m_dpiExport=flag; }
|
||||
};
|
||||
@@ -3310,7 +3313,8 @@ public:
|
||||
dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); }
|
||||
ASTNODE_NODE_FUNCS(ExtendS, EXTENDS)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||
out.opExtendS(lhs, lhsp()->widthMin()); }
|
||||
out.opExtendS(lhs, lhsp()->widthMinV());
|
||||
}
|
||||
virtual string emitVerilog() { return "%l"; }
|
||||
virtual string emitC() { return "VL_EXTENDS_%nq%lq(%nw,%lw, %P, %li)"; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
||||
@@ -3510,6 +3514,7 @@ public:
|
||||
setOp1p(lhsp); setOp2p(rhsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(CastSize, CASTSIZE)
|
||||
// No hasDType because widthing removes this node before the hasDType check
|
||||
virtual string emitVerilog() { return "((%r)'(%l))"; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;}
|
||||
@@ -4150,7 +4155,7 @@ public:
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ShiftRS, SHIFTRS)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
|
||||
out.opShiftRS(lhs,rhs,lhsp()->widthMin()); }
|
||||
out.opShiftRS(lhs,rhs,lhsp()->widthMinV()); }
|
||||
virtual string emitVerilog() { return "%k(%l %f>>> %r)"; }
|
||||
virtual string emitC() { return "VL_SHIFTRS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
|
||||
+8
-11
@@ -204,6 +204,12 @@ public:
|
||||
|
||||
class BrokenCheckVisitor : public AstNVisitor {
|
||||
private:
|
||||
void checkWidthMin(AstNode* nodep) {
|
||||
if (nodep->width() != nodep->widthMin()
|
||||
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH) {
|
||||
nodep->v3fatalSrc("Width != WidthMin");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
BrokenTable::setUnder(nodep,true);
|
||||
if (const char* whyp=nodep->broken()) {
|
||||
@@ -220,18 +226,9 @@ private:
|
||||
if (nodep->dtypep()) nodep->v3fatalSrc("DType on node without hasDType(): "<<nodep->prettyTypeName());
|
||||
}
|
||||
if (nodep->getChildDTypep()) nodep->v3fatalSrc("childDTypep() non-null on node after should have removed");
|
||||
if (AstNodeDType* dnodep = nodep->castNodeDType()) {
|
||||
if (dnodep->width() != dnodep->widthMin()
|
||||
&& v3Global.assertWidthsMatch()) {
|
||||
dnodep->v3fatalSrc("Width != WidthMin");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v3Global.assertWidthsMatch()) {
|
||||
if (nodep->width() != nodep->widthMin()) {
|
||||
nodep->v3fatalSrc("Width != WidthMin");
|
||||
}
|
||||
if (AstNodeDType* dnodep = nodep->castNodeDType()) checkWidthMin(dnodep);
|
||||
}
|
||||
checkWidthMin(nodep);
|
||||
nodep->iterateChildrenConst(*this);
|
||||
BrokenTable::setUnder(nodep,false);
|
||||
}
|
||||
|
||||
+4
-4
@@ -144,12 +144,12 @@ V3ConfigIgnores V3ConfigIgnores::s_singleton;
|
||||
//######################################################################
|
||||
// V3Config
|
||||
|
||||
void V3Config::addIgnore(V3ErrorCode code, string filename, int min, int max) {
|
||||
void V3Config::addIgnore(V3ErrorCode code, bool on, string filename, int min, int max) {
|
||||
if (filename=="*") {
|
||||
FileLine::globalWarnOff(code,true);
|
||||
FileLine::globalWarnOff(code,!on);
|
||||
} else {
|
||||
V3ConfigIgnores::singleton().addIgnore(code, filename, min, false);
|
||||
if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, true);
|
||||
V3ConfigIgnores::singleton().addIgnore(code, filename, min, on);
|
||||
if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, !on);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
|
||||
class V3Config {
|
||||
public:
|
||||
static void addIgnore(V3ErrorCode code, string filename, int min, int max);
|
||||
static void addIgnore(V3ErrorCode code, bool on, string filename, int min, int max);
|
||||
static void applyIgnores(FileLine* filelinep);
|
||||
};
|
||||
|
||||
|
||||
+4
-4
@@ -1351,7 +1351,7 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
|
||||
case 'g': displayArg(nodep,&elistp,isScan, vfmt,'g'); break;
|
||||
case 'm': {
|
||||
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
||||
string suffix = scopenamep->scopePrettyName();
|
||||
string suffix = scopenamep->scopePrettySymName();
|
||||
if (suffix=="") emitDispState.pushFormat("%S");
|
||||
else emitDispState.pushFormat("%N"); // Add a . when needed
|
||||
emitDispState.pushArg(' ',NULL, "vlSymsp->name()");
|
||||
@@ -1563,12 +1563,12 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
|
||||
VHashFnv hash;
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
hash.hash(varp->name());
|
||||
hash.hash(varp->dtypep()->width());
|
||||
hash.insert(varp->name());
|
||||
hash.insert(varp->dtypep()->width());
|
||||
}
|
||||
}
|
||||
ofp()->printf( "vluint64_t __Vcheckval = VL_ULL(0x%" VL_PRI64 "x);\n",
|
||||
hash.value());
|
||||
hash.digestUInt64());
|
||||
if (de) {
|
||||
puts("os.readAssert(__Vcheckval);\n");
|
||||
} else {
|
||||
|
||||
+6
-2
@@ -193,14 +193,18 @@ class EmitCSyms : EmitCBaseVisitor {
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
string name = nodep->scopeSymName();
|
||||
//UINFO(9,"scnameins sp "<<nodep->name()<<" sp "<<nodep->scopePrettyName()<<" ss "<<name<<endl);
|
||||
//UINFO(9,"scnameins sp "<<nodep->name()<<" sp "<<nodep->scopePrettySymName()<<" ss "<<name<<endl);
|
||||
if (m_scopeNames.find(name) == m_scopeNames.end()) {
|
||||
m_scopeNames.insert(make_pair(name, ScopeNameData(name, nodep->scopePrettyName())));
|
||||
m_scopeNames.insert(make_pair(name, ScopeNameData(name, nodep->scopePrettySymName())));
|
||||
}
|
||||
if (nodep->dpiExport()) {
|
||||
if (!m_funcp) nodep->v3fatalSrc("ScopeName not under DPI function");
|
||||
m_scopeFuncs.insert(make_pair(name + " " + m_funcp->name(),
|
||||
ScopeFuncData(nodep, m_funcp, m_modp)));
|
||||
} else {
|
||||
if (m_scopeNames.find(nodep->scopeDpiName()) == m_scopeNames.end()) {
|
||||
m_scopeNames.insert(make_pair(nodep->scopeDpiName(), ScopeNameData(nodep->scopeDpiName(), nodep->scopePrettyDpiName())));
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
|
||||
@@ -345,6 +345,7 @@ private:
|
||||
while (!m_readEof && (size<0 || size>sizegot)) {
|
||||
ssize_t todo = INFILTER_IPC_BUFSIZ;
|
||||
if (size>0 && size<todo) todo = size;
|
||||
errno = 0;
|
||||
ssize_t got = read (fd, buf, todo);
|
||||
//UINFO(9,"RD GOT g "<< got<<" e "<<errno<<" "<<strerror(errno)<<endl); usleep(50*1000);
|
||||
if (got>0) {
|
||||
@@ -384,6 +385,7 @@ private:
|
||||
if (!m_pid) { v3error("--pipe-filter: write to closed file\n"); m_readEof = true; stop(); }
|
||||
unsigned offset = 0;
|
||||
while (!m_readEof && out.length()>offset) {
|
||||
errno = 0;
|
||||
int got = write (m_writeFd, (out.c_str())+offset, out.length()-offset);
|
||||
//UINFO(9,"WR GOT g "<< got<<" e "<<errno<<" "<<strerror(errno)<<endl); usleep(50*1000);
|
||||
if (got>0) offset += got;
|
||||
|
||||
+2
-2
@@ -362,6 +362,7 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
//if (debug()>6) m_graph.dump();
|
||||
if (debug()>6) m_graph.dumpDotFilePrefixed("gate_pre");
|
||||
warnSignals(); // Before loss of sync/async pointers
|
||||
m_graph.removeRedundantEdgesSum(&V3GraphEdge::followAlwaysTrue);
|
||||
m_graph.dumpDotFilePrefixed("gate_simp");
|
||||
// Find gate interconnect and optimize
|
||||
@@ -373,8 +374,7 @@ private:
|
||||
// Remove redundant logic
|
||||
if (v3Global.opt.oDedupe()) dedupe();
|
||||
if (v3Global.opt.oAssemble()) mergeAssigns();
|
||||
// Warn
|
||||
warnSignals();
|
||||
// Consumption warnings
|
||||
consumedMark();
|
||||
m_graph.dumpDotFilePrefixed("gate_opt");
|
||||
// Rewrite assignments
|
||||
|
||||
+25
-5
@@ -36,15 +36,35 @@ class AstNetlist;
|
||||
|
||||
|
||||
//######################################################################
|
||||
// V3 - The top level class for the entire program
|
||||
|
||||
class VWidthMinUsage {
|
||||
public:
|
||||
enum en {
|
||||
LINT_WIDTH,
|
||||
MATCHES_WIDTH,
|
||||
VERILOG_WIDTH
|
||||
};
|
||||
enum en m_e;
|
||||
inline VWidthMinUsage () : m_e(LINT_WIDTH) {}
|
||||
inline VWidthMinUsage (en _e) : m_e(_e) {}
|
||||
explicit inline VWidthMinUsage (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
};
|
||||
inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (VWidthMinUsage::en lhs, VWidthMinUsage rhs) { return (lhs == rhs.m_e); }
|
||||
|
||||
//######################################################################
|
||||
// V3Global - The top level class for the entire program
|
||||
|
||||
class V3Global {
|
||||
// Globals
|
||||
AstNetlist* m_rootp; // Root of entire netlist
|
||||
VWidthMinUsage m_widthMinUsage; // What AstNode::widthMin() is used for
|
||||
|
||||
int m_debugFileNumber; // Number to append to debug files created
|
||||
int m_assertWidthsMatch; // Tree should have width()==widthMin()
|
||||
bool m_assertDTypesResolved; // Tree should have dtypep()'s
|
||||
bool m_assertWidthsMatch; // Tree should have width()==widthMin()
|
||||
bool m_constRemoveXs; // Const needs to strip any Xs
|
||||
bool m_needHInlines; // Need __Inlines file
|
||||
bool m_needHeavy; // Need verilated_heavy.h include
|
||||
@@ -58,8 +78,8 @@ public:
|
||||
// CREATORS
|
||||
V3Global() {
|
||||
m_debugFileNumber = 0;
|
||||
m_widthMinUsage = VWidthMinUsage::LINT_WIDTH;
|
||||
m_assertDTypesResolved = false;
|
||||
m_assertWidthsMatch = false;
|
||||
m_constRemoveXs = false;
|
||||
m_needHInlines = false;
|
||||
m_needHeavy = false;
|
||||
@@ -71,15 +91,15 @@ public:
|
||||
void clear();
|
||||
// ACCESSORS (general)
|
||||
AstNetlist* rootp() const { return m_rootp; }
|
||||
VWidthMinUsage widthMinUsage() const { return m_widthMinUsage; }
|
||||
bool assertDTypesResolved() const { return m_assertDTypesResolved; }
|
||||
bool assertWidthsMatch() const { return m_assertWidthsMatch; }
|
||||
|
||||
// METHODS
|
||||
void readFiles();
|
||||
void checkTree();
|
||||
static void dumpCheckGlobalTree(const string& filename, int newNumber=0, bool doDump=true);
|
||||
void assertDTypesResolved(bool flag) { m_assertDTypesResolved = flag; }
|
||||
void assertWidthsMatch(bool flag) { m_assertWidthsMatch = flag; }
|
||||
void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; }
|
||||
bool constRemoveXs() const { return m_constRemoveXs; }
|
||||
void constRemoveXs(bool flag) { m_constRemoveXs = flag; }
|
||||
string debugFilename(const string& nameComment, int newNumber=0) {
|
||||
|
||||
@@ -89,6 +89,7 @@ private:
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstVar*, AstNUser*) {}
|
||||
virtual void visit(AstTypedef*, AstNUser*) {}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
nodeHashIterate(nodep);
|
||||
}
|
||||
|
||||
+97
-71
@@ -239,81 +239,107 @@ public:
|
||||
virtual ~InstDeVisitor() {}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Inst static function
|
||||
|
||||
class InstStatic {
|
||||
private:
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
InstStatic() {} // Static class
|
||||
|
||||
static AstNode* extendOrSel(FileLine* fl, AstNode* rhsp, AstNode* cmpWidthp) {
|
||||
if (cmpWidthp->width() > rhsp->width()) {
|
||||
rhsp = (rhsp->isSigned()
|
||||
? (new AstExtendS(fl, rhsp))->castNode()
|
||||
: (new AstExtend (fl, rhsp))->castNode());
|
||||
rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above
|
||||
} else if (cmpWidthp->width() < rhsp->width()) {
|
||||
rhsp = new AstSel (fl, rhsp, 0, cmpWidthp->width());
|
||||
rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above
|
||||
}
|
||||
// else don't change dtype, as might be e.g. array of something
|
||||
return rhsp;
|
||||
}
|
||||
|
||||
public:
|
||||
static AstAssignW* pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule*,
|
||||
bool forTristate, bool alwaysCvt) {
|
||||
// If a pin connection is "simple" leave it as-is
|
||||
// Else create a intermediate wire to perform the interconnect
|
||||
// Return the new assignment, if one was made
|
||||
// Note this module calles cloneTree() via new AstVar
|
||||
AstVar* pinVarp = pinp->modVarp();
|
||||
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
|
||||
AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL
|
||||
AstBasicDType* connBasicp = NULL;
|
||||
AstAssignW* assignp = NULL;
|
||||
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp();
|
||||
//
|
||||
if (!alwaysCvt
|
||||
&& connectRefp
|
||||
&& connectRefp->varp()->dtypep()->sameTree(pinVarp->dtypep())
|
||||
&& !connectRefp->varp()->isSc()) { // Need the signal as a 'shell' to convert types
|
||||
// Done. Same data type
|
||||
} else if (!alwaysCvt
|
||||
&& connectRefp
|
||||
&& connectRefp->varp()->isIfaceRef()) {
|
||||
// Done. Interface
|
||||
} else if (!alwaysCvt
|
||||
&& connBasicp
|
||||
&& pinBasicp
|
||||
&& connBasicp->width() == pinBasicp->width()
|
||||
&& connBasicp->lsb() == pinBasicp->lsb()
|
||||
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
|
||||
&& connBasicp->width() == pinVarp->width()
|
||||
&& 1) {
|
||||
// Done. One to one interconnect won't need a temporary variable.
|
||||
} else if (!alwaysCvt && !forTristate && pinp->exprp()->castConst()) {
|
||||
// Done. Constant.
|
||||
} else {
|
||||
// Make a new temp wire
|
||||
//if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); }
|
||||
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
|
||||
string newvarname = ((string)(pinVarp->isOutput() ? "__Vcellout" : "__Vcellinp")
|
||||
+(forTristate?"t":"") // Prevent name conflict if both tri & non-tri add signals
|
||||
+"__"+cellp->name()+"__"+pinp->name());
|
||||
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
|
||||
// Important to add statement next to cell, in case there is a generate with same named cell
|
||||
cellp->addNextHere(newvarp);
|
||||
if (pinVarp->isInout()) {
|
||||
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)");
|
||||
} else if (pinVarp->isOutput()) {
|
||||
// See also V3Inst
|
||||
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
|
||||
UINFO(5,"pinRecon width "<<pinVarp->width()<<" >? "<<rhsp->width()<<" >? "<<pinexprp->width()<<endl);
|
||||
rhsp = extendOrSel (pinp->fileline(), rhsp, pinVarp);
|
||||
pinp->exprp(new AstVarRef (newvarp->fileline(), newvarp, true));
|
||||
AstNode* rhsSelp = extendOrSel (pinp->fileline(), rhsp, pinexprp);
|
||||
assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsSelp);
|
||||
} else {
|
||||
// V3 width should have range/extended to make the widths correct
|
||||
assignp = new AstAssignW (pinp->fileline(),
|
||||
new AstVarRef(pinp->fileline(), newvarp, true),
|
||||
pinexprp);
|
||||
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
|
||||
}
|
||||
if (assignp) cellp->addNextHere(assignp);
|
||||
//if (debug()) { pinp->dumpTree(cout,"- out:"); }
|
||||
//if (debug()) { assignp->dumpTree(cout,"- aout:"); }
|
||||
}
|
||||
return assignp;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Inst class functions
|
||||
|
||||
AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule*,
|
||||
AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* modp,
|
||||
bool forTristate, bool alwaysCvt) {
|
||||
// If a pin connection is "simple" leave it as-is
|
||||
// Else create a intermediate wire to perform the interconnect
|
||||
// Return the new assignment, if one was made
|
||||
// Note this module calles cloneTree() via new AstVar
|
||||
AstVar* pinVarp = pinp->modVarp();
|
||||
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
|
||||
AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL
|
||||
AstBasicDType* connBasicp = NULL;
|
||||
AstAssignW* assignp = NULL;
|
||||
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp();
|
||||
//
|
||||
if (!alwaysCvt
|
||||
&& connectRefp
|
||||
&& connectRefp->varp()->dtypep()->sameTree(pinVarp->dtypep())
|
||||
&& !connectRefp->varp()->isSc()) { // Need the signal as a 'shell' to convert types
|
||||
// Done. Same data type
|
||||
} else if (!alwaysCvt
|
||||
&& connectRefp
|
||||
&& connectRefp->varp()->isIfaceRef()) {
|
||||
// Done. Interface
|
||||
} else if (!alwaysCvt
|
||||
&& connBasicp
|
||||
&& pinBasicp
|
||||
&& connBasicp->width() == pinBasicp->width()
|
||||
&& connBasicp->lsb() == pinBasicp->lsb()
|
||||
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
|
||||
&& connBasicp->width() == pinVarp->width()
|
||||
&& 1) {
|
||||
// Done. One to one interconnect won't need a temporary variable.
|
||||
} else if (!alwaysCvt && !forTristate && pinp->exprp()->castConst()) {
|
||||
// Done. Constant.
|
||||
} else {
|
||||
// Make a new temp wire
|
||||
//if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); }
|
||||
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
|
||||
string newvarname = ((string)(pinVarp->isOutput() ? "__Vcellout" : "__Vcellinp")
|
||||
+(forTristate?"t":"") // Prevent name conflict if both tri & non-tri add signals
|
||||
+"__"+cellp->name()+"__"+pinp->name());
|
||||
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
|
||||
// Important to add statement next to cell, in case there is a generate with same named cell
|
||||
cellp->addNextHere(newvarp);
|
||||
if (pinVarp->isInout()) {
|
||||
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)");
|
||||
} else if (pinVarp->isOutput()) {
|
||||
// See also V3Inst
|
||||
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
|
||||
if (pinVarp->width() > rhsp->width()) {
|
||||
if (rhsp->isSigned()) {
|
||||
rhsp = new AstExtendS(pinp->fileline(), rhsp);
|
||||
} else {
|
||||
rhsp = new AstExtend (pinp->fileline(), rhsp);
|
||||
}
|
||||
} else if (pinVarp->width() < rhsp->width()) {
|
||||
rhsp = new AstSel (pinp->fileline(), rhsp, 0, pinVarp->width());
|
||||
}
|
||||
rhsp->dtypeFrom(pinVarp); // Need proper widthMin, which may differ from AstSel created above
|
||||
assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsp);
|
||||
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, true));
|
||||
} else {
|
||||
// V3 width should have range/extended to make the widths correct
|
||||
assignp = new AstAssignW (pinp->fileline(),
|
||||
new AstVarRef(pinp->fileline(), newvarp, true),
|
||||
pinexprp);
|
||||
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
|
||||
}
|
||||
if (assignp) cellp->addNextHere(assignp);
|
||||
//if (debug()) { pinp->dumpTree(cout,"- out:"); }
|
||||
//if (debug()) { assignp->dumpTree(cout,"- aout:"); }
|
||||
}
|
||||
return assignp;
|
||||
return InstStatic::pinReconnectSimple(pinp, cellp, modp, forTristate, alwaysCvt);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -207,7 +207,11 @@ private:
|
||||
} else if (AstMemberSel* fromp = basefromp->castMemberSel()) {
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE,
|
||||
fromp->cloneTree(false)));
|
||||
} else if (AstEnumItemRef* fromp = basefromp->castEnumItemRef()) {
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE,
|
||||
fromp->cloneTree(false)));
|
||||
} else {
|
||||
if (basefromp) { UINFO(1," Related node: "<<basefromp<<endl); }
|
||||
nodep->v3fatalSrc("Illegal bit select; no signal/member being extracted from");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1569,6 +1569,24 @@ V3Number& V3Number::opSel (const V3Number& lhs, uint32_t msbval, uint32_t lsbval
|
||||
return *this;
|
||||
}
|
||||
|
||||
V3Number& V3Number::opSelInto (const V3Number& lhs, const V3Number& lsb, int width) {
|
||||
return opSelInto(lhs, lsb.toSInt(), width);
|
||||
}
|
||||
|
||||
V3Number& V3Number::opSelInto (const V3Number& lhs, int lsbval, int width) {
|
||||
// this[lsbval+width-1 : lsbval] = lhs; Other bits of this are not affected
|
||||
int ibit=0;
|
||||
for(int bit=lsbval; bit<lsbval+width; bit++) {
|
||||
if (ibit>=0 && ibit<lhs.width()) {
|
||||
setBit(bit,lhs.bitIs(ibit));
|
||||
} else {
|
||||
setBit(bit,'x');
|
||||
}
|
||||
ibit++;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
V3Number& V3Number::opCond (const V3Number& lhs, const V3Number& if1s, const V3Number& if0s) {
|
||||
V3Number lhstrue (lhs.m_fileline); lhstrue.opRedOr(lhs);
|
||||
if (lhstrue.bitIs0(0)) {
|
||||
|
||||
@@ -235,6 +235,8 @@ public:
|
||||
V3Number& opStreamL (const V3Number& lhs, const V3Number& rhs);
|
||||
V3Number& opSel (const V3Number& lhs, const V3Number& rhs, const V3Number& ths);
|
||||
V3Number& opSel (const V3Number& lhs, uint32_t rhs, uint32_t ths);
|
||||
V3Number& opSelInto (const V3Number& lhs, const V3Number& lsb, int width);
|
||||
V3Number& opSelInto (const V3Number& lhs, int lsb, int width);
|
||||
V3Number& opCond (const V3Number& lhs, const V3Number& rhs, const V3Number& ths);
|
||||
V3Number& opCaseEq (const V3Number& lhs, const V3Number& rhs);
|
||||
V3Number& opCaseNeq (const V3Number& lhs, const V3Number& rhs);
|
||||
|
||||
@@ -960,6 +960,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
if (suffixed(filename.c_str(), ".cpp")
|
||||
|| suffixed(filename.c_str(), ".cxx")
|
||||
|| suffixed(filename.c_str(), ".cc")
|
||||
|| suffixed(filename.c_str(), ".c")
|
||||
|| suffixed(filename.c_str(), ".sp")) {
|
||||
V3Options::addCppFile(filename);
|
||||
}
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ void V3Os::setenvStr(const string& envvar, const string& value, const string& wh
|
||||
} else {
|
||||
UINFO(1,"export "<<envvar<<"="<<value<<endl);
|
||||
}
|
||||
#if defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
|
||||
#if !defined(__MINGW32__) && (defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L))
|
||||
setenv(envvar.c_str(),value.c_str(),true);
|
||||
#else
|
||||
//setenv() replaced by putenv() in MinGW/Solaris environment. Prototype is different
|
||||
|
||||
+20
-9
@@ -58,6 +58,7 @@ static void appendDefValue(const char* t, size_t l) { LEXP->appendDefValue(t,l);
|
||||
%x DEFFORM
|
||||
%x DEFVAL
|
||||
%x DEFCMT
|
||||
%x STRIFY
|
||||
%x ARGMODE
|
||||
%x INCMODE
|
||||
%x PRTMODE
|
||||
@@ -80,8 +81,8 @@ drop [\032]
|
||||
/**************************************************************/
|
||||
%%
|
||||
|
||||
<INITIAL>^{ws}*"`line"{ws}+.*{crnl} { LEXP->lineDirective(yytext);
|
||||
return(VP_LINE); }
|
||||
<INITIAL,STRIFY>^{ws}*"`line"{ws}+.*{crnl} { LEXP->lineDirective(yytext);
|
||||
return(VP_LINE); }
|
||||
|
||||
/* Special directives we recognize */
|
||||
<INITIAL>"`define" { return(VP_DEFINE); }
|
||||
@@ -93,17 +94,15 @@ drop [\032]
|
||||
<INITIAL>"`include" { return(VP_INCLUDE); }
|
||||
<INITIAL>"`undef" { return(VP_UNDEF); }
|
||||
<INITIAL>"`undefineall" { return(VP_UNDEFINEALL); }
|
||||
|
||||
/* Optional directives we recognize */
|
||||
<INITIAL>"`__FILE__" { static string rtnfile;
|
||||
<INITIAL>"`error" { if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); }
|
||||
<INITIAL,STRIFY>"`__FILE__" { static string rtnfile;
|
||||
rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename();
|
||||
rtnfile += '"'; yytext=(char*)rtnfile.c_str(); yyleng = rtnfile.length();
|
||||
return (VP_STRING); }
|
||||
<INITIAL>"`__LINE__" { static char buf[10];
|
||||
<INITIAL,STRIFY>"`__LINE__" { static char buf[10];
|
||||
sprintf(buf, "%d",LEXP->curFilelinep()->lineno());
|
||||
yytext = buf; yyleng = strlen(yytext);
|
||||
return (VP_TEXT); }
|
||||
<INITIAL>"`error" { if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); }
|
||||
|
||||
/* Pass-through strings */
|
||||
<INITIAL>{quote} { yy_push_state(STRMODE); yymore(); }
|
||||
@@ -118,8 +117,20 @@ drop [\032]
|
||||
else return (VP_STRING); }
|
||||
|
||||
/* Stringification */
|
||||
<INITIAL>{tickquote} { return VP_STRIFY; }
|
||||
<INITIAL>"`\\`\"" { return VP_BACKQUOTE; }
|
||||
<INITIAL>{tickquote} { yy_push_state(STRIFY); return VP_STRIFY; }
|
||||
<STRIFY><<EOF>> { linenoInc(); yyerrorf("EOF in unterminated '\""); yyleng=0; yyterminate(); }
|
||||
<STRIFY>"`\\`\"" { return VP_BACKQUOTE; }
|
||||
<STRIFY>{quote} { yy_push_state(STRMODE); yymore(); }
|
||||
<STRIFY>{tickquote} { yy_pop_state(); return VP_STRIFY; }
|
||||
<STRIFY>{symbdef} { return (VP_SYMBOL); }
|
||||
<STRIFY>{symbdef}`` { yyleng-=2; return (VP_SYMBOL_JOIN); }
|
||||
<STRIFY>"`"{symbdef} { return (VP_DEFREF); }
|
||||
<STRIFY>"`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); }
|
||||
<STRIFY>{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
|
||||
<STRIFY>{wsn}+ { return (VP_WHITE); }
|
||||
<STRIFY>{drop} { }
|
||||
<STRIFY>[\r] { }
|
||||
<STRIFY>. { return (VP_TEXT); }
|
||||
|
||||
/* Protected blocks */
|
||||
<INITIAL>"`protected" { yy_push_state(PRTMODE); yymore(); }
|
||||
|
||||
+51
-12
@@ -224,16 +224,24 @@ private:
|
||||
if (!vscp) nodep->v3fatalSrc("Not linked");
|
||||
return vscp;
|
||||
}
|
||||
|
||||
int unrollCount() {
|
||||
return m_params ? v3Global.opt.unrollCount()*16
|
||||
: v3Global.opt.unrollCount();
|
||||
}
|
||||
|
||||
bool jumpingOver(AstNode* nodep) {
|
||||
// True to jump over this node - all visitors must call this up front
|
||||
return (m_jumpp && m_jumpp->labelp()!=nodep);
|
||||
}
|
||||
void assignOutNumber(AstNodeAssign* nodep, AstNode* vscp, const V3Number* nump) {
|
||||
// Don't do setNumber, as value isn't yet visible to following statements
|
||||
if (nodep->castAssignDly()) {
|
||||
// Don't do setNumber, as value isn't yet visible to following statements
|
||||
newOutNumber(vscp)->opAssign(*nump);
|
||||
} else {
|
||||
newNumber(vscp)->opAssign(*nump);
|
||||
newOutNumber(vscp)->opAssign(*nump);
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
@@ -252,7 +260,9 @@ private:
|
||||
// We can't have non-delayed assignments with same value on LHS and RHS
|
||||
// as we don't figure out variable ordering.
|
||||
// Delayed is OK though, as we'll decode the next state separately.
|
||||
if (!nodep->varp()->dtypeSkipRefp()->castBasicDType()) clearOptimizable(nodep,"Array references/not basic");
|
||||
if (!nodep->varp()->dtypeSkipRefp()->castBasicDType()
|
||||
&& !nodep->varp()->dtypeSkipRefp()->castPackArrayDType())
|
||||
clearOptimizable(nodep,"Array references/not basic");
|
||||
if (nodep->lvalue()) {
|
||||
if (m_inDlyAssign) {
|
||||
if (!(vscp->user1() & VU_LVDLY)) {
|
||||
@@ -438,7 +448,43 @@ private:
|
||||
if (m_anyAssignDly) clearOptimizable(nodep, "Mix of dly/non-dly assigns");
|
||||
m_anyAssignComb = true;
|
||||
}
|
||||
if (!nodep->lhsp()->castVarRef()) {
|
||||
if (AstSel* selp = nodep->lhsp()->castSel()) {
|
||||
if (!m_params) { clearOptimizable(nodep, "LHS has select"); return; }
|
||||
checkNodeInfo(selp);
|
||||
AstVarRef* varrefp = selp->fromp()->castVarRef();
|
||||
if (!varrefp) {
|
||||
clearOptimizable(nodep, "Select LHS isn't simple variable");
|
||||
return;
|
||||
}
|
||||
if (m_checkOnly) {
|
||||
nodep->iterateChildren(*this);
|
||||
} else {
|
||||
selp->lsbp()->iterateAndNext(*this);
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
if (optimizable()) {
|
||||
AstNode* vscp = varOrScope(varrefp);
|
||||
if (optimizable()) {
|
||||
V3Number outnum (nodep->fileline(), varrefp->varp()->widthMin());
|
||||
if (V3Number* outnump = fetchOutNumberNull(vscp)) {
|
||||
outnum = *outnump;
|
||||
} else if (V3Number* outnump = fetchNumberNull(vscp)) {
|
||||
outnum = *outnump;
|
||||
} else { // Assignment to unassigned variable, all bits are X or 0
|
||||
if (varrefp->varp()->basicp() && varrefp->varp()->basicp()->isZeroInit()) {
|
||||
outnum.setAllBits0();
|
||||
} else {
|
||||
outnum.setAllBitsX();
|
||||
}
|
||||
}
|
||||
outnum.opSelInto(*fetchNumber(nodep->rhsp()),
|
||||
*fetchNumber(selp->lsbp()),
|
||||
selp->widthConst());
|
||||
assignOutNumber(nodep, vscp, &outnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!nodep->lhsp()->castVarRef()) {
|
||||
clearOptimizable(nodep, "LHS isn't simple variable");
|
||||
}
|
||||
else if (m_checkOnly) {
|
||||
@@ -448,14 +494,7 @@ private:
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
if (optimizable()) {
|
||||
AstNode* vscp = varOrScope(nodep->lhsp()->castVarRef());
|
||||
// Copy by value, not reference, as we don't want a=a+1 to get right results
|
||||
if (nodep->castAssignDly()) {
|
||||
// Don't do setNumber, as value isn't yet visible to following statements
|
||||
newOutNumber(vscp)->opAssign(*fetchNumber(nodep->rhsp()));
|
||||
} else {
|
||||
newNumber(vscp)->opAssign(*fetchNumber(nodep->rhsp()));
|
||||
newOutNumber(vscp)->opAssign(*fetchNumber(nodep->rhsp()));
|
||||
}
|
||||
assignOutNumber(nodep, vscp, fetchNumber(nodep->rhsp()));
|
||||
}
|
||||
}
|
||||
m_inDlyAssign = false;
|
||||
|
||||
+9
-9
@@ -55,35 +55,35 @@ public:
|
||||
VHashFnv() : m_hash(FNV1_64_INIT) {}
|
||||
~VHashFnv() {}
|
||||
|
||||
vluint64_t value() const { return m_hash; }
|
||||
vluint64_t digestUInt64() const { return m_hash; }
|
||||
|
||||
VHashFnv& hash(const void* bufp, size_t len) { // Memory
|
||||
VHashFnv& insert(const void* bufp, size_t len) { // Memory
|
||||
const uint8_t* bp = (const uint8_t*)bufp;
|
||||
const uint8_t* be = bp + len;
|
||||
while (bp < be) hashC((vluint64_t)*bp++);
|
||||
return *this;
|
||||
}
|
||||
VHashFnv& hash(const char* strp) { // String
|
||||
VHashFnv& insert(const char* strp) { // String
|
||||
const uint8_t* sp = (const uint8_t*)strp;
|
||||
while (*sp) hashC((vluint64_t)*sp++);
|
||||
return *this;
|
||||
}
|
||||
VHashFnv& hash(const string& str) { return hash(str.c_str()); }
|
||||
VHashFnv& hash(vluint64_t n) {
|
||||
VHashFnv& insert(const string& str) { return insert(str.data(), str.length()); }
|
||||
VHashFnv& insert(vluint64_t n) {
|
||||
hashC(n>>0); hashC(n>>8); hashC(n>>16); hashC(n>>24);
|
||||
hashC(n>>32); hashC(n>>40); hashC(n>>48); hashC(n>>56);
|
||||
return *this;
|
||||
}
|
||||
VHashFnv& hash(uint32_t n) {
|
||||
VHashFnv& insert(uint32_t n) {
|
||||
hashC(n>>0); hashC(n>>8); hashC(n>>16); hashC(n>>24);
|
||||
return *this;
|
||||
}
|
||||
VHashFnv& hash(uint16_t n) {
|
||||
VHashFnv& insert(uint16_t n) {
|
||||
hashC(n>>0); hashC(n>>8);
|
||||
return *this;
|
||||
}
|
||||
VHashFnv& hash(uint8_t n) { hashC(n); return *this; }
|
||||
VHashFnv& hash(int n) { hashC((vluint64_t)n); return *this; }
|
||||
VHashFnv& insert(uint8_t n) { hashC(n); return *this; }
|
||||
VHashFnv& insert(int n) { hashC((vluint64_t)n); return *this; }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+34
-13
@@ -834,9 +834,8 @@ private:
|
||||
// Don't iterate children, don't want to lose VarRef.
|
||||
switch (nodep->attrType()) {
|
||||
case AstAttrType::VAR_BASE:
|
||||
// Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf
|
||||
break;
|
||||
case AstAttrType::MEMBER_BASE:
|
||||
case AstAttrType::ENUM_BASE:
|
||||
// Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf
|
||||
break;
|
||||
case AstAttrType::DIM_DIMENSIONS:
|
||||
@@ -1009,8 +1008,10 @@ private:
|
||||
//if (debug()) newp->dumpTree(cout," CastOut: ");
|
||||
}
|
||||
virtual void visit(AstCastSize* nodep, AstNUser* vup) {
|
||||
// IEEE: Signedness of result is same as self-determined signedness
|
||||
// However, the result is same as BITSEL, so we do not sign extend the LHS
|
||||
if (!nodep->rhsp()->castConst()) nodep->v3fatalSrc("Unsupported: Non-const cast of size");
|
||||
//if (debug()) nodep->dumpTree(cout," CastPre: ");
|
||||
//if (debug()) nodep->dumpTree(cout," CastSizePre: ");
|
||||
if (vup->c()->prelim()) {
|
||||
int width = nodep->rhsp()->castConst()->toSInt();
|
||||
if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width=1; }
|
||||
@@ -1020,12 +1021,29 @@ private:
|
||||
nodep->v3error("Unsupported: Size-changing cast on non-basic data type");
|
||||
underDtp = nodep->findLogicBoolDType()->castBasicDType();
|
||||
}
|
||||
AstNodeDType* newDtp = (underDtp->keyword().isFourstate()
|
||||
? nodep->findLogicDType(width, width, underDtp->numeric())
|
||||
: nodep->findBitDType(width, width, underDtp->numeric()));
|
||||
nodep->dtypep(newDtp);
|
||||
// We ignore warnings as that is sort of the point of a cast
|
||||
iterateCheck(nodep,"Cast LHS",nodep->lhsp(),CONTEXT,FINAL,newDtp,EXTEND_EXP,false);
|
||||
// A cast propagates its size to the lower expression and is included in the maximum
|
||||
// width, so 23'(1'b1 + 1'b1) uses 23-bit math, but 1'(2'h2 * 2'h1) uses two-bit math.
|
||||
// However the output width is exactly that requested.
|
||||
// So two steps, first do the calculation's width (max of the two widths)
|
||||
{
|
||||
int calcWidth = max(width, underDtp->width());
|
||||
AstNodeDType* calcDtp = (underDtp->keyword().isFourstate()
|
||||
? nodep->findLogicDType(calcWidth, calcWidth, underDtp->numeric())
|
||||
: nodep->findBitDType(calcWidth, calcWidth, underDtp->numeric()));
|
||||
nodep->dtypep(calcDtp);
|
||||
// We ignore warnings as that is sort of the point of a cast
|
||||
iterateCheck(nodep,"Cast expr",nodep->lhsp(),CONTEXT,FINAL,calcDtp,EXTEND_EXP,false);
|
||||
}
|
||||
if (debug()) nodep->dumpTree(cout," CastSizeClc: ");
|
||||
// Next step, make the proper output width
|
||||
{
|
||||
AstNodeDType* outDtp = (underDtp->keyword().isFourstate()
|
||||
? nodep->findLogicDType(width, width, underDtp->numeric())
|
||||
: nodep->findBitDType(width, width, underDtp->numeric()));
|
||||
nodep->dtypep(outDtp);
|
||||
// We ignore warnings as that is sort of the point of a cast
|
||||
widthCheckSized(nodep,"Cast expr",nodep->lhsp(),outDtp,EXTEND_EXP,false);
|
||||
}
|
||||
}
|
||||
if (vup->c()->final()) {
|
||||
// CastSize not needed once sizes determined
|
||||
@@ -1033,6 +1051,7 @@ private:
|
||||
nodep->replaceWith(underp);
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
}
|
||||
//if (debug()) nodep->dumpTree(cout," CastSizeOut: ");
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser* vup) {
|
||||
//if (debug()) nodep->dumpTree(cout," InitPre: ");
|
||||
@@ -1805,7 +1824,8 @@ private:
|
||||
// Apply width
|
||||
iterateCheck(nodep,"Case expression",nodep->exprp(),CONTEXT,FINAL,subDTypep,EXTEND_LHS);
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstNode* condp = itemp->condsp(); condp; condp=condp->nextp()) {
|
||||
for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) {
|
||||
nextcp = condp->nextp(); // Final may cause the node to get replaced
|
||||
iterateCheck(nodep,"Case Item",condp,CONTEXT,FINAL,subDTypep,EXTEND_LHS);
|
||||
}
|
||||
}
|
||||
@@ -3005,9 +3025,10 @@ private:
|
||||
// which bits to truncate.
|
||||
AstNodeAssign* assignp = nodep->castNodeAssign();
|
||||
AstPin* pinp = nodep->castPin();
|
||||
if (assignp && assignp->lhsp()->castNodeStream()) { }
|
||||
else if (pinp && !pinp->modVarp()->isInput()) { }
|
||||
else {
|
||||
if (assignp && assignp->lhsp()->castNodeStream()) {
|
||||
} else if (pinp && !pinp->modVarp()->isInput()) { // V3Inst::pinReconnectSimple must deal
|
||||
UINFO(5,"pinInSizeMismatch: "<<pinp);
|
||||
} else {
|
||||
fixWidthExtend(underp, expDTypep, extendRule); underp=NULL;//Changed
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -187,7 +187,7 @@ void process () {
|
||||
// Commit to the widths we've chosen; Make widthMin==width
|
||||
V3Width::widthCommit(v3Global.rootp());
|
||||
v3Global.assertDTypesResolved(true);
|
||||
v3Global.assertWidthsMatch(true);
|
||||
v3Global.widthMinUsage(VWidthMinUsage::MATCHES_WIDTH);
|
||||
|
||||
// Coverage insertion
|
||||
// Before we do dead code elimination and inlining, or we'll lose it.
|
||||
@@ -448,7 +448,7 @@ void process () {
|
||||
|
||||
// Here down, widthMin() is the Verilog width, and width() is the C++ width
|
||||
// Bits between widthMin() and width() are irrelevant, but may be non zero.
|
||||
v3Global.assertWidthsMatch(false);
|
||||
v3Global.widthMinUsage(VWidthMinUsage::VERILOG_WIDTH);
|
||||
|
||||
// Make all math operations either 8, 16, 32 or 64 bits
|
||||
V3Clean::cleanAll(v3Global.rootp());
|
||||
|
||||
+4
-1
@@ -117,7 +117,7 @@ void yyerrorf(const char* format, ...) {
|
||||
|
||||
va_list ap;
|
||||
va_start(ap,format);
|
||||
vsnprintf(msg,maxlen,format,ap);
|
||||
VL_VSNPRINTF(msg,maxlen,format,ap);
|
||||
msg[maxlen-1] = '\0';
|
||||
va_end(ap);
|
||||
|
||||
@@ -167,8 +167,11 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||
{crnl} { NEXTLINE(); } /* Count line numbers */
|
||||
|
||||
"coverage_off" { FL; return yVLT_COVERAGE_OFF; }
|
||||
"coverage_on" { FL; return yVLT_COVERAGE_ON; }
|
||||
"lint_off" { FL; return yVLT_LINT_OFF; }
|
||||
"lint_on" { FL; return yVLT_LINT_ON; }
|
||||
"tracing_off" { FL; return yVLT_TRACING_OFF; }
|
||||
"tracing_on" { FL; return yVLT_TRACING_ON; }
|
||||
|
||||
-?"-file" { FL; return yVLT_D_FILE; }
|
||||
-?"-lines" { FL; return yVLT_D_LINES; }
|
||||
|
||||
+22
-6
@@ -243,8 +243,11 @@ class AstSenTree;
|
||||
%token<strp> yaSCDTOR "`systemc_imp_header BLOCK"
|
||||
|
||||
%token<fl> yVLT_COVERAGE_OFF "coverage_off"
|
||||
%token<fl> yVLT_LINT_OFF "lint_off"
|
||||
%token<fl> yVLT_TRACING_OFF "tracing_off"
|
||||
%token<fl> yVLT_COVERAGE_ON "coverage_on"
|
||||
%token<fl> yVLT_LINT_OFF "lint_off"
|
||||
%token<fl> yVLT_LINT_ON "lint_on"
|
||||
%token<fl> yVLT_TRACING_OFF "tracing_off"
|
||||
%token<fl> yVLT_TRACING_ON "tracing_on"
|
||||
|
||||
%token<fl> yVLT_D_FILE "--file"
|
||||
%token<fl> yVLT_D_LINES "--lines"
|
||||
@@ -3625,10 +3628,14 @@ package_scopeIdFollows<packagep>: // IEEE: package_scope
|
||||
// VLT Files
|
||||
|
||||
vltItem:
|
||||
vltOffFront { V3Config::addIgnore($1,"*",0,0); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,*$3,0,0); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,*$3,$5->toUInt(),$5->toUInt()+1); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,*$3,$5->toUInt(),$7->toUInt()+1); }
|
||||
vltOffFront { V3Config::addIgnore($1,false,"*",0,0); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,false,*$3,0,0); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$5->toUInt()+1); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$7->toUInt()+1); }
|
||||
| vltOnFront { V3Config::addIgnore($1,true,"*",0,0); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,true,*$3,0,0); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$5->toUInt()+1); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$7->toUInt()+1); }
|
||||
;
|
||||
|
||||
vltOffFront<errcodeen>:
|
||||
@@ -3640,6 +3647,15 @@ vltOffFront<errcodeen>:
|
||||
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); } }
|
||||
;
|
||||
|
||||
vltOnFront<errcodeen>:
|
||||
yVLT_COVERAGE_ON { $$ = V3ErrorCode::I_COVERAGE; }
|
||||
| yVLT_TRACING_ON { $$ = V3ErrorCode::I_TRACING; }
|
||||
| yVLT_LINT_ON { $$ = V3ErrorCode::I_LINT; }
|
||||
| yVLT_LINT_ON yVLT_D_MSG yaID__ETC
|
||||
{ $$ = V3ErrorCode((*$3).c_str());
|
||||
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); } }
|
||||
;
|
||||
|
||||
//**********************************************************************
|
||||
%%
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
//*************************************************************************
|
||||
|
||||
#include "vpi_user.h"
|
||||
#include <sstream>
|
||||
|
||||
class TestSimulator {
|
||||
private:
|
||||
@@ -69,9 +70,11 @@ public:
|
||||
}
|
||||
// return absolute scope of obj
|
||||
static const char* rooted(const char *obj) {
|
||||
static char buf[256];
|
||||
snprintf(buf, sizeof(buf), "%s.%s", top(), obj);
|
||||
return buf;
|
||||
static string buf;
|
||||
ostringstream os;
|
||||
os<<top()<<"."<<obj;
|
||||
buf = os.str();
|
||||
return buf.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,27 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Jonathon Donaldson.
|
||||
|
||||
module t_bitsel_enum
|
||||
(
|
||||
output out0,
|
||||
output out1
|
||||
);
|
||||
|
||||
localparam [6:0] CNST_VAL = 7'h22;
|
||||
|
||||
enum logic [6:0] {
|
||||
ENUM_VAL = 7'h33
|
||||
} MyEnum;
|
||||
|
||||
assign out0 = CNST_VAL[0];
|
||||
// This is not supported by NC-verilog nor VCS, so Verilator does not support it either
|
||||
assign out1 = ENUM_VAL[0]; // named values of an enumeration should act like constants so this should work just like the line above works
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,25 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2014 by Jonathon Donaldson.
|
||||
|
||||
module t
|
||||
(
|
||||
input i_clk,
|
||||
input [6:0] i_input,
|
||||
output logic o_output
|
||||
);
|
||||
|
||||
always_ff @(posedge i_clk)
|
||||
// verilator lint_off CASEINCOMPLETE
|
||||
case (i_input)
|
||||
7'(92+2),
|
||||
7'(92+3): o_output <= 1'b1;
|
||||
endcase
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -13,6 +13,23 @@ module t;
|
||||
logic [15:0] allones = 16'hffff;
|
||||
parameter FOUR = 4;
|
||||
|
||||
// bug925
|
||||
localparam [6:0] RESULT = 7'((6*9+92)%96);
|
||||
|
||||
logic signed [14:0] samp0 = 15'h0000;
|
||||
logic signed [14:0] samp1 = 15'h0000;
|
||||
logic signed [14:0] samp2 = 15'h6000;
|
||||
logic signed [11:0] coeff0 = 12'h009;
|
||||
logic signed [11:0] coeff1 = 12'h280;
|
||||
logic signed [11:0] coeff2 = 12'h4C5;
|
||||
logic signed [26:0] mida = ((27'(coeff2 * samp2) >>> 11));
|
||||
// verilator lint_off WIDTH
|
||||
logic signed [26:0] midb = 15'((27'(coeff2 * samp2) >>> 11));
|
||||
// verilator lint_on WIDTH
|
||||
logic signed [14:0] outa = 15'((27'(coeff0 * samp0) >>> 11) + // 27' size casting in order for intermediate result to not be truncated to the width of LHS vector
|
||||
(27'(coeff1 * samp1) >>> 11) +
|
||||
(27'(coeff2 * samp2) >>> 11)); // 15' size casting to avoid synthesis/simulator warnings
|
||||
|
||||
initial begin
|
||||
if (4'shf > 4'sh0) $stop;
|
||||
if (signed'(4'hf) > 4'sh0) $stop;
|
||||
@@ -24,10 +41,15 @@ module t;
|
||||
if ((4+2)'(allones) !== 6'h3f) $stop;
|
||||
if ((4-2)'(allones) !== 2'h3) $stop;
|
||||
if ((FOUR+2)'(allones) !== 6'h3f) $stop;
|
||||
if (50 !== RESULT) $stop;
|
||||
|
||||
o = tocast_t'(4'b1);
|
||||
if (o != 4'b1) $stop;
|
||||
|
||||
if (15'h6cec != outa) $stop;
|
||||
if (27'h7ffecec != mida) $stop;
|
||||
if (27'h7ffecec != midb) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
@@ -18,6 +18,7 @@ if (!-r "$root/.git") {
|
||||
uint();
|
||||
printfll();
|
||||
cstr();
|
||||
vsnprintf();
|
||||
}
|
||||
|
||||
ok(1);
|
||||
@@ -86,4 +87,23 @@ sub cstr {
|
||||
}
|
||||
}
|
||||
|
||||
sub vsnprintf {
|
||||
# Note do not do test_regress, as VPI files need to compile without verilatedos.h
|
||||
my $files = "src/*.c* src/*.h include/*.c* include/*.h test_c/*.c*";
|
||||
my $cmd = "cd $root && grep -n -P '(snprintf|vsnprintf)' $files | sort";
|
||||
print "C $cmd\n";
|
||||
my $grep = `$cmd`;
|
||||
my %names;
|
||||
foreach my $line (split /\n/, $grep) {
|
||||
if ($line =~ /\b(snprintf|vsnprintf)\b/) {
|
||||
next if $line =~ /# *define\s*VL_V?SNPRINTF/;
|
||||
print "$line\n";
|
||||
$names{$1} = 1;
|
||||
}
|
||||
}
|
||||
if (keys %names) {
|
||||
$Self->error("Files with vsnprintf, use VL_VSNPRINTF: ",join(' ',sort keys %names));
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2011 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["t/t_dpi_imp_gen_c.cpp"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,33 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// Copyright 2009 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
parameter integer BLKS = 3;
|
||||
|
||||
generate
|
||||
for (genvar blkIdx=0; blkIdx < BLKS; blkIdx=blkIdx+1 ) begin : slice
|
||||
|
||||
import "DPI-C" context function void dpi_genvarTest ();
|
||||
|
||||
initial begin
|
||||
dpi_genvarTest();
|
||||
$display("slice = %0d : %m", blkIdx);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @ (posedge clk) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,39 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// Copyright 2009 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
//*************************************************************************
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "svdpi.h"
|
||||
|
||||
//======================================================================
|
||||
|
||||
#if defined(VERILATOR)
|
||||
# include "Vt_dpi_imp_gen__Dpi.h"
|
||||
#elif defined(VCS)
|
||||
# include "../vc_hdrs.h"
|
||||
#elif defined(CADENCE)
|
||||
# define NEED_EXTERNS
|
||||
#else
|
||||
# error "Unknown simulator for DPI test"
|
||||
#endif
|
||||
|
||||
#ifdef NEED_EXTERNS
|
||||
extern "C" {
|
||||
extern void dpi_genvarTest();
|
||||
}
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
|
||||
// Called from our Verilog code to run the tests
|
||||
void dpi_genvarTest () {
|
||||
const char *scopeName = svGetNameFromScope(svGetScope());
|
||||
printf("scope name : %s\n", scopeName);
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,50 @@
|
||||
// DESCRIPTION:tor:ilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
wire [31:0] o;
|
||||
wire [31:0] oe;
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Outputs
|
||||
.o (o[31:0]),
|
||||
.oe (oe[31:0]));
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
if (o !== 32'h00000001) $stop;
|
||||
if (oe !== 32'h00000001) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module subimp(o,oe);
|
||||
output [31:0] o;
|
||||
assign o = 32'h12345679;
|
||||
output [31:0] oe;
|
||||
assign oe = 32'hab345679;
|
||||
endmodule
|
||||
|
||||
module Test(o,oe);
|
||||
output [31:0] o;
|
||||
output [31:0] oe;
|
||||
wire [31:0] xe;
|
||||
assign xe[31:1] = 0;
|
||||
// verilator lint_off IMPLICIT
|
||||
// verilator lint_off WIDTH
|
||||
subimp subimp(x, // x is implicit and one bit
|
||||
xe[0]); // xe explicit one bit
|
||||
assign o = x;
|
||||
assign oe = xe;
|
||||
// verilator lint_on WIDTH
|
||||
// verilator lint_on IMPLICIT
|
||||
endmodule
|
||||
@@ -29,12 +29,8 @@ module t (/*AUTOARG*/
|
||||
`endif
|
||||
if (sgn_wide[2:0] != 3'sh7) $stop;
|
||||
if (unsgn_wide[2:0] != 3'h7) $stop;
|
||||
if (sgn_wide !== 8'sh7) $stop;
|
||||
// Simulators differ here.
|
||||
if (sgn_wide !== 8'sbzzzzz111 // z-extension - NC
|
||||
`ifdef VERILATOR
|
||||
&& sgn_wide !== 8'sb00000111 // 0-extension - verilator as it doesn't have Z
|
||||
`endif
|
||||
&& sgn_wide !== 8'sb11111111) $stop; // sign extension - VCS
|
||||
if (unsgn_wide !== 8'sbzzzzz111
|
||||
&& unsgn_wide!== 8'sb00000111) $stop;
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,132 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This test demonstrates an issue with sign extension.
|
||||
// Assigning to localparms larger than 32 bits broke in 3.862
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Mike Thyer.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
|
||||
localparam [ 0:0] one1_lp = 1;
|
||||
localparam [ 1:0] one2_lp = 1;
|
||||
localparam [ 2:0] one3_lp = 1;
|
||||
localparam [ 3:0] one4_lp = 1;
|
||||
localparam [ 4:0] one5_lp = 1;
|
||||
localparam [ 5:0] one6_lp = 1;
|
||||
localparam [ 6:0] one7_lp = 1;
|
||||
localparam [ 7:0] one8_lp = 1;
|
||||
localparam [ 8:0] one9_lp = 1;
|
||||
localparam [ 9:0] one10_lp = 1;
|
||||
localparam [19:0] one20_lp = 1;
|
||||
localparam [29:0] one30_lp = 1;
|
||||
localparam [30:0] one31_lp = 1;
|
||||
localparam [31:0] one32_lp = 1;
|
||||
localparam [32:0] one33_lp = 1;
|
||||
localparam [33:0] one34_lp = 1;
|
||||
localparam [34:0] one35_lp = 1;
|
||||
localparam [35:0] one36_lp = 1;
|
||||
localparam [36:0] one37_lp = 1;
|
||||
localparam [37:0] one38_lp = 1;
|
||||
localparam [38:0] one39_lp = 1;
|
||||
localparam [39:0] one40_lp = 1;
|
||||
localparam [49:0] one50_lp = 1;
|
||||
localparam [59:0] one60_lp = 1;
|
||||
localparam [60:0] one61_lp = 1;
|
||||
localparam [61:0] one62_lp = 1;
|
||||
localparam [62:0] one63_lp = 1;
|
||||
localparam [63:0] one64_lp = 1;
|
||||
localparam [64:0] one65_lp = 1;
|
||||
localparam [65:0] one66_lp = 1;
|
||||
localparam [66:0] one67_lp = 1;
|
||||
localparam [67:0] one68_lp = 1;
|
||||
localparam [68:0] one69_lp = 1;
|
||||
localparam [69:0] one70_lp = 1;
|
||||
|
||||
bit all_ok = 1;
|
||||
|
||||
initial begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$display("one1_lp : %x %d", one1_lp, one1_lp==1);
|
||||
$display("one2_lp : %x %d", one2_lp, one2_lp==1);
|
||||
$display("one3_lp : %x %d", one3_lp, one3_lp==1);
|
||||
$display("one4_lp : %x %d", one4_lp, one4_lp==1);
|
||||
$display("one5_lp : %x %d", one5_lp, one5_lp==1);
|
||||
$display("one6_lp : %x %d", one6_lp, one6_lp==1);
|
||||
$display("one7_lp : %x %d", one7_lp, one7_lp==1);
|
||||
$display("one8_lp : %x %d", one8_lp, one8_lp==1);
|
||||
$display("one9_lp : %x %d", one9_lp, one9_lp==1);
|
||||
$display("one10_lp: %x %d", one10_lp, one10_lp==1);
|
||||
$display("one20_lp: %x %d", one20_lp, one20_lp==1);
|
||||
$display("one30_lp: %x %d", one30_lp, one30_lp==1);
|
||||
$display("one31_lp: %x %d", one31_lp, one31_lp==1);
|
||||
$display("one32_lp: %x %d", one32_lp, one32_lp==1);
|
||||
$display("one33_lp: %x %d", one33_lp, one33_lp==1);
|
||||
$display("one34_lp: %x %d", one34_lp, one34_lp==1);
|
||||
$display("one35_lp: %x %d", one35_lp, one35_lp==1);
|
||||
$display("one36_lp: %x %d", one36_lp, one36_lp==1);
|
||||
$display("one37_lp: %x %d", one37_lp, one37_lp==1);
|
||||
$display("one38_lp: %x %d", one38_lp, one38_lp==1);
|
||||
$display("one39_lp: %x %d", one39_lp, one39_lp==1);
|
||||
$display("one40_lp: %x %d", one40_lp, one40_lp==1);
|
||||
$display("one50_lp: %x %d", one50_lp, one50_lp==1);
|
||||
$display("one60_lp: %x %d", one60_lp, one60_lp==1);
|
||||
$display("one61_lp: %x %d", one61_lp, one61_lp==1);
|
||||
$display("one62_lp: %x %d", one62_lp, one62_lp==1);
|
||||
$display("one63_lp: %x %d", one63_lp, one63_lp==1);
|
||||
$display("one64_lp: %x %d", one64_lp, one64_lp==1);
|
||||
$display("one65_lp: %x %d", one65_lp, one65_lp==1);
|
||||
$display("one66_lp: %x %d", one66_lp, one66_lp==1);
|
||||
$display("one67_lp: %x %d", one67_lp, one67_lp==1);
|
||||
$display("one68_lp: %x %d", one68_lp, one68_lp==1);
|
||||
$display("one69_lp: %x %d", one69_lp, one69_lp==1);
|
||||
$display("one70_lp: %x %d", one70_lp, one70_lp==1);
|
||||
`endif
|
||||
|
||||
all_ok &= one1_lp == 1;
|
||||
all_ok &= one2_lp == 1;
|
||||
all_ok &= one3_lp == 1;
|
||||
all_ok &= one4_lp == 1;
|
||||
all_ok &= one5_lp == 1;
|
||||
all_ok &= one6_lp == 1;
|
||||
all_ok &= one7_lp == 1;
|
||||
all_ok &= one8_lp == 1;
|
||||
all_ok &= one9_lp == 1;
|
||||
all_ok &= one10_lp == 1;
|
||||
all_ok &= one20_lp == 1;
|
||||
all_ok &= one30_lp == 1;
|
||||
all_ok &= one31_lp == 1;
|
||||
all_ok &= one32_lp == 1;
|
||||
all_ok &= one33_lp == 1;
|
||||
all_ok &= one34_lp == 1;
|
||||
all_ok &= one35_lp == 1;
|
||||
all_ok &= one36_lp == 1;
|
||||
all_ok &= one37_lp == 1;
|
||||
all_ok &= one38_lp == 1;
|
||||
all_ok &= one39_lp == 1;
|
||||
all_ok &= one40_lp == 1;
|
||||
all_ok &= one50_lp == 1;
|
||||
all_ok &= one60_lp == 1;
|
||||
all_ok &= one61_lp == 1;
|
||||
all_ok &= one62_lp == 1;
|
||||
all_ok &= one63_lp == 1;
|
||||
all_ok &= one64_lp == 1;
|
||||
all_ok &= one65_lp == 1;
|
||||
all_ok &= one66_lp == 1;
|
||||
all_ok &= one67_lp == 1;
|
||||
all_ok &= one68_lp == 1;
|
||||
all_ok &= one69_lp == 1;
|
||||
all_ok &= one70_lp == 1;
|
||||
|
||||
if (!all_ok) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
|
||||
end
|
||||
endmodule
|
||||
|
||||
@@ -169,6 +169,10 @@
|
||||
`checkh(w32_u, 32'h0000_0180);
|
||||
w32_u = 32'(signed'({4'b0011,5'b10000}) << 3);
|
||||
`checkh(w32_u, 32'h0000_0380);
|
||||
w32_u = signed'(32'({4'b0001,5'b10000}) << 3);
|
||||
`checkh(w32_u, 32'h0000_0180);
|
||||
w32_u = signed'(32'({4'b0011,5'b10000}) << 3);
|
||||
`checkh(w32_u, 32'h0000_0380);
|
||||
// verilator lint_on WIDTH
|
||||
w32_u = 32'(signed'({4'b0011,5'b10000})) << 3; // Check no width warning
|
||||
`checkh(w32_u, 32'h0000_0380);
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,27 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
function integer bottom_4bits;
|
||||
input [7:0] i;
|
||||
bottom_4bits = 0;
|
||||
bottom_4bits[3:0] = i[3:0];
|
||||
endfunction
|
||||
|
||||
function integer bottom_2_unknown;
|
||||
input [7:0] i;
|
||||
// bottom_4bits = 0; 'x
|
||||
bottom_2_unknown[1:0] = i[1:0];
|
||||
endfunction
|
||||
|
||||
localparam p = bottom_4bits(8'h13);
|
||||
localparam bu = bottom_2_unknown(8'h13);
|
||||
|
||||
initial begin
|
||||
if (p != 3) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,34 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This test examines Verilator against paramter definition with functions.
|
||||
// Particularly the function takes in argument which is multi-dimentional.
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2015 by Roland Kruse and Jie Xu.
|
||||
|
||||
module test#(
|
||||
parameter size = 4,
|
||||
parameter p = sum({32'h1,32'h2,32'h3,32'h4}, size))
|
||||
|
||||
(input clk,
|
||||
input logic sel,
|
||||
output [p:0] res);
|
||||
|
||||
logic [p:0] cc = 'h45;
|
||||
|
||||
assign res = sel ? cc : {(p+1){1'b1}};
|
||||
|
||||
function integer sum;
|
||||
input [3:0][31:0] values;
|
||||
input int size;
|
||||
|
||||
sum = 0;
|
||||
|
||||
begin
|
||||
for (int i = 0; i < size; i ++)
|
||||
sum += values[i];
|
||||
end
|
||||
endfunction
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -792,6 +792,13 @@ module t;
|
||||
|
||||
|
||||
initial $write("Slashed=`%s'\n", "1//2.3");
|
||||
|
||||
|
||||
|
||||
|
||||
initial
|
||||
`line 531 "t/t_preproc.v" 0
|
||||
$display("%s%s","a1","b2c3\n");
|
||||
endmodule
|
||||
|
||||
|
||||
@@ -813,4 +820,4 @@ predef 1 1
|
||||
predef 2 2
|
||||
|
||||
|
||||
`line 548 "t/t_preproc.v" 2
|
||||
`line 553 "t/t_preproc.v" 2
|
||||
|
||||
@@ -524,6 +524,11 @@ module t;
|
||||
// bug845
|
||||
`define SLASHED "1//2.3"
|
||||
initial $write("Slashed=`%s'\n", `SLASHED);
|
||||
//----
|
||||
// bug915
|
||||
`define BUG915(a,b,c) \
|
||||
$display("%s%s",a,`"b``c``\n`")
|
||||
initial `BUG915("a1",b2,c3);
|
||||
endmodule
|
||||
//======================================================================
|
||||
// IEEE mandated predefines
|
||||
|
||||
@@ -66,6 +66,14 @@ module t;
|
||||
$fclose(file);
|
||||
end
|
||||
|
||||
begin
|
||||
// Check read functions w/string
|
||||
s = "t/t_sys_file_basic_input.dat";
|
||||
file = $fopen(s,"r");
|
||||
if ($feof(file)) $stop;
|
||||
$fclose(file);
|
||||
end
|
||||
|
||||
begin
|
||||
// Check read functions
|
||||
file = $fopen("t/t_sys_file_basic_input.dat","r");
|
||||
|
||||
@@ -26,11 +26,11 @@ double sc_time_stamp() {
|
||||
const char* trace_name() {
|
||||
static char name[1000];
|
||||
#if defined(T_TRACE_CAT)
|
||||
snprintf(name,1000,"obj_dir/t_trace_cat/simpart_%04d.vcd", (int)main_time);
|
||||
VL_SNPRINTF(name,1000,"obj_dir/t_trace_cat/simpart_%04d.vcd", (int)main_time);
|
||||
#elif defined(T_TRACE_CAT_REOPEN)
|
||||
snprintf(name,1000,"obj_dir/t_trace_cat_reopen/simpart_%04d.vcd", (int)main_time);
|
||||
VL_SNPRINTF(name,1000,"obj_dir/t_trace_cat_reopen/simpart_%04d.vcd", (int)main_time);
|
||||
#elif defined(T_TRACE_CAT_RENEW)
|
||||
snprintf(name,1000,"obj_dir/t_trace_cat_renew/simpart_%04d.vcd", (int)main_time);
|
||||
VL_SNPRINTF(name,1000,"obj_dir/t_trace_cat_renew/simpart_%04d.vcd", (int)main_time);
|
||||
#else
|
||||
# error "Unknown test"
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,13 @@ program t;
|
||||
//reg [SIZE-1:0] a; initial a =0;
|
||||
//reg [SIZE-1:0] b; initial b =0;
|
||||
|
||||
initial begin
|
||||
typedef logic [3:0][7:0] instr_mem_t;
|
||||
instr_mem_t a;
|
||||
a[0] = 8'h12;
|
||||
if (a[0] != 8'h12) $stop;
|
||||
end
|
||||
|
||||
integer j;
|
||||
initial begin
|
||||
for (j=0;j<=(1<<SIZE);j=j+1) begin
|
||||
|
||||
+2
-2
@@ -140,8 +140,8 @@ int sc_main(int argc, char* argv[]) {
|
||||
// Coverage analysis (since test passed)
|
||||
mkdir("logs", 0777);
|
||||
#if VM_COVERAGE
|
||||
SpCoverage::write(); // Writes logs/coverage.pl
|
||||
#endif
|
||||
VerilatedCov::write("logs/coverage.dat");
|
||||
#endif // VM_COVERAGE
|
||||
|
||||
//==========
|
||||
// Close LogFiles
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
datarootdir=@datarootdir@
|
||||
includedir=@pkgdatadir@/include
|
||||
|
||||
Name: verilator
|
||||
Description: fast free Verilog simulator
|
||||
URL: http://www.veripool.org/verilator
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires:
|
||||
Libs:
|
||||
Cflags: -I${includedir} -I${includedir}/vltstd
|
||||
Reference in New Issue
Block a user