Merge branch 'master' of github.com:steveicarus/iverilog
This commit is contained in:
commit
a427440054
|
|
@ -5685,7 +5685,6 @@ unsigned PETernary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
} else if (tru_type == IVL_VT_LOGIC || fal_type == IVL_VT_LOGIC) {
|
} else if (tru_type == IVL_VT_LOGIC || fal_type == IVL_VT_LOGIC) {
|
||||||
expr_type_ = IVL_VT_LOGIC;
|
expr_type_ = IVL_VT_LOGIC;
|
||||||
} else {
|
} else {
|
||||||
ivl_assert(*this, tru_type == fal_type);
|
|
||||||
expr_type_ = tru_type;
|
expr_type_ = tru_type;
|
||||||
}
|
}
|
||||||
if (expr_type_ == IVL_VT_REAL) {
|
if (expr_type_ == IVL_VT_REAL) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
.TH iverilog-vpi 1 "May 10th, 2015" "" "Version %M.%n%E"
|
.TH iverilog-vpi 1 "Jan 29th, 2017" "" "Version %M.%n%E"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
iverilog-vpi - Compile front end for VPI modules
|
iverilog-vpi - Compile front end for VPI modules
|
||||||
|
|
||||||
|
|
@ -26,6 +26,11 @@ becomes \fIfoo.vpi\fP.
|
||||||
Include the named library in the link of the VPI module. This allows
|
Include the named library in the link of the VPI module. This allows
|
||||||
VPI modules to further reference external libraries.
|
VPI modules to further reference external libraries.
|
||||||
|
|
||||||
|
.TP 8
|
||||||
|
.B -L\fIdirectory\fP
|
||||||
|
Add \fIdirectory\fP to the list of directories that will be searched
|
||||||
|
for library files.
|
||||||
|
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -I\fIdirectory\fP
|
.B -I\fIdirectory\fP
|
||||||
Add \fIdirectory\fP to the list of directories that will be searched
|
Add \fIdirectory\fP to the list of directories that will be searched
|
||||||
|
|
@ -115,7 +120,7 @@ iverilog(1), vvp(1),
|
||||||
|
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
.nf
|
.nf
|
||||||
Copyright \(co 2002\-2015 Stephen Williams
|
Copyright \(co 2002\-2017 Stephen Williams
|
||||||
|
|
||||||
This document can be freely redistributed according to the terms of the
|
This document can be freely redistributed according to the terms of the
|
||||||
GNU General Public License version 2.0
|
GNU General Public License version 2.0
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ CCSRC=
|
||||||
CXSRC=
|
CXSRC=
|
||||||
OBJ=
|
OBJ=
|
||||||
LIB=
|
LIB=
|
||||||
|
LIBDIR=
|
||||||
OUT=
|
OUT=
|
||||||
INCOPT=
|
INCOPT=
|
||||||
DEFS=
|
DEFS=
|
||||||
|
|
@ -81,6 +82,9 @@ do
|
||||||
-l*) LIB="$LIB $parm"
|
-l*) LIB="$LIB $parm"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
-L*) LIBDIR="$LIBDIR $parm"
|
||||||
|
;;
|
||||||
|
|
||||||
-I*) INCOPT="$INCOPT $parm"
|
-I*) INCOPT="$INCOPT $parm"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
@ -148,4 +152,4 @@ then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Making $OUT from $OBJ..."
|
echo "Making $OUT from $OBJ..."
|
||||||
exec $LD -o $OUT $LDFLAGS $OBJ $LIB $LDLIBS
|
exec $LD -o $OUT $LDFLAGS $LIBDIR $OBJ $LIB $LDLIBS
|
||||||
|
|
|
||||||
236
pform.cc
236
pform.cc
|
|
@ -40,6 +40,7 @@
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
# include <cstring>
|
# include <cstring>
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
|
# include <cctype>
|
||||||
|
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
# include "ivl_alloc.h"
|
# include "ivl_alloc.h"
|
||||||
|
|
@ -86,6 +87,42 @@ std::string vlltype::get_fileline() const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_hex_digit_str(const char *str)
|
||||||
|
{
|
||||||
|
while (*str) {
|
||||||
|
if (!isxdigit(*str)) return false;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_dec_digit_str(const char *str)
|
||||||
|
{
|
||||||
|
while (*str) {
|
||||||
|
if (!isdigit(*str)) return false;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_oct_digit_str(const char *str)
|
||||||
|
{
|
||||||
|
while (*str) {
|
||||||
|
if (*str < '0' || *str > '7') return false;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_bin_digit_str(const char *str)
|
||||||
|
{
|
||||||
|
while (*str) {
|
||||||
|
if (*str != '0' && *str != '1') return false;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse configuration file with format <key>=<value>, where key
|
* Parse configuration file with format <key>=<value>, where key
|
||||||
* is the hierarchical name of a valid parameter name, and value
|
* is the hierarchical name of a valid parameter name, and value
|
||||||
|
|
@ -152,90 +189,137 @@ void parm_to_defparam_list(const string¶m)
|
||||||
ptr = strchr(nkey, '.');
|
ptr = strchr(nkey, '.');
|
||||||
}
|
}
|
||||||
name.push_back(name_component_t(lex_strings.make(nkey)));
|
name.push_back(name_component_t(lex_strings.make(nkey)));
|
||||||
|
free(key);
|
||||||
|
|
||||||
// Resolve value to PExpr class. Should support all kind of constant
|
// Resolve value to PExpr class. Should support all kind of constant
|
||||||
// format including based number, dec number, real number and string.
|
// format including based number, dec number, real number and string.
|
||||||
if (*value == '"') { // string type
|
|
||||||
char *buf = strdup (value);
|
|
||||||
char *buf_ptr = buf+1;
|
|
||||||
// Parse until another '"' or '\0'
|
|
||||||
while (*buf_ptr != '"' && *buf_ptr != '\0') {
|
|
||||||
buf_ptr++;
|
|
||||||
// Check for escape, especially '\"', which does not mean the
|
|
||||||
// end of string.
|
|
||||||
if (*buf_ptr == '\\' && *(buf_ptr+1) != '\0')
|
|
||||||
buf_ptr += 2;
|
|
||||||
}
|
|
||||||
if (*buf_ptr == '\0') // String end without '"'
|
|
||||||
cerr << "<command line>: error: missing close quote of string for defparam: " << name << endl;
|
|
||||||
else if (*(buf_ptr+1) != 0) { // '"' appears within string with no escape
|
|
||||||
cerr << buf_ptr << endl;
|
|
||||||
cerr << "<command line>: error: \'\"\' appears within string value for defparam: " << name
|
|
||||||
<< ". Ignore characters after \'\"\'" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buf_ptr = '\0';
|
// Is it a string?
|
||||||
buf_ptr = buf+1;
|
if (*value == '"') {
|
||||||
// Remember to use 'new' to allocate string for PEString
|
char *buf = strdup (value);
|
||||||
// because 'delete' is used by its destructor.
|
char *buf_ptr = buf+1;
|
||||||
char *nchar = strcpy(new char [strlen(buf_ptr)+1], buf_ptr);
|
// Parse until another '"' or '\0'
|
||||||
PExpr* ndec = new PEString(nchar);
|
while (*buf_ptr != '"' && *buf_ptr != '\0') {
|
||||||
|
buf_ptr++;
|
||||||
|
// Check for escape, especially '\"', which does not mean the
|
||||||
|
// end of string.
|
||||||
|
if (*buf_ptr == '\\' && *(buf_ptr+1) != '\0')
|
||||||
|
buf_ptr += 2;
|
||||||
|
}
|
||||||
|
if (*buf_ptr == '\0') // String end without '"'
|
||||||
|
cerr << "<command line>: error: missing close quote of string for defparam: " << name << endl;
|
||||||
|
else if (*(buf_ptr+1) != 0) { // '"' appears within string with no escape
|
||||||
|
cerr << buf_ptr << endl;
|
||||||
|
cerr << "<command line>: error: \'\"\' appears within string value for defparam: " << name
|
||||||
|
<< ". Ignore characters after \'\"\'" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf_ptr = '\0';
|
||||||
|
buf_ptr = buf+1;
|
||||||
|
// Remember to use 'new' to allocate string for PEString
|
||||||
|
// because 'delete' is used by its destructor.
|
||||||
|
char *nchar = strcpy(new char [strlen(buf_ptr)+1], buf_ptr);
|
||||||
|
PExpr* ndec = new PEString(nchar);
|
||||||
Module::user_defparms.push_back( make_pair(name, ndec) );
|
Module::user_defparms.push_back( make_pair(name, ndec) );
|
||||||
free(buf);
|
free(buf);
|
||||||
|
free(value);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else { // number type
|
|
||||||
char *num = strchr(value, '\'');
|
|
||||||
if (num != 0) {
|
|
||||||
verinum *val;
|
|
||||||
// BASED_NUMBER, something like - scope.parameter='b11
|
|
||||||
// make sure to check 'h' first because 'b'&'d' may be included
|
|
||||||
// in hex format
|
|
||||||
if (strchr(num, 'h') || strchr(num, 'H'))
|
|
||||||
val = make_unsized_hex(num);
|
|
||||||
else if (strchr(num, 'd') || strchr(num, 'D'))
|
|
||||||
if (strchr(num, 'x') || strchr(num, 'X') || strchr(num, 'z') || strchr(num, 'Z'))
|
|
||||||
val = make_undef_highz_dec(num);
|
|
||||||
else
|
|
||||||
val = make_unsized_dec(num);
|
|
||||||
else if (strchr(num, 'b') || strchr(num, 'B')) {
|
|
||||||
val = make_unsized_binary(num);
|
|
||||||
}
|
|
||||||
else if (strchr(num, 'o') || strchr(num, 'O'))
|
|
||||||
val = make_unsized_octal(num);
|
|
||||||
else {
|
|
||||||
cerr << "<command line>: error: value specify error for defparam: " << name << endl;
|
|
||||||
free(key);
|
|
||||||
free(value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BASED_NUMBER with size, something like - scope.parameter=2'b11
|
// Is it a based number?
|
||||||
if (num != value) {
|
char *num = strchr(value, '\'');
|
||||||
*num = 0;
|
if (num != 0) {
|
||||||
verinum *siz = make_unsized_dec(value);
|
verinum *val;
|
||||||
val = pform_verinum_with_size(siz, val, "<command line>", 0);
|
const char *base = num + 1;
|
||||||
}
|
if (*base == 's' || *base == 'S')
|
||||||
|
base++;
|
||||||
PExpr* ndec = new PENumber(val);
|
switch (*base) {
|
||||||
Module::user_defparms.push_back( make_pair(name, ndec) );
|
case 'h':
|
||||||
|
case 'H':
|
||||||
}
|
if (is_hex_digit_str(base+1)) {
|
||||||
else {
|
val = make_unsized_hex(num);
|
||||||
// REALTIME, something like - scope.parameter=1.22 or scope.parameter=1e2
|
} else {
|
||||||
if (strchr(value, '.') || strchr(value, 'e') || strchr(value, 'E')) {
|
cerr << "<command line>: error: invalid digit in hex value specified for defparam: " << name << endl;
|
||||||
verireal *val = new verireal(value);
|
free(value);
|
||||||
PExpr* nreal = new PEFNumber(val);
|
return;
|
||||||
Module::user_defparms.push_back( make_pair(name, nreal) );
|
}
|
||||||
}
|
break;
|
||||||
else {
|
case 'd':
|
||||||
// DEC_NUMBER, something like - scope.parameter=3
|
case 'D':
|
||||||
verinum *val = make_unsized_dec(value);
|
if (is_dec_digit_str(base+1)) {
|
||||||
PExpr* ndec = new PENumber(val);
|
val = make_unsized_dec(num);
|
||||||
Module::user_defparms.push_back( make_pair(name, ndec) );
|
} else {
|
||||||
}
|
cerr << "<command line>: error: invalid digit in decimal value specified for defparam: " << name << endl;
|
||||||
}
|
free(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
if (is_oct_digit_str(base+1)) {
|
||||||
|
val = make_unsized_octal(num);
|
||||||
|
} else {
|
||||||
|
cerr << "<command line>: error: invalid digit in octal value specified for defparam: " << name << endl;
|
||||||
|
free(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
if (is_bin_digit_str(base+1)) {
|
||||||
|
val = make_unsized_binary(num);
|
||||||
|
} else {
|
||||||
|
cerr << "<command line>: error: invalid digit in binary value specified for defparam: " << name << endl;
|
||||||
|
free(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cerr << "<command line>: error: invalid numeric base specified for defparam: " << name << endl;
|
||||||
|
free(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (num != value) { // based number with size
|
||||||
|
*num = 0;
|
||||||
|
if (is_dec_digit_str(value)) {
|
||||||
|
verinum *siz = make_unsized_dec(value);
|
||||||
|
val = pform_verinum_with_size(siz, val, "<command line>", 0);
|
||||||
|
} else {
|
||||||
|
cerr << "<command line>: error: invalid size for value specified for defparam: " << name << endl;
|
||||||
|
free(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PExpr* ndec = new PENumber(val);
|
||||||
|
Module::user_defparms.push_back( make_pair(name, ndec) );
|
||||||
|
free(value);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
free(key);
|
|
||||||
|
// Is it a decimal number?
|
||||||
|
num = (value[0] == '-') ? value + 1 : value;
|
||||||
|
if (is_dec_digit_str(num)) {
|
||||||
|
verinum *val = make_unsized_dec(num);
|
||||||
|
if (value[0] == '-') *val = -(*val);
|
||||||
|
PExpr* ndec = new PENumber(val);
|
||||||
|
Module::user_defparms.push_back( make_pair(name, ndec) );
|
||||||
|
free(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is it a real number?
|
||||||
|
char *end = 0;
|
||||||
|
double rval = strtod(value, &end);
|
||||||
|
if (end != value && *end == 0) {
|
||||||
|
verireal *val = new verireal(rval);
|
||||||
|
PExpr* nreal = new PEFNumber(val);
|
||||||
|
Module::user_defparms.push_back( make_pair(name, nreal) );
|
||||||
|
free(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// None of the above.
|
||||||
|
cerr << "<command line>: error: invalid value specified for defparam: " << name << endl;
|
||||||
free(value);
|
free(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue