From 5311aeaa1983fbc8d9ffe538ffda96e7043eefc0 Mon Sep 17 00:00:00 2001 From: Prasad Joshi Date: Fri, 19 Aug 2011 14:02:35 +0530 Subject: [PATCH 01/20] Operand of increment/decrement should not be a number The patch adds necessary error checking to verify that the operands of increment decrement operator is not number. Signed-off-by: Prasad Joshi --- elab_expr.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/elab_expr.cc b/elab_expr.cc index 4c92faf91..009edd6fa 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3646,6 +3646,16 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, des->errors += 1; return 0; } else if (t == IVL_VT_LOGIC || t == IVL_VT_BOOL) { + if (dynamic_cast (ip)) { + /* invalid operand: operand is a constant number */ + cerr << get_fileline() << ": error: " + << "inappropriate use of " + << human_readable_op(op_, true) + << " operator." << endl; + des->errors += 1; + return 0; + } + tmp = new NetEUnary(op_, ip, expr_wid, signed_flag_); tmp->set_line(*this); } else { From 95d58cbc42418ec8ff534a84fb50dd89c1c73b35 Mon Sep 17 00:00:00 2001 From: Prasad Joshi Date: Sun, 21 Aug 2011 08:59:41 +0530 Subject: [PATCH 02/20] Real variable support for increment/decrement operator Signed-off-by: Prasad Joshi --- elab_expr.cc | 29 +++++++------- tgt-vvp/eval_real.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 009edd6fa..ec2bc5643 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3634,20 +3634,15 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, << "vector slice." << endl; des->errors += 1; return 0; - } else if (t == IVL_VT_REAL) { - /* - * TODO: Need to modify draw_unary_real() to support - * operations on real variables - */ - 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) { - if (dynamic_cast (ip)) { - /* invalid operand: operand is a constant number */ + } else if (t == IVL_VT_LOGIC || t == IVL_VT_BOOL || + t == IVL_VT_REAL) { + + if (dynamic_cast (ip) || + dynamic_cast (ip)) { + /* + * invalid operand: operand is a constant + * or real number + */ cerr << get_fileline() << ": error: " << "inappropriate use of " << human_readable_op(op_, true) @@ -3656,6 +3651,12 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, return 0; } + /* + * **** 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. + */ tmp = new NetEUnary(op_, ip, expr_wid, signed_flag_); tmp->set_line(*this); } else { diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index f5f9dfe59..933210da8 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -25,6 +25,7 @@ # include # include # include +# include 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); From b16401301e069469a989e4af4f11a2c9b8ea88f4 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 23 Aug 2011 18:27:34 -0700 Subject: [PATCH 03/20] For MinGW report an error of the two \\ are not found in the exe path We need to print a message and fail if the two \\ characters are not found in the executable path. --- vvp/main.cc | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/vvp/main.cc b/vvp/main.cc index 68e0ef42c..cb2f63d5b 100644 --- a/vvp/main.cc +++ b/vvp/main.cc @@ -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 From e49b796a5157ea0a3cfbcaf3e65ee8a935602756 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 28 Aug 2011 17:10:43 +0100 Subject: [PATCH 04/20] Fix for pr3397689. This is caused by a bug in some simple pattern matching the VHDL target does to try and produce more idiomatic code in common cases (e.g. FFs with asynchronous resets in this case). This patch just restricts the kinds of if-statements we use this optimisation for. --- tgt-vhdl/stmt.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc index 1053ed00f..7581113df 100644 --- a/tgt-vhdl/stmt.cc +++ b/tgt-vhdl/stmt.cc @@ -767,6 +767,11 @@ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *containe set 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 From f3522e98f1300c34c5e4771c6d2b04861cb3a5f7 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 1 Sep 2011 09:34:29 -0700 Subject: [PATCH 05/20] For MinGW driver report an error if the two \\ are not found in the exe path We need to print a message and fail if the two \\ characters are not found in the executable path. Also update the generation warning to include -g2005-sv. --- driver/main.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/driver/main.c b/driver/main.c index 73c0d666e..0409166d3 100644 --- a/driver/main.c +++ b/driver/main.c @@ -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 From b2ebc29c5a1082425fde42501676a8bd988f9a9e Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 1 Sep 2011 14:29:40 -0700 Subject: [PATCH 06/20] Fix some enum bugs. This patch fixes a few more bugs in the enumeration code. It add support for saving the file and line information to make diagnostic messages better. It updates some of the compiler warning messages to use the file and line information. It passes if the enumeration type is signed all the way to the code generators. It fixes the parser to correctly have the range after the signed designation for the vector types. It adds a warning that vvp does not currently support a negative two state enumeration value. --- elab_expr.cc | 4 ++-- elab_scope.cc | 16 +++++++++++----- ivl.def | 5 ++++- ivl_target.h | 7 +++++++ netenum.h | 8 ++++++-- parse.y | 18 +++++++++--------- pform.cc | 3 +++ pform_types.h | 4 +++- t-dll-api.cc | 19 ++++++++++++++++++- tgt-vvp/draw_enum.c | 34 +++++++++++++++++++++++++++++----- 10 files changed, 92 insertions(+), 26 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index ec2bc5643..20e7b4f4c 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1833,8 +1833,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_; } diff --git a/elab_scope.cc b/elab_scope.cc index da9030141..e1492c331 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -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 (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; } diff --git a/ivl.def b/ivl.def index b942383d1..ebc1844fe 100644 --- a/ivl.def +++ b/ivl.def @@ -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 diff --git a/ivl_target.h b/ivl_target.h index f63852a2f..d46454cd4 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -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 diff --git a/netenum.h b/netenum.h index d89a45595..b88f75918 100644 --- a/netenum.h +++ b/netenum.h @@ -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 # include 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 diff --git a/parse.y b/parse.y index a75c4f893..90d1233ef 100644 --- a/parse.y +++ b/parse.y @@ -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; } ; diff --git a/pform.cc b/pform.cc index 05ddc3314..82bb894ce 100644 --- a/pform.cc +++ b/pform.cc @@ -2508,6 +2508,9 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, listrange.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); diff --git a/pform_types.h b/pform_types.h index 61a41d4f2..609641e1f 100644 --- a/pform_types.h +++ b/pform_types.h @@ -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 > range; std::auto_ptr< list > names; + LineInfo li; }; diff --git a/t-dll-api.cc b/t-dll-api.cc index 4a7a67a94..d6d1f08a0 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -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); diff --git a/tgt-vvp/draw_enum.c b/tgt-vvp/draw_enum.c index 6567e1c86..61ad79604 100644 --- a/tgt-vvp/draw_enum.c +++ b/tgt-vvp/draw_enum.c @@ -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 # include +// HERE: This still needs work! Fall back to '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); From ca6af1c20d4853f3cac5546ac1319b16fe4a8621 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 1 Sep 2011 14:32:07 -0700 Subject: [PATCH 07/20] Fix some space issues. --- tgt-vvp/eval_real.c | 6 +++--- vhdlpp/README.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 933210da8..ce8c10d22 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -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 @@ -457,7 +457,7 @@ static int increment(ivl_expr_t e, int s, bool pre) 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. @@ -496,7 +496,7 @@ static int decrement(ivl_expr_t e, int s, bool pre) 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. diff --git a/vhdlpp/README.txt b/vhdlpp/README.txt index 2007dd436..e904d94c0 100644 --- a/vhdlpp/README.txt +++ b/vhdlpp/README.txt @@ -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 ..*;" +the same name. When Icarus Verilog encounters the "use ..*;" statement, it looks for the .pkg file in the library and parses that file to get the package header declared therin. From 40c37be3072fe4dbc71734014a6d3b4cfd57f83d Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 14:40:31 -0700 Subject: [PATCH 08/20] Display the type name for bit variable (vpiBitVar). Display vpiBitVar instead of 620 when asking for the type name of a bit variable. --- vvp/vpi_priv.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index 5696344e1..a009be2fa 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -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: From 4f8cace5a97752365d09da2054b6f2988838f2d6 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 14:55:58 -0700 Subject: [PATCH 09/20] Add the ability to place callbacks on bit, byte, short, int and long variables. You can place a callback on the new SystemVerilog 2-state variables. --- vvp/vpi_callback.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index 201b3aa12..1ff3b9352 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -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; From 9fb317a4e1772c26700ea6d5a9fbd6657ea68681 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 16:10:08 -0700 Subject: [PATCH 10/20] A vpiBitVar can have a non-zero LSB and can be unsigned. The general bit variable can be either signed or unsigned and can have a non-zero LSB. --- vvp/parse.y | 4 ++-- vvp/vpi_priv.h | 2 +- vvp/vpi_signal.cc | 52 +++++++++++++++++++++++++++-------------------- vvp/words.cc | 4 ++-- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/vvp/parse.y b/vvp/parse.y index 23bab0337..5b7a310f1 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -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 ';' diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 71c859fbc..68272c41c 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -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, diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index f51ccee52..08df4e1ce 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -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; diff --git a/vvp/words.cc b/vvp/words.cc index 9485cc257..a1168223f 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -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); From 45d8925ad2be0dbc882d40eb9ed20d9716f986f4 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 16:25:05 -0700 Subject: [PATCH 11/20] Add the ability to $display and $monitor a bit, byte, short, int or long var. Add code so that we can $display and $monitor the two-state variables. --- vpi/sys_display.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vpi/sys_display.c b/vpi/sys_display.c index 5b8e5af6b..184db2454 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -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 From e7a705d8e6227c96b32a70afd8d6843ac469a072 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 17:19:38 -0700 Subject: [PATCH 12/20] The $queue routines can use two-state variables. Update the various $queue routines to use the appropriate two-state variables depending on the context. --- vpi/sys_queue.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vpi/sys_queue.c b/vpi/sys_queue.c index f7312c0fc..c45fb63ec 100644 --- a/vpi/sys_queue.c +++ b/vpi/sys_queue.c @@ -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: From 57f296455a62694db133d4925b59c5e0b87bc428 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 17:17:13 -0700 Subject: [PATCH 13/20] The $value$plusargs() routine can put to a two-state variable. Update the $value_plusargs() routine so it can put the extracted value to a two-state variable. --- vpi/sys_plusargs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vpi/sys_plusargs.c b/vpi/sys_plusargs.c index f4aeae324..f1d5e23f3 100644 --- a/vpi/sys_plusargs.c +++ b/vpi/sys_plusargs.c @@ -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; From dc0e66ab90b848142d9747f370fa42c2a10b60d5 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 17:11:40 -0700 Subject: [PATCH 14/20] Update $clog2() to add support for two-state variables. The $clog2() routine can consider any two state variable argument as numeric. --- vpi/sys_clog2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vpi/sys_clog2.c b/vpi/sys_clog2.c index ee29c6105..e19aeecc4 100644 --- a/vpi/sys_clog2.c +++ b/vpi/sys_clog2.c @@ -20,6 +20,7 @@ #include #include #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: From 746a21b437b25e0a2f82b57177d2aafd1bce07db Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 17:23:22 -0700 Subject: [PATCH 15/20] Update the $random routines to allow an int, long or bit as a seed. Modify the $random code to allow the seed to be either an int, long or bit that is 32 bits or longer. The 32 bit check is new and also applies to reg/logic variables. --- vpi/sys_random.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/vpi/sys_random.c b/vpi/sys_random.c index 67d10ad9a..2193b3140 100644 --- a/vpi/sys_random.c +++ b/vpi/sys_random.c @@ -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)); From 507621ef3001dbc6ed9c8f65587a4f7274b766c4 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 5 Sep 2011 17:35:26 -0700 Subject: [PATCH 16/20] Update $scanf, $printtimescale and the general is_numeric check for 2-state This patch updates the $scanf and $printtimescale routines to work with two-state variables. It also updates the general is_numeric check to recognize two-state variables as numeric. --- vpi/sys_display.c | 5 +++++ vpi/sys_priv.c | 10 ++++++++++ vpi/sys_scanf.c | 7 ++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/vpi/sys_display.c b/vpi/sys_display.c index 184db2454..cf315c97c 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -1808,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: diff --git a/vpi/sys_priv.c b/vpi/sys_priv.c index a71971cd8..f14d5f285 100644 --- a/vpi/sys_priv.c +++ b/vpi/sys_priv.c @@ -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: diff --git a/vpi/sys_scanf.c b/vpi/sys_scanf.c index 896a2af0a..440661eba 100644 --- a/vpi/sys_scanf.c +++ b/vpi/sys_scanf.c @@ -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: From dd9962c2210884ad4a542c36f1dcd7950c23045a Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 6 Sep 2011 08:58:25 -0700 Subject: [PATCH 17/20] The two-state variables are in the vpiVariable category. Add all the two-state variables (bit, byte, short, int and long) to the vpiVariable category. --- vvp/vpi_scope.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/vvp/vpi_scope.cc b/vvp/vpi_scope.cc index 45afce324..084cd064f 100644 --- a/vvp/vpi_scope.cc +++ b/vvp/vpi_scope.cc @@ -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; From 83831882928bf834211b2c5b702f15e68f45161b Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 6 Sep 2011 09:23:42 -0700 Subject: [PATCH 18/20] Add support to dump the two-state variables. Add support to dump the two-state variables (bit, byte, short, int and long) using the fst, lxt, lxt2 and vcd dumpers. --- vpi/sys_fst.c | 15 +++++++++++++++ vpi/sys_lxt.c | 5 +++++ vpi/sys_lxt2.c | 5 +++++ vpi/sys_vcd.c | 16 ++++++++++++++++ vpi/vcd_priv.c | 5 +++++ 5 files changed, 46 insertions(+) diff --git a/vpi/sys_fst.c b/vpi/sys_fst.c index 4e0e5a8f0..228e4ea04 100644 --- a/vpi/sys_fst.c +++ b/vpi/sys_fst.c @@ -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: diff --git a/vpi/sys_lxt.c b/vpi/sys_lxt.c index 1576229f8..7879cba81 100644 --- a/vpi/sys_lxt.c +++ b/vpi/sys_lxt.c @@ -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"; } diff --git a/vpi/sys_lxt2.c b/vpi/sys_lxt2.c index 3032f6345..0a558138c 100644 --- a/vpi/sys_lxt2.c +++ b/vpi/sys_lxt2.c @@ -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"; } diff --git a/vpi/sys_vcd.c b/vpi/sys_vcd.c index e027608af..22ba24621 100644 --- a/vpi/sys_vcd.c +++ b/vpi/sys_vcd.c @@ -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: diff --git a/vpi/vcd_priv.c b/vpi/vcd_priv.c index dcbb59fbe..e95a87309 100644 --- a/vpi/vcd_priv.c +++ b/vpi/vcd_priv.c @@ -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: From 64e16d34f385c90cd427d7242e42e3565cf7b967 Mon Sep 17 00:00:00 2001 From: Cary R Date: Wed, 7 Sep 2011 16:22:29 -0700 Subject: [PATCH 19/20] Add vhdl_sys.vpi to the make clean target --- vpi/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpi/Makefile.in b/vpi/Makefile.in index ee0542bc1..f692a37c7 100644 --- a/vpi/Makefile.in +++ b/vpi/Makefile.in @@ -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 From 766bf45dcfa1536b8d46d0a798612e375a4eb10e Mon Sep 17 00:00:00 2001 From: Alexander Klimov Date: Thu, 15 Sep 2011 00:33:12 +0300 Subject: [PATCH 20/20] Fix long division. On a 64-bit machine the following module shows incorrect division results: `define X {4'b 1000, `N'b 0} `define Y {1'b 1, `N'b 0} module b; reg [`N:0] y = `Y; reg [3:0] z1, z2; initial begin z1 = `X / `Y; z2 = `X / y; $display("%3d %b %b", `N, z1, z2); end endmodule // b $ for N in {60..65}; do /usr/bin/iverilog -DN=$N -oa b.v && /usr/bin/vvp a; done 60 1000 1000 61 1000 1000 62 1000 0111 63 1000 0101 64 1000 1000 65 1000 1000 The first chunk of the patch (result -> tmp_result) fixes this: $ for N in {60..65}; do iverilog -DN=$N -oa b.v && vvp a; done 60 1000 1000 61 1000 1000 62 1000 1000 63 1000 1000 64 1000 1000 65 1000 1000 The second chunk fixes `define X 264'h 800000000000000000000000000000000000000000000000000000000000000000 `define Y 192'h c6df998d06b97b0db1f056638484d609c0895e8112153524 module c; reg [191:0] y = `Y; reg [72:0] z1, z2; initial begin z1 = `X / `Y; z2 = `X / y; $display("%x %x %b", z1, z2, z1 == z2); end endmodule // c $ /usr/bin/iverilog -oa c.v && /usr/bin/vvp a 0a4c4a2c1dacd76220c 0809033397ca3427927 0 $ iverilog -oa c.v && vvp a 0a4c4a2c1dacd76220c 0a4c4a2c1dacd76220c 1 --- vvp/vthread.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vvp/vthread.cc b/vvp/vthread.cc index a6042f652..78980de0e 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -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