diff --git a/PDelays.cc b/PDelays.cc index 8e9ea79fc..b7cecf0c6 100644 --- a/PDelays.cc +++ b/PDelays.cc @@ -124,6 +124,9 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr) static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr) { + if (expr == 0) + return 0; + if (dynamic_cast (expr)) return expr; diff --git a/elab_expr.cc b/elab_expr.cc index 1146921a4..7a7c9fa70 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1868,6 +1868,36 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) return expr_width_; } + // The width of a specparam is the width of the specparam value + // (as evaluated earlier). Note that specparams aren't fully + // supported yet, so this code is likely to need rework when + // they are. + if (gn_specify_blocks_flag) { + map::const_iterator specp; + perm_string key = peek_tail_name(path_); + if (path_.size() == 1 + && ((specp = scope->specparams.find(key)) != scope->specparams.end())) { + NetScope::spec_val_t value = (*specp).second; + if (value.type == IVL_VT_REAL) { + expr_type_ = IVL_VT_REAL; + expr_width_ = 1; + min_width_ = 1; + signed_flag_ = true; + } else { + verinum val (value.integer); + expr_type_ = IVL_VT_BOOL; + expr_width_ = val.len(); + min_width_ = expr_width_; + signed_flag_ = true; + + if (mode < LOSSLESS) + mode = LOSSLESS; + + } + return expr_width_; + } + } + // Not a net, and not a parameter? Give up on the type, but // set the width to 0. expr_type_ = IVL_VT_NO_TYPE; diff --git a/elaborate.cc b/elaborate.cc index d5b97cb51..dcb561b49 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -852,7 +852,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const cerr << get_fileline() << ": error: " << "Expression width " << sig->vector_width() << " does not match width " << instance_width - << " of logic gate array port " << idx + << " of logic gate array port " << idx+1 << "." << endl; des->errors += 1; } diff --git a/vpi/fstapi.c b/vpi/fstapi.c index 69278f6c6..8ed5af6f3 100644 --- a/vpi/fstapi.c +++ b/vpi/fstapi.c @@ -3357,6 +3357,7 @@ uint64_t previous_time = UINT64_MAX; uint64_t *time_table = NULL; uint64_t tsec_nitems; int secnum = 0; +int blocks_skipped = 0; off_t blkpos = 0; uint64_t seclen, beg_tim, end_tim; uint64_t frame_uclen, frame_clen, frame_maxhandle, vc_maxhandle; @@ -3419,6 +3420,7 @@ for(;;) { if(beg_tim < xc->limit_range_start) { + blocks_skipped++; blkpos += seclen; continue; } @@ -3506,7 +3508,7 @@ for(;;) if(secnum == 0) { - if(beg_tim != time_table[0]) + if((beg_tim != time_table[0]) || (blocks_skipped)) { unsigned char *mu = malloc(frame_uclen); uint32_t sig_offs = 0; diff --git a/vpi/sys_queue.c b/vpi/sys_queue.c index 13b35e220..f7312c0fc 100644 --- a/vpi/sys_queue.c +++ b/vpi/sys_queue.c @@ -84,9 +84,12 @@ uint64_t calc_average_wait_time(uint64_t high, uint64_t low, uint64_t total) /* It's a big value so calculate the average the long way. */ do { + unsigned carry = 0U; /* Copy bits from low to high until we have a bit to place * in the result or there are no bits left. */ - while ((bit >= 0) && (high < total)) { + while ((bit >= 0) && (high < total) && !carry) { + /* If the MSB is set then we will have a carry. */ + if (high > (UINT64_MAX >> 1)) carry = 1U; high <<= 1; high |= (low & 0x8000000000000000) != 0; low <<= 1; diff --git a/vpi/table_mod.c b/vpi/table_mod.c index ff2e09070..dc41ae03e 100644 --- a/vpi/table_mod.c +++ b/vpi/table_mod.c @@ -348,7 +348,7 @@ static unsigned initialize_control_fields(vpiHandle callh, p_table_mod table, table->have_ctl = 1; /* Look for the dependent data field. */ - cp = index(control, ';'); + cp = strchr(control, ';'); if (cp) { size_t len; unsigned long val; @@ -385,7 +385,7 @@ static unsigned initialize_control_fields(vpiHandle callh, p_table_mod table, /* Find the number of interpolation/extrapolation control fields. */ num_fields = 1; cp = control; - while ((cp = index(cp, ','))) { + while ((cp = strchr(cp, ','))) { cp += 1; num_fields += 1; } diff --git a/vpi/table_mod_parse.y b/vpi/table_mod_parse.y index d2c004c5a..700d1265c 100644 --- a/vpi/table_mod_parse.y +++ b/vpi/table_mod_parse.y @@ -24,21 +24,85 @@ #include "table_mod.h" #include "ivl_alloc.h" +/* + * The number of parse errors encountered while parsing the data file. + */ static unsigned errors = 0; + +/* + * The minimum number of columns needed in the data file to satisfy the + * control string/input variable requirements. + */ static unsigned minimum_columns; + +/* + * The number of independent values we expect to keep based on the control + * string/independent variables. + */ static unsigned indep_values; + +/* + * The total number of independent columns to expect. This includes any + * ignored columns. + */ static unsigned indep_columns; + +/* + * The zero based dependent column location. This is just minimum_columns - 1. + */ static unsigned dep_column; + +/* + * The number of columns to expect in this data file. This must be + * greater than or equal to the minimum_columns above. + */ static unsigned number_of_columns = 0; + +/* + * The number of columns that this point currently has. + */ static unsigned cur_columns; + +/* + * The zero based current independent value we are looking for. + */ static unsigned cur_value; + +/* + * The usable values for this point. The independent values are first and + * the dependent value is the last entry. + */ static double *values; + +/* + * The name of the file we are getting data from. + */ static const char *in_file_name; + +/* + * The table structure that we are getting data for. + */ static p_table_mod table_def; +/* + * The lexor and error routines. + */ extern int tblmodlex(void); static void yyerror(const char *fmt, ...); +static void process_point() +{ + assert(cur_value == indep_values); + #if 0 + unsigned idx; + fprintf(stderr, "%#g", values[0]); + for (idx = 1; idx < indep_values; idx += 1) { + fprintf(stderr, ", %#g", values[idx]); + } + fprintf(stderr, " => %#g\n", values[indep_values]); + #endif +} + %} %locations @@ -52,19 +116,23 @@ static void yyerror(const char *fmt, ...); %% + /* + * A table is just a bunch of points. The lexor ignores any comments. + */ table : point | table point + /* + * An individual point is just a bunch of columns followed by one or more + * end of line characters. + */ point : columns END_LINE { - #if 0 - unsigned idx; - fprintf(stderr, "%#g", values[0]); - for (idx = 1; idx < indep_values; idx += 1) { - fprintf(stderr, ", %#g", values[idx]); - } - fprintf(stderr, " => %#g\n", values[indep_values]); - #endif + /* + * If the number of columns has been defined then we must have + * enough columns and we expect every line to have the same + * number of columns. + */ if (number_of_columns) { if (cur_columns < minimum_columns) { yyerror("Found %u columns, need at least %u.", @@ -72,15 +140,26 @@ point : columns END_LINE } else if (cur_columns != number_of_columns) { yyerror("Found %u columns, expected %u.", cur_columns, number_of_columns); - } + } else process_point(); + /* + * If this is the first point then we must have enough columns. + * If there are enough then we define this to be the number of + * columns that the file must have. + */ } else { if (cur_columns < minimum_columns) { yyerror("Found %u columns, need at least %u.", cur_columns, minimum_columns); - } else number_of_columns = cur_columns; + } else { + number_of_columns = cur_columns; + process_point(); + } } } + /* + * Each column is a real value. We only save the columns we care about. + */ columns : REAL { if (table_def->control.info.interp[0] != IVL_IGNORE_COLUMN) { @@ -103,12 +182,17 @@ columns : REAL %% +/* + * Setup the various variables, then parse the input file and then cleanup + * the lexor and the allocated memory. + */ unsigned parse_table_model(FILE *fp, vpiHandle callh, p_table_mod table) { unsigned rtn = 0; assert(table); assert(table->fields > 0); assert(table->depend > 0); + /* Initialize the variables used by the parser. */ table_def = table; indep_values = table->dims; indep_columns = table->fields; @@ -117,7 +201,9 @@ unsigned parse_table_model(FILE *fp, vpiHandle callh, p_table_mod table) values = malloc(sizeof(double)*(indep_values+1)); assert(values); in_file_name = table->file.name; + /* Parse the input file. */ init_tblmod_lexor(fp); + /* If there are errors then print a message. */ if (yyparse()) errors += 1; if (errors) { vpi_printf("ERROR: %s:%u: ", vpi_get_str(vpiFile, callh), @@ -125,14 +211,15 @@ unsigned parse_table_model(FILE *fp, vpiHandle callh, p_table_mod table) vpi_printf("Had %u error(s) while reading table file.\n", errors); rtn = 1; } + /* Cleanup the lexor and allocated memory. */ destroy_tblmod_lexor(); free(values); return rtn; } /* - * Because every parse error is reported after the newline subtract one from - * the line count. + * Currently every parse error is reported after the newline so subtract + * one from the line count. */ void yyerror(const char *fmt, ...) { diff --git a/vvp/ivl_dlfcn.h b/vvp/ivl_dlfcn.h index ef68d9bb0..1406482d7 100644 --- a/vvp/ivl_dlfcn.h +++ b/vvp/ivl_dlfcn.h @@ -1,7 +1,7 @@ #ifndef __ivl_dlfcn_H #define __ivl_dlfcn_H /* - * 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 @@ -33,7 +33,15 @@ typedef shl_t ivl_dll_t; #if defined(__MINGW32__) inline ivl_dll_t ivl_dlopen(const char *name, bool global_flag) -{ return (void *)LoadLibrary(name); } +{ + static char full_name[4096]; + unsigned long length = GetFullPathName(name, sizeof(full_name), + full_name, NULL); + if ((length == 0) || (length > sizeof(full_name))) + return 0; + + return (void *)LoadLibrary(full_name); +} inline void *ivl_dlsym(ivl_dll_t dll, const char *nm) { return (void *)GetProcAddress((HINSTANCE)dll,nm);} diff --git a/vvp/main.cc b/vvp/main.cc index a81664e72..68e0ef42c 100644 --- a/vvp/main.cc +++ b/vvp/main.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 @@ -266,7 +266,7 @@ int main(int argc, char*argv[]) { char *s; char basepath[4096], tmp[4096]; GetModuleFileName(NULL, tmp, sizeof tmp); - /* Convert to a short na,e to remove any embedded spaces. */ + /* Convert to a short name to remove any embedded spaces. */ GetShortPathName(tmp, basepath, sizeof basepath); s = strrchr(basepath, '\\'); if (s) *s = 0; diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index e76789f7a..7eee8f9c7 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.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 @@ -742,6 +742,7 @@ void print_vpi_call_errors() free(vpi_call_error_lst[idx].name); } free(vpi_call_error_lst); + fflush(stderr); } #ifdef CHECK_WITH_VALGRIND