From 6c0e1480ff34127137814b309d9b651041b04f16 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 7 May 2009 18:39:09 -0700 Subject: [PATCH 1/6] Fix the %assign/v0/x1 operators for width equal negative offset case. This patch fixes the three %assign/v0/x1 operators to correctly notice that the select has fallen off the start of the vector for the case that the negative offset equaled the width. --- vvp/vthread.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vvp/vthread.cc b/vvp/vthread.cc index ce7b91d33..1b87cbc22 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -1018,7 +1018,7 @@ bool of_ASSIGN_V0X1(vthread_t thr, vvp_code_t cp) if (off >= (long)sig->size()) return true; else if (off < 0 ) { // We fell off the LSB end. - if ((unsigned)-off > wid ) return true; + if ((unsigned)-off >= wid ) return true; // Trim the bits before the LSB wid += off; bit -= off; @@ -1055,7 +1055,7 @@ bool of_ASSIGN_V0X1D(vthread_t thr, vvp_code_t cp) if (off >= (long)sig->size()) return true; else if (off < 0 ) { // We fell off the LSB end. - if ((unsigned)-off > wid ) return true; + if ((unsigned)-off >= wid ) return true; // Trim the bits before the LSB wid += off; bit -= off; @@ -1094,7 +1094,7 @@ bool of_ASSIGN_V0X1E(vthread_t thr, vvp_code_t cp) return true; } else if (off < 0 ) { // We fell off the LSB end. - if ((unsigned)-off > wid ) { + if ((unsigned)-off >= wid ) { thr->event = 0; thr->ecount = 0; return true; From fd2e27fe0f91de10f6d0258932bed5ecaf0dfec2 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 11 May 2009 11:37:06 -0700 Subject: [PATCH 2/6] Document -gsystem-verilog and add -gno-system-verilog --- driver/iverilog.man | 5 +++++ driver/main.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/driver/iverilog.man b/driver/iverilog.man index 05245a5b9..a7a4f743e 100644 --- a/driver/iverilog.man +++ b/driver/iverilog.man @@ -66,6 +66,11 @@ other tools. .TP 8 .B -gverilog-ams\fI|-fP-gno-verilog-ams Enable or disable (default) support for Verilog-AMS. +Very little Verilog-AMS specific functionality is currently supported. +.TP 8 +.B -gsystem-verilog\fI|-fP-gno-system-verilog +Enable or disable (default) support for SystemVerilog. +Very little SystemVerilog specific functionality is currently supported. .TP 8 .B -gspecify\fI|\fP-gno-specify Enable or disable (default) specify block support. When enabled, diff --git a/driver/main.c b/driver/main.c index d53e3ab4c..b97decf7a 100644 --- a/driver/main.c +++ b/driver/main.c @@ -626,6 +626,9 @@ int process_generation(const char*name) else if (strcmp(name,"system-verilog") == 0) gen_system_verilog = "system-verilog"; + else if (strcmp(name,"no-system-verilog") == 0) + gen_verilog_ams = "no-system-verilog"; + else { fprintf(stderr, "Unknown/Unsupported Language generation " "%s\n\n", name); @@ -636,6 +639,7 @@ int process_generation(const char*name) "Other generation flags:\n" " specify | no-specify\n" " verilog-ams | no-verilog-ams\n" + " system-verilog | no-system-verilog\n" " std-include | no-std-include\n" " relative-include | no-relative-include\n" " xtypes | no-xtypes\n" From 9a04f1c3800c4dcaa4318e76bcf646c00591f75e Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 12 May 2009 13:31:20 -0700 Subject: [PATCH 3/6] Add escaping to the stringification of macros. Icarus support returning a string version of a macro ``. The problem was that it did not escape '\' or '"' so if the macro to be escaped had either of these it would create an invalid string. This patch fixes this by translating these two codes to their octal equivalent when the macro is converted. --- ivlpp/lexor.lex | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index a6e652c5e..875e40050 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -1353,10 +1353,17 @@ static void do_expand(int use_args) struct include_stack_t*isp; int head = 0; int tail = 0; + const char *cp; + unsigned escapes = 0; + char *str_buf = 0; if (cur_macro->keyword) { fprintf(yyout, "%s", cur_macro->value); + if (do_expand_stringify_flag) { + do_expand_stringify_flag = 0; + fputc('"', yyout); + } return; } @@ -1385,6 +1392,43 @@ static void do_expand(int use_args) isp->ebs = 0; } + /* Escape some characters if we are making a string version. */ + for (cp = isp->str; (cp = strpbrk(cp, "\"\\")); cp += 1, escapes += 1); + if (escapes && isp->stringify_flag) { + unsigned idx = 0; + str_buf = (char *) malloc(strlen(isp->str)+3*escapes+1); + for (cp = isp->str; *cp; cp += 1) { + if (*cp == '"') { + str_buf[idx] = '\\'; + str_buf[idx+1] = '0'; + str_buf[idx+2] = '4'; + str_buf[idx+3] = '2'; + idx += 4; + continue; + } + if (*cp == '\\') { + str_buf[idx] = '\\'; + str_buf[idx+1] = '1'; + str_buf[idx+2] = '3'; + str_buf[idx+3] = '4'; + idx += 4; + continue; + } + str_buf[idx] = *cp; + idx += 1; + } + str_buf[idx] = 0; + idx += 1; + if (use_args) exp_buf_free += isp->ebs; + exp_buf_grow_to_fit(idx); + head = exp_buf_size - exp_buf_free; + exp_buf_free -= idx; + strcpy(&exp_buf[head], str_buf); + isp->str = &exp_buf[head]; + isp->ebs = idx; + free(str_buf); + } + isp->next = istack; istack->yybs = YY_CURRENT_BUFFER; istack = isp; @@ -1808,4 +1852,5 @@ void destroy_lexor() # endif # endif free(def_buf); + free(exp_buf); } From fe3dd3a559badd9a25993b85040e5afe98041b85 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 14 May 2009 09:32:15 -0700 Subject: [PATCH 4/6] Add support for initializing outputs declared as output reg. The standard allows an output declared as "output reg" to be given an initialization assignment in the output declaration. this patch adds that functionality. Specifically: output reg out = 1'b0; works as expected. --- netmisc.cc | 1 + parse.y | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/netmisc.cc b/netmisc.cc index 4840ca0f2..183d9d47e 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -416,6 +416,7 @@ const char *human_readable_op(const char op, bool unary) case '-': type = "-"; break; case '*': type = "*"; break; case '/': type = "/"; break; + case '%': type = "%"; break; case '<': type = "<"; break; case '>': type = ">"; break; diff --git a/parse.y b/parse.y index 24ef79d2d..764d99ffc 100644 --- a/parse.y +++ b/parse.y @@ -80,6 +80,22 @@ static stack current_block_stack; const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL }; const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; +static list >* make_port_list(char*id, PExpr*expr) +{ + list >*tmp = new list >; + tmp->push_back(make_pair(lex_strings.make(id), expr)); + delete[]id; + return tmp; +} +static list >* make_port_list(list >*tmp, + char*id, PExpr*expr) +{ + tmp->push_back(make_pair(lex_strings.make(id), expr)); + delete[]id; + return tmp; +} + static list* list_from_identifier(char*id) { list*tmp = new list; @@ -146,6 +162,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) strdup. They can be put into lists with the texts type. */ char*text; list*perm_strings; + + list >*port_list; + pform_name_t*pform_name; ivl_discipline_t discipline; @@ -260,7 +279,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) %type udp_initial_expr_opt %type register_variable net_variable real_variable -%type register_variable_list net_variable_list real_variable_list list_of_identifiers +%type register_variable_list net_variable_list +%type real_variable_list list_of_identifiers +%type list_of_port_identifiers %type net_decl_assign net_decl_assigns @@ -1647,6 +1668,17 @@ list_of_identifiers { $$ = list_from_identifier($1, $3); } ; +list_of_port_identifiers + : IDENTIFIER + { $$ = make_port_list($1, 0); } + | IDENTIFIER '=' expression + { $$ = make_port_list($1, $3); } + | list_of_port_identifiers ',' IDENTIFIER + { $$ = make_port_list($1, $3, 0); } + | list_of_port_identifiers ',' IDENTIFIER '=' expression + { $$ = make_port_list($1, $3, $5); } + ; + /* The list_of_ports and list_of_port_declarations rules are the port list formats for module ports. The list_of_ports_opt rule is @@ -1991,9 +2023,20 @@ module_item SR_BOTH); } - | K_output var_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, NetNet::POUTPUT, - IVL_VT_NO_TYPE, 0, SR_BOTH); + | K_output var_type signed_opt range_opt list_of_port_identifiers ';' + { list >::const_iterator pp; + list*tmp = new list; + for (pp = $5->begin(); pp != $5->end(); pp++) { + tmp->push_back((*pp).first); + } + pform_makewire(@1, $4, $3, tmp, $2, NetNet::POUTPUT, + IVL_VT_NO_TYPE, 0, SR_BOTH); + for (pp = $5->begin(); pp != $5->end(); pp++) { + if ((*pp).second) { + pform_make_reginit(@1, (*pp).first, (*pp).second); + } + } + delete $5; } /* var_type declaration (reg variables) cannot be input or output, From 7f20f8c768604d9624864ba97c54c6a38b9ce6c4 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 18 May 2009 10:58:15 -0700 Subject: [PATCH 5/6] Add support for displaying a real parameter using %d. This patch modifies the real parameter get_value routine to use the standard vpip_real_get_value() routine. This routine has support for an integer and a decimal string value. --- vvp/vpi_const.cc | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/vvp/vpi_const.cc b/vvp/vpi_const.cc index 0773a4377..78202e521 100644 --- a/vvp/vpi_const.cc +++ b/vvp/vpi_const.cc @@ -696,16 +696,7 @@ static void real_value(vpiHandle ref, p_vpi_value vp) assert((ref->vpi_type->type_code == vpiConstant) || (ref->vpi_type->type_code == vpiParameter)); - switch (vp->format) { - case vpiObjTypeVal: - vp->format = vpiRealVal; - case vpiRealVal: - vp->value.real = rfp->value; - break; - default: - fprintf(stderr, "vvp error: unsupported format %d.\n", vp->format); - assert(0); - } + vpip_real_get_value(rfp->value, vp); } static const struct __vpirt vpip_real_rt = { From 90d9debe816ec504a66a085c588d2d6201010e93 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 18 May 2009 14:08:09 -0700 Subject: [PATCH 6/6] Display and error for hierarchical references in a parameter r-value expr. Display and error message when the user uses a hierarchical reference in a parameter r-value expression. --- elab_pexpr.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/elab_pexpr.cc b/elab_pexpr.cc index b7e243341..59849ee37 100644 --- a/elab_pexpr.cc +++ b/elab_pexpr.cc @@ -207,6 +207,14 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const name_component_t name_tail = path_.back(); oldpath.pop_back(); + if (path_.size() > 1) { + cerr << get_fileline() << ": error: parameter r-value expression " + "does not support hierarchical references `" << path_ + << "`." << endl; + des->errors += 1; + return 0; + } + NetScope*pscope = scope; if (path_.size() > 0) { list tmp = eval_scope_path(des, scope, oldpath); @@ -229,8 +237,9 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const ivl_assert(*this, pscope); } if (ex == 0) { - cerr << get_fileline() << ": error: identifier ``" << name_tail.name << - "'' is not a parameter in "<< scope_path(scope)<< "." << endl; + cerr << get_fileline() << ": error: identifier `" + << name_tail.name << "` is not a parameter in " + << scope_path(scope)<< "." << endl; des->errors += 1; return 0; }