Merge branch 'master' into work8

This commit is contained in:
Stephen Williams 2011-09-18 19:48:50 -07:00
commit 52019b0e55
36 changed files with 426 additions and 105 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -705,10 +705,11 @@ int process_generation(const char*name)
fprintf(stderr, "Unknown/Unsupported Language generation "
"%s\n\n", name);
fprintf(stderr, "Supported generations are:\n");
fprintf(stderr, " 1995 -- IEEE1364-1995\n"
" 2001 -- IEEE1364-2001\n"
" 2005 -- IEEE1364-2005\n"
" 2009 -- IEEE1800-2009\n"
fprintf(stderr, " 1995 -- IEEE1364-1995\n"
" 2001 -- IEEE1364-2001\n"
" 2005 -- IEEE1364-2005\n"
" 2005-sv -- IEEE1800-2005\n"
" 2009 -- IEEE1800-2009\n"
"Other generation flags:\n"
" specify | no-specify\n"
" verilog-ams | no-verilog-ams\n"
@ -792,21 +793,28 @@ int main(int argc, char **argv)
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl$(suffix) to finish. */
{ char *s;
char basepath[4096], tmppath[4096];
GetModuleFileName(NULL, tmppath, sizeof tmppath);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmppath, basepath, sizeof basepath);
strncpy(ivl_root, basepath, MAXSIZE);
ivl_root[MAXSIZE-1] = 0;
s = strrchr(ivl_root, sep);
if (s) *s = 0;
s = strrchr(ivl_root, sep);
if (s) *s = 0;
strcat(ivl_root, "\\lib\\ivl" IVL_SUFFIX);
base = ivl_root;
char *s;
char tmppath[MAXSIZE];
GetModuleFileName(NULL, tmppath, sizeof tmppath);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmppath, ivl_root, sizeof ivl_root);
s = strrchr(ivl_root, sep);
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing first %c in exe path!\n",
argv[0], sep);
exit(1);
}
s = strrchr(ivl_root, sep);
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing second %c in exe path!\n",
argv[0], sep);
exit(1);
}
strcat(ivl_root, "\\lib\\ivl" IVL_SUFFIX);
base = ivl_root;
#else
/* In a UNIX environment, the IVL_ROOT from the Makefile is

View File

@ -1853,8 +1853,8 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
expr_type_ = use_enum->base_type();
expr_width_ = use_enum->base_width();
min_width_ = expr_width_;
signed_flag_ = false;
min_width_ = expr_width_;
signed_flag_ = par_enum->has_sign();
return expr_width_;
}
@ -3654,18 +3654,29 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
<< "vector slice." << endl;
des->errors += 1;
return 0;
} else if (t == IVL_VT_REAL) {
} else if (t == IVL_VT_LOGIC || t == IVL_VT_BOOL ||
t == IVL_VT_REAL) {
if (dynamic_cast<NetEConst *> (ip) ||
dynamic_cast<NetECReal*> (ip)) {
/*
* invalid operand: operand is a constant
* or real number
*/
cerr << get_fileline() << ": error: "
<< "inappropriate use of "
<< human_readable_op(op_, true)
<< " operator." << endl;
des->errors += 1;
return 0;
}
/*
* TODO: Need to modify draw_unary_real() to support
* operations on real variables
* **** Valid use of operator ***
* For REAL variables draw_unary_real() is ivoked during
* evaluation and for LOGIC/BOOLEAN draw_unary_expr()
* is called for evaluation.
*/
cerr << get_fileline() << ": sorry: "
<< human_readable_op(op_, true)
<< " operation is not yet supported on "
<< "reals." << endl;
des->errors += 1;
return 0;
} else if (t == IVL_VT_LOGIC || t == IVL_VT_BOOL) {
tmp = new NetEUnary(op_, ip, expr_wid, signed_flag_);
tmp->set_line(*this);
} else {

View File

@ -147,6 +147,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
netenum_t*use_enum = new netenum_t(enum_type->base_type, enum_type->signed_flag,
msb, lsb, enum_type->names->size());
use_enum->set_line(enum_type->li);
scope->add_enumeration_set(use_enum);
verinum cur_value (0);
@ -177,7 +178,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
NetExpr*val = elab_and_eval(des, scope, cur->parm, -1);
NetEConst*val_const = dynamic_cast<NetEConst*> (val);
if (val_const == 0) {
cerr << "<>:0: error: Enumeration expression is not "
cerr << use_enum->get_fileline()
<< ": error: Enumeration expression is not "
"constant." << endl;
des->errors += 1;
continue;
@ -186,14 +188,16 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
if (enum_type->base_type==IVL_VT_BOOL &&
! cur_value.is_defined()) {
cerr << "<>:0: error: Enumeration name " << cur->name
cerr << use_enum->get_fileline()
<< ": error: Enumeration name " << cur->name
<< " cannot have an undefined value." << endl;
des->errors += 1;
continue;
}
} else if (! cur_value.is_defined()) {
cerr << "<>:0: error: Enumeration name " << cur->name
cerr << use_enum->get_fileline()
<< ": error: Enumeration name " << cur->name
<< " cannot have an undefined inferred value." << endl;
des->errors += 1;
continue;
@ -202,7 +206,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
// The enumeration value must fit into the enumeration bits.
if ((cur_value > max_value) ||
(cur_value.has_sign() && (cur_value < min_value))) {
cerr << "<>:0: error: Enumeration name " << cur->name
cerr << use_enum->get_fileline()
<< ": error: Enumeration name " << cur->name
<< " cannot have a value equal to " << cur_value
<< "." << endl;
des->errors += 1;
@ -226,7 +231,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
rc_flag = use_enum->insert_name(name_idx, cur->name, tmp_val);
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
if (! rc_flag) {
cerr << "<>:0: error: Duplicate enumeration name "
cerr << use_enum->get_fileline()
<< ": error: Duplicate enumeration name "
<< cur->name << endl;
des->errors += 1;
}

View File

@ -30,9 +30,12 @@ ivl_discipline_flow
ivl_discipline_name
ivl_discipline_potential
ivl_enum_bits
ivl_enum_file
ivl_enum_lineno
ivl_enum_name
ivl_enum_names
ivl_enum_bits
ivl_enum_signed
ivl_enum_type
ivl_enum_width

View File

@ -652,6 +652,9 @@ extern const char* ivl_nature_name(ivl_nature_t net);
* of the enumeration should match the length of this string. Every
* name also has bits that make up the value.
*
* ivl_enum_signed
* Is the base type for the enum signed?
*
* ivl_enum_type
* Get the data-type for the base type that the enum uses. This
* will be either IVL_VT_BOOL or IVL_VT_LOGIC
@ -664,9 +667,13 @@ extern const char* ivl_nature_name(ivl_nature_t net);
extern unsigned ivl_enum_names(ivl_enumtype_t net);
extern const char*ivl_enum_name(ivl_enumtype_t net, unsigned idx);
extern const char*ivl_enum_bits(ivl_enumtype_t net, unsigned idx);
extern int ivl_enum_signed(ivl_enumtype_t net);
extern ivl_variable_type_t ivl_enum_type(ivl_enumtype_t net);
extern unsigned ivl_enum_width(ivl_enumtype_t net);
extern const char*ivl_enum_file(ivl_enumtype_t net);
extern unsigned ivl_enum_lineno(ivl_enumtype_t net);
/* EVENTS
*
* Events are a unification of named events and implicit events

View File

@ -1,7 +1,7 @@
#ifndef __netenum_H
#define __netenum_H
/*
* Copyright (c) 2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2010-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -22,12 +22,13 @@
# include "ivl_target.h"
# include "verinum.h"
# include "StringHeap.h"
# include "LineInfo.h"
# include <vector>
# include <map>
class NetScope;
class netenum_t {
class netenum_t : public LineInfo {
public:
explicit netenum_t(ivl_variable_type_t base_type, bool signed_flag,
@ -36,6 +37,7 @@ class netenum_t {
ivl_variable_type_t base_type() const;
unsigned base_width() const;
bool has_sign() const;
// The size() is the number of enumeration literals.
size_t size() const;
@ -79,4 +81,6 @@ inline unsigned netenum_t::base_width() const
inline size_t netenum_t::size() const { return names_.size(); }
inline bool netenum_t::has_sign() const { return signed_flag_; }
#endif

18
parse.y
View File

@ -773,28 +773,28 @@ enum_data_type
enum_type->range.reset( make_range_from_width(integer_width) );
$$ = enum_type;
}
| K_enum K_logic range unsigned_signed_opt '{' enum_name_list '}'
| K_enum K_logic unsigned_signed_opt range '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $4;
enum_type->range.reset( $3 );
enum_type->signed_flag = $3;
enum_type->range.reset( $4 );
$$ = enum_type;
}
| K_enum K_reg range unsigned_signed_opt '{' enum_name_list '}'
| K_enum K_reg unsigned_signed_opt range '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $4;
enum_type->range.reset( $3 );
enum_type->signed_flag = $3;
enum_type->range.reset( $4 );
$$ = enum_type;
}
| K_enum K_bit range unsigned_signed_opt '{' enum_name_list '}'
| K_enum K_bit unsigned_signed_opt range '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $4;
enum_type->range.reset( $3 );
enum_type->signed_flag = $3;
enum_type->range.reset( $4 );
$$ = enum_type;
}
;

View File

@ -2508,6 +2508,9 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_st
assert(enum_type->range.get() != 0);
assert(enum_type->range->size() == 2);
// Add the file and line information to the enumeration type.
FILE_NAME(&(enum_type->li), li);
// Attach the enumeration to the current scope.
pform_put_enum_type_in_scope(enum_type);

View File

@ -1,7 +1,7 @@
#ifndef __pform_types_H
#define __pform_types_H
/*
* Copyright (c) 2007-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2007-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -21,6 +21,7 @@
// This for the perm_string type.
# include "StringHeap.h"
# include "LineInfo.h"
# include "verinum.h"
# include "named.h"
# include "ivl_target.h"
@ -67,6 +68,7 @@ struct enum_type_t {
bool signed_flag;
std::auto_ptr< list<PExpr*> > range;
std::auto_ptr< list<named_pexpr_t> > names;
LineInfo li;
};

View File

@ -262,6 +262,24 @@ extern "C" unsigned ivl_enum_width(ivl_enumtype_t net)
return net->base_width();
}
extern "C" int ivl_enum_signed(ivl_enumtype_t net)
{
assert(net);
return net->has_sign();
}
extern "C" const char*ivl_enum_file(ivl_enumtype_t net)
{
assert(net);
return net->get_file().str();
}
extern "C" unsigned ivl_enum_lineno(ivl_enumtype_t net)
{
assert(net);
return net->get_lineno();
}
extern "C" const char* ivl_event_name(ivl_event_t net)
{
static char*name_buffer = 0;
@ -291,7 +309,6 @@ extern "C" const char* ivl_event_basename(ivl_event_t net)
return net->name;
}
extern "C" const char*ivl_event_file(ivl_event_t net)
{
assert(net);

View File

@ -767,6 +767,11 @@ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *containe
set<ivl_nexus_t> test_nexuses;
get_nexuses_from_expr(ivl_stmt_cond_expr(sub_stmt), test_nexuses);
// If the test is not a simple function of one variable then this
// template will not work
if (test_nexuses.size() != 1)
return false;
// Now subtracting this set from the set of edge triggered events
// should leave just one nexus, which is hopefully the clock.
// If not, then we fall back on the default draw_wait

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2010-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -23,13 +23,36 @@
# include <string.h>
# include <assert.h>
// HERE: This still needs work! Fall back to <width>'<signed>b format for
// very large constants. This should also be int64_t sized values.
// The run time still needs to be modified to work with signed values
// and we also need to pass the file and line information.
static void draw_enum2_value(ivl_enumtype_t enumtype, unsigned idx)
{
long val = 0;
long mask = 1;
long val, mask;
const char*bits = ivl_enum_bits(enumtype, idx);
const char*bit;
for (bit = bits, mask = 1 ; bit[0] != 0 ; bit += 1, mask <<= 1) {
unsigned len = strlen(bits);
/* Sign extend if needed. */
if (ivl_enum_signed(enumtype)) {
assert(len <= sizeof(long)*8);
if ((bits[len-1] == '1') && (len < sizeof(long)*8)) {
val = -1L & ~((1L << len) - 1L);
// HERE: Remove once vvp has been updated.
if (ivl_enum_signed(enumtype)) {
fprintf(stderr, "%s:%u: tgt-vvp sorry: signed "
"enumerations with negative values are not "
"currently supported by vvp.\n",
ivl_enum_file(enumtype),
ivl_enum_lineno(enumtype));
vvp_errors += 1;
}
} else val = 0;
} else {
assert(len < sizeof(long)*8);
val = 0;
}
for (bit = bits, mask = 1 ; *bit != 0 ; bit += 1, mask <<= 1) {
if (*bit == '1')
val |= mask;
}
@ -42,7 +65,8 @@ static void draw_enum4_value(ivl_enumtype_t enumtype, unsigned idx)
const char*bits = ivl_enum_bits(enumtype, idx);
const char*bit;
fprintf(vvp_out, "%u'b", ivl_enum_width(enumtype));
fprintf(vvp_out, "%u'%sb", ivl_enum_width(enumtype),
ivl_enum_signed(enumtype) ? "s" : "");
for (bit = bits+strlen(bits) ; bit > bits ; bit -= 1)
fputc(bit[-1], vvp_out);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -25,6 +25,7 @@
# include <stdlib.h>
# include <math.h>
# include <assert.h>
# include <stdbool.h>
static unsigned long word_alloc_mask = 0x0f;
@ -442,6 +443,84 @@ static int draw_ternary_real(ivl_expr_t expr)
return res;
}
static int increment(ivl_expr_t e, int s, bool pre)
{
ivl_signal_t sig;
int r;
int one;
sig = ivl_expr_signal(e);
r = s;
/* create a temporary word to hold value 1.0 */
one = allocate_word();
fprintf(vvp_out, " %%loadi/wr %d, 1, 0x1000; load 1.0\n", one);
if (!pre) {
/*
* post-increment must return the non-incremented value.
* Therefore, copy the current value in a new word and return
* it.
*/
r = allocate_word();
fprintf(vvp_out, " %%mov/wr %d, %d;\n", r, s);
}
fprintf(vvp_out, " %%add/wr %d, %d;\n", s, one);
fprintf(vvp_out, " %%set/wr v%p_0, %d;\n", sig, s);
return r;
}
static inline int pre_increment(ivl_expr_t e, int s)
{
return increment(e, s, true);
}
static inline int post_increment(ivl_expr_t e, int s)
{
return increment(e, s, false);
}
static int decrement(ivl_expr_t e, int s, bool pre)
{
ivl_signal_t sig;
int r;
int one;
sig = ivl_expr_signal(e);
r = s;
/* create a temporary word to hold value 1.0 */
one = allocate_word();
fprintf(vvp_out, " %%loadi/wr %d, 1, 0x1000; load 1.0\n", one);
if (!pre) {
/*
* post-decrement must return the non-incremented value.
* Therefore, copy the current value in a new word and return
* it.
*/
r = allocate_word();
fprintf(vvp_out, " %%mov/wr %d, %d;\n", r, s);
}
fprintf(vvp_out, " %%sub/wr %d, %d;\n", s, one);
fprintf(vvp_out, " %%set/wr v%p_0, %d;\n", sig, s);
return r;
}
static inline int pre_decrement(ivl_expr_t e, int s)
{
return decrement(e, s, true);
}
static inline int post_decrement(ivl_expr_t e, int s)
{
return decrement(e, s, false);
}
static int draw_unary_real(ivl_expr_t expr)
{
ivl_expr_t sube;
@ -494,6 +573,20 @@ static int draw_unary_real(ivl_expr_t expr)
assert(0);
}
switch (ivl_expr_opcode(expr)) {
case 'I':
return pre_increment(sube, sub);
case 'i':
return post_increment(sube, sub);
case 'D':
return pre_decrement(sube, sub);
case 'd':
return post_decrement(sube, sub);
}
fprintf(stderr, "vvp.tgt error: unhandled real unary operator: %c.\n",
ivl_expr_opcode(expr));
assert(0);

View File

@ -47,6 +47,6 @@ in your VHDL code, access packages like this:
use bar.test3.all;
The *.pkg files are just VHDL code containing only the package with
the same name. When Icarus Verilog encounters the "use <lib>.<name>.*;"
the same name. When Icarus Verilog encounters the "use <lib>.<name>.*;"
statement, it looks for the <name>.pkg file in the <lib> library and
parses that file to get the package header declared therin.

View File

@ -87,7 +87,7 @@ clean:
rm -f sdf_lexor.c sdf_parse.c sdf_parse.output sdf_parse.h
rm -f table_mod_parse.c table_mod_parse.h table_mod_parse.output
rm -f table_mod_lexor.c
rm -f va_math.vpi v2005_math.vpi v2009.vpi
rm -f va_math.vpi v2005_math.vpi v2009.vpi vhdl_sys.vpi
distclean: clean
rm -f Makefile config.log

View File

@ -20,6 +20,7 @@
#include <math.h>
#include <string.h>
#include "vpi_user.h"
#include "sv_vpi_user.h"
/*
* This routine returns 1 if the argument supports has a numeric value,
@ -42,6 +43,11 @@ static unsigned is_numeric_obj(vpiHandle obj)
/* These can have a valid numeric value. */
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiMemoryWord:
case vpiNet:
case vpiPartSelect:

View File

@ -916,6 +916,11 @@ static char *get_display(unsigned int *rtnsz, const struct strobe_cb_info *info)
case vpiNet:
case vpiReg:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiIntegerVar:
case vpiMemoryWord:
case vpiPartSelect:
@ -1438,6 +1443,11 @@ static PLI_INT32 sys_monitor_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
case vpiNet:
case vpiReg:
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiRealVar:
case vpiPartSelect:
/* Monitoring reg and net values involves setting
@ -1798,6 +1808,11 @@ static PLI_INT32 sys_printtimescale_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
switch (vpi_get(vpiType, arg)) {
case vpiFunction:
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiMemory:
case vpiMemoryWord:
case vpiModule:

View File

@ -503,11 +503,16 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
item_type = vpi_get(vpiType, item);
switch (item_type) {
case vpiNamedEvent: type = FST_VT_VCD_EVENT; break;
case vpiIntVar:
case vpiIntegerVar: type = FST_VT_VCD_INTEGER; break;
case vpiParameter: type = FST_VT_VCD_PARAMETER; break;
/* Icarus converts realtime to real. */
case vpiRealVar: type = FST_VT_VCD_REAL; break;
case vpiMemoryWord:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiLongIntVar:
case vpiReg: type = FST_VT_VCD_REG; break;
/* Icarus converts a time to a plain register. */
case vpiTimeVar: type = FST_VT_VCD_TIME; break;
@ -572,6 +577,11 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
case vpiNamedEvent:
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiRealVar:
case vpiMemoryWord:
case vpiReg:
@ -791,6 +801,11 @@ static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
* been included. */
switch (item_type) {
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiMemoryWord:
case vpiNamedEvent:
case vpiNet:

View File

@ -557,6 +557,11 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
item = vpi_handle_by_index(array, idx);
}
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiTimeVar:
case vpiReg: type = "reg"; }

View File

@ -620,6 +620,11 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
item = vpi_handle_by_index(array, idx);
}
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiTimeVar:
case vpiReg: type = "reg"; }

View File

@ -109,6 +109,11 @@ static PLI_INT32 sys_value_plusargs_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
case vpiReg:
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiRealVar:
case vpiTimeVar:
break;

View File

@ -169,6 +169,11 @@ unsigned is_numeric_obj(vpiHandle obj)
/* These can have a valid numeric value. */
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiMemoryWord:
case vpiNet:
case vpiPartSelect:
@ -204,6 +209,11 @@ unsigned is_string_obj(vpiHandle obj)
/* These can have a valid string value. */
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiMemoryWord:
case vpiNet:
case vpiPartSelect:

View File

@ -493,6 +493,10 @@ static unsigned is_32_or_smaller_obj(vpiHandle obj)
/* These can have valid 32 bit or smaller numeric values. */
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiMemoryWord:
case vpiNet:
case vpiPartSelect:
@ -518,6 +522,7 @@ static void check_var_arg_32(vpiHandle arg, vpiHandle callh,
switch (vpi_get(vpiType, arg)) {
case vpiMemoryWord:
case vpiPartSelect:
case vpiBitVar:
case vpiReg: // Check that we have exactly 32 bits.
if (vpi_get(vpiSize, arg) != 32) {
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
@ -527,6 +532,7 @@ static void check_var_arg_32(vpiHandle arg, vpiHandle callh,
vpi_control(vpiFinish, 1);
}
case vpiIntegerVar:
case vpiIntVar:
break;
default:
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
@ -548,6 +554,7 @@ static void check_var_arg_large(vpiHandle arg, vpiHandle callh,
switch (vpi_get(vpiType, arg)) {
case vpiMemoryWord:
case vpiPartSelect:
case vpiBitVar:
case vpiReg: // Check that we have at least 32 bits.
if (vpi_get(vpiSize, arg) < 32) {
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
@ -557,6 +564,8 @@ static void check_var_arg_large(vpiHandle arg, vpiHandle callh,
vpi_control(vpiFinish, 1);
}
case vpiIntegerVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiTimeVar:
break;
default:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -374,9 +374,22 @@ static unsigned is_seed_obj(vpiHandle obj, vpiHandle callh, const char *name)
switch (vpi_get(vpiType, obj)) {
case vpiTimeVar:
case vpiIntegerVar:
case vpiReg:
case vpiIntVar:
case vpiLongIntVar:
rtn = 1;
break;
case vpiBitVar:
case vpiReg:
if (vpi_get(vpiSize, obj) < 32) {
vpi_printf("Error: %s:%d: ",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
vpi_printf("%s's seed variable is less than 32 bits "
" (%d).\n", name,
(int)vpi_get(vpiSize, obj));
vpi_control(vpiFinish, 1);
} else rtn = 1;
break;
default:
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2006-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -552,6 +552,11 @@ static int is_assignable_obj(vpiHandle obj)
case vpiPartSelect:
if (! is_assignable_obj(vpi_handle(vpiParent, obj))) break;
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiRealVar:
case vpiReg:
case vpiTimeVar:

View File

@ -532,11 +532,16 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
item_type = vpi_get(vpiType, item);
switch (item_type) {
case vpiNamedEvent: type = "event"; break;
case vpiIntVar:
case vpiIntegerVar: type = "integer"; break;
case vpiParameter: type = "parameter"; break;
/* Icarus converts realtime to real. */
case vpiRealVar: type = "real"; break;
case vpiMemoryWord:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiLongIntVar:
case vpiReg: type = "reg"; break;
/* Icarus converts a time to a plain register. */
case vpiTimeVar: type = "time"; break;
@ -601,12 +606,18 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
case vpiNamedEvent:
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiRealVar:
case vpiMemoryWord:
case vpiReg:
case vpiTimeVar:
case vpiNet:
/* If we are skipping all signal or this is in an automatic
* scope then just return. */
if (skip || vpi_get(vpiAutomatic, item)) return;
@ -787,6 +798,11 @@ static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
* been included. */
switch (item_type) {
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiMemoryWord:
case vpiNamedEvent:
case vpiNet:

View File

@ -189,6 +189,11 @@ PLI_INT32 sys_dumpvars_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
case vpiNet:
case vpiReg:
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
case vpiTimeVar:
case vpiRealVar:
case vpiNamedEvent:

View File

@ -263,18 +263,25 @@ int main(int argc, char*argv[])
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl$(suffix) to finish. */
{ char *s;
char basepath[4096], tmp[4096];
GetModuleFileName(NULL, tmp, sizeof tmp);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmp, basepath, sizeof basepath);
s = strrchr(basepath, '\\');
if (s) *s = 0;
s = strrchr(basepath, '\\');
if (s) *s = 0;
strcat(s, "\\lib\\ivl" IVL_SUFFIX);
vpip_module_path[0] = strdup(basepath);
char *s;
char basepath[4096], tmp[4096];
GetModuleFileName(NULL, tmp, sizeof tmp);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmp, basepath, sizeof basepath);
s = strrchr(basepath, '\\');
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing first \\ in exe path!\n", argv[0]);
exit(1);
}
s = strrchr(basepath, '\\');
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing second \\ in exe path!\n", argv[0]);
exit(1);
}
strcat(s, "\\lib\\ivl" IVL_SUFFIX);
vpip_module_path[0] = strdup(basepath);
#endif
/* For non-interactive runs we do not want to run the interactive

View File

@ -682,10 +682,10 @@ statement
| T_LABEL K_VAR_I local_flag T_STRING ',' T_NUMBER T_NUMBER ';'
{ compile_variable($1, $4, $6, $7, vpiIntegerVar, true, $3); }
| T_LABEL K_VAR_2S local_flag T_STRING ',' T_NUMBER T_NUMBER ';'
| T_LABEL K_VAR_2S local_flag T_STRING ',' signed_t_number signed_t_number ';'
{ compile_variable($1, $4, $6, $7, vpiIntVar, true, $3); }
| T_LABEL K_VAR_2U local_flag T_STRING ',' T_NUMBER T_NUMBER ';'
| T_LABEL K_VAR_2U local_flag T_STRING ',' signed_t_number signed_t_number ';'
{ compile_variable($1, $4, $6, $7, vpiIntVar, false, $3); }
| T_LABEL K_VAR_R T_STRING ',' signed_t_number signed_t_number ';'

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -148,6 +148,11 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
case vpiReg:
case vpiNet:
case vpiIntegerVar:
case vpiBitVar:
case vpiByteVar:
case vpiShortIntVar:
case vpiIntVar:
case vpiLongIntVar:
/* Attach the callback to the vvp_fun_signal node by
putting it in the vpi_callbacks list. */
struct __vpiSignal*sig;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2008-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -256,6 +256,8 @@ static const char* vpi_type_values(PLI_INT32 code)
{
static char buf[32];
switch (code) {
case vpiBitVar:
return "vpiBitVar";
case vpiByteVar:
return "vpiByteVar";
case vpiConstant:

View File

@ -263,7 +263,7 @@ extern unsigned vpip_size(__vpiSignal *sig);
extern struct __vpiScope* vpip_scope(__vpiSignal*sig);
extern vpiHandle vpip_make_int2(const char*name, int msb, int lsb,
vvp_net_t*vec);
bool signed_flag, vvp_net_t*vec);
extern vpiHandle vpip_make_int4(const char*name, int msb, int lsb,
vvp_net_t*vec);
extern vpiHandle vpip_make_var4(const char*name, int msb, int lsb,

View File

@ -270,8 +270,13 @@ static int compare_types(int code, int type)
return 1;
if ( code == vpiVariables &&
(type == vpiIntegerVar ||
type == vpiTimeVar ||
(type == vpiIntegerVar ||
type == vpiBitVar ||
type == vpiByteVar ||
type == vpiShortIntVar ||
type == vpiIntVar ||
type == vpiLongIntVar ||
type == vpiTimeVar ||
type == vpiRealVar))
return 1;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -996,31 +996,39 @@ vpiHandle vpip_make_int4(const char*name, int msb, int lsb, vvp_net_t*vec)
}
/*
* Construct a vpi
* Construct the two-state SystemVerilog variables.
*/
vpiHandle vpip_make_int2(const char*name, int msb, int lsb, vvp_net_t*vec)
vpiHandle vpip_make_int2(const char*name, int msb, int lsb, bool signed_flag,
vvp_net_t*vec)
{
vpiHandle obj = vpip_make_net4(name, msb,lsb, true, vec);
vpiHandle obj = vpip_make_net4(name, msb, lsb, signed_flag, vec);
assert(lsb == 0);
switch (msb) {
case 7:
obj->vpi_type = &vpip_byte_rt;
break;
case 15:
obj->vpi_type = &vpip_shortint_rt;
break;
case 31:
obj->vpi_type = &vpip_int_rt;
break;
case 63:
obj->vpi_type = &vpip_longint_rt;
break;
default:
// Every other type of bit vector is a vpiBitVar with
// array dimensions.
// All unsigned 2-state variables are a vpiBitVar. All 2-state
// variables with a non-zero lsb are also a vpiBitVar.
if ((! signed_flag) || (lsb != 0) ) {
obj->vpi_type = &vpip_bitvar_rt;
break;
} else {
// These could also be bit declarations with matching
// information, but for now they get the apparent type.
switch (msb) {
case 7:
obj->vpi_type = &vpip_byte_rt;
break;
case 15:
obj->vpi_type = &vpip_shortint_rt;
break;
case 31:
obj->vpi_type = &vpip_int_rt;
break;
case 63:
obj->vpi_type = &vpip_longint_rt;
break;
default:
// Every other type of bit vector is a vpiBitVar with
// array dimensions.
obj->vpi_type = &vpip_bitvar_rt;
break;
}
}
return obj;

View File

@ -2034,7 +2034,7 @@ static unsigned long divide2words(unsigned long a, unsigned long b,
remain += 1;
if (remain >= b) {
remain -= b;
result += 1;
tmp_result += 1;
}
// Now 0x1_0...0 = b*tmp_result + remain
@ -2050,7 +2050,9 @@ static unsigned long divide2words(unsigned long a, unsigned long b,
// The new iteration starts with high*remain + a.
remain = multiply_with_carry(high, remain, high);
a = add_with_carry(a, remain, high);
a += remain;
if(a < remain)
high += 1;
// Now result*b + {high,a} == the input {high,a}. It is
// possible that the new high >= 1. If so, it will

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -117,7 +117,7 @@ void compile_variable(char*label, char*name,
obj = vpip_make_int4(name, msb, lsb, net);
break;
case vpiIntVar: // This handles all the atom2 int types
obj = vpip_make_int2(name, msb, lsb, net);
obj = vpip_make_int2(name, msb, lsb, signed_flag, net);
break;
default:
fprintf(stderr, "internal error: %s: vpi_type_code=%d\n", name, vpi_type_code);