Compare commits

...

20 Commits

Author SHA1 Message Date
Stephen Williams 4205752bb0 Clean up release builder scripts.
The version.h file is generated by the Makefile, we should
prefill the version_tag.h file.
2009-03-20 14:29:18 -07:00
Cary R d237e35076 Make vvp use inttypes for the 64 bit printing info.
To get the correct print format for a 64 bit value it is much
better to use <inttypes.h> (when available) than building our
own value. This allows MinGW to use the non-standard I64.
2009-03-20 13:58:32 -07:00
Stephen Williams 90f37fe3cb Slightly more portable version of configure test. 2009-03-19 18:31:21 -07:00
Stephen Williams 4be2f61b53 Get ready for the 0.9 first release. 2009-03-19 10:17:12 -07:00
Purdea Andrei f8aa9073ac fixing: %0b format prints nothing for a 0 input
the following example returns ||. This patch fixes it to return |0|.
module t();
wire [3:0] b;
initial
    $monitor("|%0b|", b);
assign b = 0;
endmodule
(cherry picked from commit c9d2400dd0)
2009-03-19 09:11:49 -07:00
Cary R 9ea20d6677 Cleanup lxt and lxt2 EOS data.
This patch cleans up the memory allocated in the lxt and lxt2
$dumpvars routines.
(cherry picked from commit be158dd45f)
2009-03-19 09:05:05 -07:00
Cary R 9fec1f7e45 Handle zero repetition in a synthesized concatenation.
It is valid to have a repetition of zero inside a concatenation
that has other elements with a defined width. This patch adds
this functionality to the synthesize method. It also prints
an error if you try to synthesize a zero width constant.
(cherry picked from commit fa8a3d6c2e)
2009-03-17 16:04:49 -07:00
Stephen Williams c47ea0721c fix the arithmetic of multi-word division.
The Multiword division was not handling some degenerate high
guesses for the intermediate division result guess. The end result
was an assertion. Recover from this case.

(Does the addinb back of bp need to be optimized better?)
(cherry picked from commit 6715426833)
2009-03-17 16:04:28 -07:00
Stephen Williams ef12137931 Pass unsigned-ness of arithmetic operators through operands.
The arithmetic operands are signed only if both operands are signed.
If the expression is unsigned, then the expression as a whole needs
to be processed as unsigned in order to get padding right.
(cherry picked from commit c4a62dee0d)
2009-03-17 16:04:09 -07:00
Larry Doolittle 0e8a12eebf Don't make useless arrays of nexa
When a pin array is virtual, dll_target::signal() doesn't need
to make a corresponding set of stub nexa.

This patch includes new detection of oversized arrays, configurable
with the ARRAY_SIZE_LIMIT flag.  This limit only applies to devirtualized
arrays; virtual arrays are only limited by your architecture's
unsigned int type.

The concept and earlier versions of this patch have been successfully
stress-tested by multiple people.  This one causes no testsuite
regressions on my machine.

Closes: pr2023076
(cherry picked from commit 3a18bda8ee)
2009-03-15 13:54:08 -07:00
Cary R 9473e823ed You must assert a logical not NULL.
This fixes a small problem where an assert was being called
with NULL instead of 0.
(cherry picked from commit ac4cb1bbe9)
2009-03-15 13:53:55 -07:00
Larry Doolittle c75f9db315 Add user interface to pin virtualization
Flag is DISABLE_VIRTUAL_PINS.  Try to give a helpful hint for
how to work around any problems our regression testing might
have missed.
(cherry picked from commit 67381431ed)
2009-03-15 13:53:41 -07:00
Larry Doolittle 1d31a91b4f Remove valgrind errors triggered by virtual pins
NetBus wasn't initializing pin direction.
I hope Link::PASSIVE is correct for busses!
No test suite regressions.
(cherry picked from commit f344515e38)
2009-03-15 13:53:28 -07:00
Larry Doolittle b795d8c1d8 Virtualize Pins until needed
Reduces resource usage when compiling large memories.
Normal usage patterns still create large nexus arrays
in t-dll.cc:dll_target::signal().

This patch is extensively tested; it shouldn't break anything.

The existing debug "optimizer" flag is (ab)used to control
message printing when large (>1000 element) arrays are
devirtualized or nexus-ized.

The new global variable disable_virtual_pins is available
to force allocation of Pin arrays when they are declared,
but no user interface is provided.

See extensive discussion on iverilog-devel, March 4-5 2009,
title "pr2023076: large memories".
(cherry picked from commit 5bc41e1a17)
2009-03-15 13:52:57 -07:00
Larry Doolittle 5ec7731e04 Detect overflows converting to long
The code is ugly, but the results are good.
No regressions in existing testsuite, needs a new entry.
2009-03-13 15:17:51 -07:00
Larry Doolittle bb29e1d588 Drop useless CVS stuff in .txt files
Remove useless, redundant, misleading, and misspelled $Id$ and $Log$
cruft from all .txt files.
(cherry picked from commit 86bf6c447b)
2009-03-13 09:42:17 -07:00
Larry Doolittle 74fd1865cb Minor tweaks ahead of memory virtualization
Limit memory sizes to whatever fits in unsigned; crash if
the conversion from unsigned long to unsigned overflows,
instead of just wrapping.  I don't know what happens on
a 32-bit machine if you ask for an 8 Gig memory, but with
a 64-bit machine and this patch, it crashes with an assert.

Set direction on PartSelect Links before connecting them.

May or may not be considered orthogonal to upcoming
memory virtualization patches.
2009-03-09 14:46:13 -07:00
Larry Doolittle b40b6fb50d Spelling fixes
Mostly comments, but includes user-visible debug messages.
(cherry picked from commit b0c4a87133)
2009-03-09 14:44:07 -07:00
Stephen Williams 19b68f6332 Fix broken definition of is_linked().
(cherry picked from commit fff2598709)
2009-03-09 14:43:18 -07:00
Cary R c96e4da9e4 More constant function not supported warnings.
This patch adds more places that need to warn about constant
functions not being available.
2009-03-05 17:09:43 -08:00
42 changed files with 417 additions and 263 deletions

View File

@ -2,7 +2,6 @@
CADENCE PLI1 MODULES
Copyright 2003 Stephen Williams
$Id: cadpli.txt,v 1.2 2003/02/17 00:01:25 steve Exp $
With the cadpli module, Icarus Verilog is able to load PLI1
applications that were compiled and linked to be dynamic loaded by
@ -34,15 +33,3 @@ the +loadpli1= argument to Verilog-XL.
The integration from this point is seamless. The PLI application
hardly knows that it is being invoked by Icarus Verilog instead of
Verilog-XL, so operates as it would otherwise.
$Log: cadpli.txt,v $
Revision 1.2 2003/02/17 00:01:25 steve
Use a variant of ivl_dlfcn to do dynamic loading
from within the cadpli module.
Change the +cadpli flag to -cadpli, to keep the
plusargs namespace clear.
Revision 1.1 2003/02/16 02:44:47 steve
Add the cadpli HOWTO.

View File

@ -89,6 +89,12 @@ extern bool debug_elab_pexpr;
extern bool debug_synth2;
extern bool debug_optimizer;
/* Possibly temporary flag to control virtualization of pin arrays */
extern bool disable_virtual_pins;
/* Limit to size of devirtualized arrays */
extern unsigned long array_size_limit;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;

View File

@ -181,21 +181,21 @@ AX_C_UNDERSCORES_TRAILING
#######################
AC_MSG_CHECKING(for sanity of prefix)
if test X`echo "$prefix" | wc -w` != X1
if test `echo "$prefix" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in prefix: $prefix)
fi
AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of exec_prefix)
if test X`echo "$exec_prefix" | wc -w` != X1
if test `echo "$exec_prefix" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix)
fi
AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of libdir)
if test X`echo "$libdir" | wc -w` != X1
if test `echo "$libdir" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
fi

View File

@ -208,8 +208,12 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " scope=" << scope_path(scope());
o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count()
<< " init=";
<< " pin_count=" << pin_count();
if (pins_are_virtual()) {
o << " pins_are_virtual" << endl;
return;
}
o << " init=";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << pin(idx-1).get_init();

View File

@ -686,7 +686,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
}
// Special case: shift is negative (so do a left shift)
// and is greater then the output width. Replace the
// and is greater than the output width. Replace the
// expression with a constant-0.
if (shift < 0 && (0-shift) >= use_wid) {
if (debug_elaborate)
@ -1790,7 +1790,9 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
two bit select expressions, and both must be
constant. Evaluate them and pass the results back to
the caller. */
need_constant_expr = true;
NetExpr*lsb_ex = elab_and_eval(des, scope, index_tail.lsb, lsb_wid);
need_constant_expr = false;
NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
if (lsb_c == 0) {
cerr << index_tail.lsb->get_fileline() << ": error: "
@ -1808,7 +1810,9 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
lsb = lsb_c->value().as_long();
}
need_constant_expr = true;
NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, msb_wid);
need_constant_expr = false;
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
if (msb_c == 0) {
cerr << index_tail.msb->get_fileline() << ": error: "
@ -1845,7 +1849,9 @@ bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
/* Calculate the width expression (in the lsb_ position)
first. If the expression is not constant, error but guess 1
so we can keep going and find more errors. */
need_constant_expr = true;
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
need_constant_expr = false;
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
if (wid_c == 0) {
@ -2259,7 +2265,7 @@ NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
if (! parts_defined_flag) {
if (debug_elaborate)
cerr << get_fileline() << ": debug: Part select of paramter "
cerr << get_fileline() << ": debug: Part select of parameter "
<< "has x/z bits, so resorting to 'bx result." << endl;
long wid = 1 + labs(par_msv-par_lsv);
@ -2394,7 +2400,9 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
/* Get and evaluate the width of the index
select. This must be constant. */
need_constant_expr = true;
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
need_constant_expr = false;
NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
if (wid_ec == 0) {
cerr << index_tail.lsb->get_fileline() << ": error: "

View File

@ -220,7 +220,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
case index_component_t::SEL_IDX_DO:
case index_component_t::SEL_IDX_UP: {
need_constant_expr = true;
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
need_constant_expr = false;
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) {
cerr << get_fileline() << ": error: indexed part select of "
@ -437,7 +439,9 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
}
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
need_constant_expr = true;
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
need_constant_expr = false;
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) {
cerr << get_fileline() << ": error: array " << sig->name()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 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
@ -496,7 +496,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// use) the genvar itself, so we can evaluate this expression
// the same way any other parameter value is evaluated.
probe_expr_width(des, container, loop_init);
need_constant_expr = true;
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
need_constant_expr = false;
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
if (init == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -526,7 +528,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
container->genvar_tmp = loop_index;
container->genvar_tmp_val = genvar;
probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
if (test == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -579,7 +583,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// Calculate the step for the loop variable.
probe_expr_width(des, container, loop_step);
need_constant_expr = true;
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
need_constant_expr = false;
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
if (step == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -611,7 +617,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
{
probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
if (test == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -671,7 +679,9 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
{
probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
if (case_value_co == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar case"
@ -702,9 +712,17 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
bool match_flag = false;
for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) {
probe_expr_width(des, container, item->item_test[idx]);
need_constant_expr = true;
NetExpr*item_value_ex = elab_and_eval(des, container, item->item_test[idx], -1);
need_constant_expr = false;
NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
assert(item_value_co);
if (item_value_co == 0) {
cerr << get_fileline() << ": error: Cannot evaluate "
<< " genvar case item expression: "
<< *item->item_test[idx] << endl;
des->errors += 1;
return false;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate case "
@ -952,8 +970,10 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
{
if (msb_) probe_expr_width(des, sc, msb_);
if (lsb_) probe_expr_width(des, sc, lsb_);
need_constant_expr = true;
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
need_constant_expr = false;
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);

View File

@ -843,8 +843,8 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
/*
* Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the
* multiple properties of a wire (i.e., "input wire") so come the
* elaboration this creates an object in the design that represent the
* multiple properties of a wire (i.e., "input wire"), so come the
* elaboration this creates an object in the design that represents the
* defined item.
*/
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
@ -1108,6 +1108,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
? new NetNet(scope, name_, wtype, msb, lsb, array_s0, array_e0)
: new NetNet(scope, name_, wtype, msb, lsb);
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
ivl_variable_type_t use_data_type = data_type_;
if (use_data_type == IVL_VT_NO_TYPE) {
use_data_type = IVL_VT_LOGIC;

View File

@ -234,8 +234,10 @@ unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
gates, then I am expected to make more than one
gate. Figure out how many are desired. */
if (msb_) {
need_constant_expr = true;
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1);
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1);
need_constant_expr = false;
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);

View File

@ -133,7 +133,7 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: "
<< "Partially evalutate " << *this
<< "Partially evaluate " << *this
<< " using (a+2)-1 --> (a+1) transform." << endl;
}

View File

@ -719,16 +719,20 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
/* First, synthesize the operands. */
unsigned nparms = parms_.count();
NetNet**tmp = new NetNet*[parms_.count()];
bool flag = true;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
if (tmp[idx] == 0)
flag = false;
if (parms_[idx]->expr_width() == 0) {
tmp[idx] = 0;
nparms -= 1;
} else {
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
if (tmp[idx] == 0) flag = false;
}
}
if (flag == false)
return 0;
if (flag == false) return 0;
ivl_assert(*this, tmp[0]);
@ -740,7 +744,7 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
osig->vector_width(),
parms_.count() * repeat());
nparms * repeat());
concat->set_line(*this);
des->add_node(concat);
connect(concat->pin(0), osig->pin(0));
@ -750,7 +754,7 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
for (unsigned rpt = 0; rpt < repeat(); rpt += 1) {
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
unsigned concat_item = parms_.count()-idx-1;
ivl_assert(*this, tmp[concat_item]);
if (tmp[concat_item] == 0) continue;
connect(concat->pin(cur_pin), tmp[concat_item]->pin(0));
cur_pin += 1;
count_input_width += tmp[concat_item]->vector_width();
@ -773,6 +777,11 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*)
{
perm_string path = scope->local_symbol();
unsigned width=expr_width();
if (width == 0) {
cerr << get_fileline() << ": internal error: "
<< "Found a zero width constant!" << endl;
return 0;
}
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true);

View File

@ -499,65 +499,3 @@ already seems to exist amongst VCD viewers in the wild, this behavior
seems to be acceptable according to the standard, is a better mirror
of 4-value behavior in the dead zone, and appears more user friendly
when viewed by reasonable viewers.
$Id: ieee1364-notes.txt,v 1.19 2007/04/18 02:36:13 steve Exp $
$Log: ieee1364-notes.txt,v $
Revision 1.19 2007/04/18 02:36:13 steve
Put to iverilog wiki for further notes.
Revision 1.18 2007/03/22 16:08:16 steve
Spelling fixes from Larry
Revision 1.17 2003/07/15 03:49:22 steve
Spelling fixes.
Revision 1.16 2003/04/14 03:40:21 steve
Make some effort to preserve bits while
operating on constant values.
Revision 1.15 2003/02/16 23:39:08 steve
NaN in dead zones of VCD dumps.
Revision 1.14 2003/02/06 17:51:36 steve
Edge of vectors notes.
Revision 1.13 2002/08/20 04:11:53 steve
Support parameters with defined ranges.
Revision 1.12 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.11 2002/04/27 02:38:04 steve
Support selecting bits from parameters.
Revision 1.10 2002/03/31 01:54:13 steve
Notes about scheduling
Revision 1.9 2002/01/26 02:08:07 steve
Handle x in l-value of set/x
Revision 1.8 2001/08/01 05:17:31 steve
Accept empty port lists to module instantiation.
Revision 1.7 2001/02/17 05:27:31 steve
I allow function ports to have types.
Revision 1.6 2001/02/12 16:48:04 steve
Rant about bit widths.
Revision 1.5 2001/01/02 17:28:08 steve
Resolve repeat ambiguity in favor of loop.
Revision 1.4 2001/01/01 19:12:35 steve
repeat loops ambiguity.
Revision 1.3 2000/12/15 00:21:46 steve
rounding of time and x in primitives.
Revision 1.2 2000/11/19 22:03:04 steve
Integer parameter comments.
Revision 1.1 2000/07/23 18:06:31 steve
Document ieee1364 issues.

View File

@ -2,7 +2,6 @@
Icarus Verilog LOADABLE TARGET API (ivl_target)
Copyright 2002 Stephen Williams <steve@icarus.com>
$Id: ivl_target.txt,v 1.3 2002/06/11 03:34:33 steve Exp $
The ivl_target API is the interface available to modules that the
@ -38,14 +37,3 @@ other LPM device with outputs.
There are ivl_lpm_size() input ports, each with the width
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().
$Log: ivl_target.txt,v $
Revision 1.3 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.2 2002/03/17 19:31:17 steve
Add API to support user defined function.
Revision 1.1 2002/03/09 02:10:22 steve
Add the NetUserFunc netlist node.

11
main.cc
View File

@ -128,6 +128,12 @@ bool debug_elab_pexpr = false;
bool debug_synth2 = false;
bool debug_optimizer = false;
/*
* Miscellaneous flags.
*/
bool disable_virtual_pins = false;
unsigned long array_size_limit = 16777216; // Minimum required by IEEE-1364?
/*
* Verbose messages enabled.
*/
@ -709,6 +715,11 @@ int main(int argc, char*argv[])
cout << endl << "PARSING INPUT" << endl;
}
const char *flag_tmp = flags["DISABLE_VIRTUAL_PINS"];
if (flag_tmp) disable_virtual_pins = strcmp(flag_tmp,"true")==0;
flag_tmp = flags["ARRAY_SIZE_LIMIT"];
if (flag_tmp) array_size_limit = strtoul(flag_tmp,NULL,0);
/* Parse the input. Make the pform. */
int rc = pform_parse(argv[optind]);

View File

@ -173,7 +173,7 @@ void Link::unlink()
bool Link::is_equal(const Link&that) const
{
return (node_ == that.node_) && (pin_ == that.pin_);
return (get_obj() == that.get_obj()) && (get_pin() == that.get_pin());
}
bool Link::is_linked() const

View File

@ -172,26 +172,51 @@ Link* find_next_output(Link*lnk)
return 0;
}
NetPins::NetPins(unsigned npins)
: npins_(npins)
void NetPins::devirtualize_pins(void)
{
if (pins_) return;
if (npins_ > array_size_limit) {
cerr << get_fileline() << ": error: pin count " << npins_ <<
" exceeds " << array_size_limit <<
" (set by -pARRAY_SIZE_LIMIT)" << endl;
assert(0);
}
if (debug_optimizer && npins_ > 1000) cerr << "debug: devirtualizing " << npins_ << " pins." << endl;
pins_ = new Link[npins_];
pins_[0].pin_zero_ = true;
pins_[0].node_ = this;
pins_[0].dir_ = default_dir_;
pins_[0].init_ = default_init_;
for (unsigned idx = 1 ; idx < npins_ ; idx += 1) {
pins_[idx].pin_zero_ = false;
pins_[idx].pin_ = idx;
pins_[idx].dir_ = default_dir_;
pins_[idx].init_ = default_init_;
}
}
bool NetPins::pins_are_virtual(void) const
{
return pins_ == NULL;
}
NetPins::NetPins(unsigned npins)
: npins_(npins)
{
pins_ = NULL; // Wait until someone asks.
if (disable_virtual_pins) devirtualize_pins(); // Ask. Bummer.
}
NetPins::~NetPins()
{
delete[]pins_;
if (pins_) delete[]pins_;
}
Link& NetPins::pin(unsigned idx)
{
if (!pins_) devirtualize_pins();
if (idx >= npins_) {
cerr << get_fileline() << ": internal error: pin("<<idx<<")"
<< " out of bounds("<<npins_<<")" << endl;
@ -207,11 +232,27 @@ Link& NetPins::pin(unsigned idx)
const Link& NetPins::pin(unsigned idx) const
{
if (!pins_ && !disable_virtual_pins) {
cerr << get_fileline() << ": internal error: pin is unexpectedly"
" virtual, try again with -pDISABLE_VIRTUAL_PINS=true" << endl;
assert(0);
}
assert(pins_);
assert(idx < npins_);
assert(idx == 0? pins_[0].pin_zero_ : pins_[idx].pin_==idx);
return pins_[idx];
}
void NetPins::set_default_dir(Link::DIR d)
{
default_dir_ = d;
}
void NetPins::set_default_init(verinum::V val)
{
default_init_ = val;
}
bool NetPins::is_linked(void)
{
bool linked_flag = false;
@ -228,6 +269,11 @@ bool NetPins::is_linked(void)
NetObj::NetObj(NetScope*s, perm_string n, unsigned np)
: NetPins(np), scope_(s), name_(n), delay1_(0), delay2_(0), delay3_(0)
{
/* Don't
ivl_assert(*this, np > 0);
* because it would happen before we get to print a useful
* message in the NetNet constructor
*/
}
NetObj::~NetObj()
@ -269,6 +315,9 @@ NetBranch::~NetBranch()
NetBus::NetBus(NetScope*s, unsigned pin_count__)
: NetObj(s, perm_string::literal(""), pin_count__)
{
for (unsigned idx = 0 ; idx <pin_count__ ; idx += 1) {
pin(idx).set_dir(Link::PASSIVE);
}
}
NetBus::~NetBus()
@ -479,7 +528,11 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
void NetNet::initialize_value_and_dir(verinum::V init_value, Link::DIR dir)
{
if (1) {
if (pins_are_virtual()) {
if (0) cerr << "NetNet setting Link default value and dir" << endl;
set_default_init(init_value);
set_default_dir(dir);
} else {
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(dir);
pin(idx).set_init(init_value);
@ -524,10 +577,16 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
static unsigned calculate_count(long s, long e)
{
if (s >= e)
return s - e + 1;
else
return e - s + 1;
unsigned long r;
if (s >= e) {
r = s - e;
} else {
r = e - s;
}
if (r >= UINT_MAX) {
return 0;
}
return r + 1;
}
NetNet::NetNet(NetScope*s, perm_string n, Type t,
@ -538,7 +597,11 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
discipline_(0), msb_(ms), lsb_(ls), dimensions_(1), s0_(array_s), e0_(array_e),
local_flag_(false), eref_count_(0), lref_count_(0)
{
assert(s);
ivl_assert(*this, s);
if (pin_count() == 0) {
cerr << "Array too big [" << array_s << ":" << array_e << "]" << endl;
ivl_assert(*this, 0);
}
verinum::V init_value = verinum::Vz;
Link::DIR dir = Link::PASSIVE;
@ -732,7 +795,9 @@ bool NetNet::array_addr_swapped() const
unsigned NetNet::array_count() const
{
return calculate_count(s0_, e0_);
unsigned c = calculate_count(s0_, e0_);
ivl_assert(*this, c > 0);
return c;
}
bool NetNet::array_index_is_valid(long sb) const
@ -810,7 +875,6 @@ NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
: NetNode(sig->scope(), sig->scope()->local_symbol(), 2),
off_(off), wid_(wid), dir_(dir__)
{
connect(pin(1), sig->pin(0));
set_line(*sig);
switch (dir_) {
@ -823,6 +887,8 @@ NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
pin(1).set_dir(Link::OUTPUT);
break;
}
connect(pin(1), sig->pin(0));
}
NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel,
@ -830,9 +896,6 @@ NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel,
: NetNode(sig->scope(), sig->scope()->local_symbol(), 3),
off_(0), wid_(wid), dir_(VP)
{
connect(pin(1), sig->pin(0));
connect(pin(2), sel->pin(0));
switch (dir_) {
case NetPartSelect::VP:
pin(0).set_dir(Link::OUTPUT);
@ -844,6 +907,9 @@ NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel,
break;
}
pin(2).set_dir(Link::INPUT);
connect(pin(1), sig->pin(0));
connect(pin(2), sel->pin(0));
}
NetPartSelect::~NetPartSelect()

View File

@ -193,11 +193,17 @@ class NetPins : public LineInfo {
const Link&pin(unsigned idx) const;
void dump_node_pins(ostream&, unsigned, const char**pin_names =0) const;
void set_default_dir(Link::DIR d);
void set_default_init(verinum::V val);
bool is_linked();
bool pins_are_virtual(void) const;
void devirtualize_pins(void);
private:
Link*pins_;
const unsigned npins_;
Link::DIR default_dir_;
verinum::V default_init_;
};
/* =========
@ -3256,6 +3262,7 @@ class NetEBAdd : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBAdd* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
@ -3278,6 +3285,7 @@ class NetEBDiv : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBDiv* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
@ -3408,6 +3416,7 @@ class NetEBMult : public NetEBinary {
virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBMult* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);

View File

@ -16,7 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: netlist.txt,v 1.10 2000/07/23 18:06:15 steve Exp $"
Note that the netlist.h header contains detailed descriptions of how
@ -291,49 +290,3 @@ values. These are filled in during scope elaboration and are used in
subsequent elaboration phases to arrange for scaling of delays. This
information can also be used by the code generator to scale times back
to the units of the scope, if that is desired.
$Log: netlist.txt,v $
Revision 1.10 2000/07/23 18:06:15 steve
Document time scale in netlists.
Revision 1.9 2000/07/14 06:12:57 steve
Move inital value handling from NetNet to Nexus
objects. This allows better propogation of inital
values.
Clean up constant propagation a bit to account
for regs that are not really values.
Revision 1.8 2000/03/08 04:36:54 steve
Redesign the implementation of scopes and parameters.
I now generate the scopes and notice the parameters
in a separate pass over the pform. Once the scopes
are generated, I can process overrides and evalutate
paremeters before elaboration begins.
Revision 1.7 1999/11/28 23:42:02 steve
NetESignal object no longer need to be NetNode
objects. Let them keep a pointer to NetNet objects.
Revision 1.6 1999/11/21 00:13:09 steve
Support memories in continuous assignments.
Revision 1.5 1999/11/02 04:55:34 steve
Add the synthesize method to NetExpr to handle
synthesis of expressions, and use that method
to improve r-value handling of LPM_FF synthesis.
Modify the XNF target to handle LPM_FF objects.
Revision 1.4 1999/09/29 00:03:27 steve
Spelling fixes from Larry.
Revision 1.3 1999/07/24 02:11:20 steve
Elaborate task input ports.
Revision 1.2 1999/07/21 01:15:29 steve
Document netlist semantics.
Revision 1.1 1999/05/27 04:13:08 steve
Handle expression bit widths with non-fatal errors.

65
scripts/MAKE_RELEASE.sh Normal file
View File

@ -0,0 +1,65 @@
#!/bin/sh
# This script makes a release from a git repository. The input is
# the number for a snapshot and the path to a temporary directory.
# for example:
#
# sh scripts/MAKE_RELEASE.sh 0.9.1 ~/tmp
#
# The above assumes that there is a tag "v0_9_1" at the point
# to be released. (The tag has the "v", but the argument to this
# script does not have the "v"). This script extracts based on the
# tag, uses the temporary directory to stage intermediate results,
# and finally creates a file called verilog-0.9.1.tar.gz that
# contains the release ready to go.
#
# The complete steps to make a release x.y.z generally are:
#
# git tag -a v0_9_1
# (Make the tag in the local git repository.)
#
# sh scripts/MAKE_RELEASE.sh 0.9.1 ~/tmp
# (Make the snapshot bundle verilog-0.9.1.tar.gz)
#
# git push --tags
# (Publish the tag to the repository.)
#
id=$1
destdir=$2
# The git tag to use.
tag="v"`echo $id | tr '.' '_'`
# The prefix is the directory that contains the extracted files
# of the bundle. This is also the name of the bundle file itself.
prefix="verilog-$id"
if [ ! -d $destdir ]; then
echo "ERROR: Directory $destdir does not exist."
exit 1
fi
if [ -e $destdir/$prefix ]; then
echo "ERROR: $destdir/$prefix already exists."
exit 1
fi
echo "Exporting $tag to $destdir/$prefix..."
git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - )
versionh="$destdir/$prefix/version_tag.h"
echo "Create $versionh ..."
echo "#ifndef VERSION_TAG" > $versionh
echo "#define VERSION_TAG \"$tag\"" >> $versionh
echo "#endif" >> $versionh
echo "Running autoconf.sh..."
( cd $destdir/$prefix && sh autoconf.sh )
echo "Making bundle $prefix.tar.gz..."
tar czf $prefix.tar.gz --exclude=autom4te.cache -C "$destdir" $prefix
echo "Removing temporary $destdir/$prefix..."
rm -rf "$destdir/$prefix"
echo done

View File

@ -47,9 +47,11 @@ fi
echo "Exporting $tag to $destdir/$prefix..."
git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - )
versionh="$destdir/$prefix/version.h"
versionh="$destdir/$prefix/version_tag.h"
echo "Create $versionh ..."
echo "#define VERSION_TAG \"$tag\"" > $versionh
echo "#ifndef VERSION_TAG" > $versionh
echo "#define VERSION_TAG \"$tag\"" >> $versionh
echo "#endif" >> $versionh
echo "Running autoconf.sh..."
( cd $destdir/$prefix && sh autoconf.sh )

View File

@ -106,6 +106,18 @@ bool NetEBAdd::set_width(unsigned w, bool)
return wid == w;
}
void NetEBAdd::cast_signed(bool sign_flag)
{
if (has_sign() == sign_flag)
return;
if (sign_flag == false) {
left_->cast_signed(sign_flag);
right_->cast_signed(sign_flag);
}
cast_signed_base_(sign_flag);
}
/*
* The bitwise logical operators have operands the same size as the
* result. Anything else is a mess. I first try to get the operands to
@ -168,6 +180,19 @@ bool NetEBDiv::set_width(unsigned w, bool)
return w == expr_width();
}
void NetEBDiv::cast_signed(bool sign_flag)
{
if (has_sign() == sign_flag)
return;
if (sign_flag == false) {
left_->cast_signed(sign_flag);
right_->cast_signed(sign_flag);
}
cast_signed_base_(sign_flag);
}
bool NetEBLogic::set_width(unsigned w, bool)
{
bool flag;
@ -192,6 +217,19 @@ bool NetEBMult::set_width(unsigned w, bool)
return true;
}
void NetEBMult::cast_signed(bool sign_flag)
{
if (has_sign() == sign_flag)
return;
if (sign_flag == false) {
left_->cast_signed(sign_flag);
right_->cast_signed(sign_flag);
}
cast_signed_base_(sign_flag);
}
bool NetEBPow::set_width(unsigned w, bool last_chance)
{
return w == expr_width();

View File

@ -1,5 +1,3 @@
# $Id: README-solaris_pkg.txt,v 1.3 2007/02/26 19:49:49 steve Exp $
Notes about the solaris package.
I. Installing a prebuilt solaris package

View File

@ -1893,10 +1893,16 @@ extern "C" const char* ivl_signal_name(ivl_signal_t net)
extern "C" ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word)
{
assert(word < net->array_words);
if (net->array_words > 1)
return net->pins[word];
else
if (net->array_words > 1) {
if (net->pins) {
return net->pins[word];
} else {
cerr << "AACK! ivl_signal_nex() returning NULL" << endl;
return NULL;
}
} else {
return net->pin;
}
}
extern "C" int ivl_signal_msb(ivl_signal_t net)

View File

@ -2560,12 +2560,22 @@ void dll_target::signal(const NetNet*net)
obj->array_base = net->array_first();
obj->array_words = net->array_count();
obj->array_addr_swapped = net->array_addr_swapped() ? 1 : 0;
assert(obj->array_words == net->pin_count());
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: "
"t-dll creating nexus array " << obj->array_words << " long" << endl;
if (obj->array_words > 1 && net->pins_are_virtual()) {
obj->pins = NULL;
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: "
"t-dll used NULL for big nexus array" << endl;
return;
}
if (obj->array_words > 1)
obj->pins = new ivl_nexus_t[obj->array_words];
for (unsigned idx = 0 ; idx < obj->array_words ; idx += 1) {
const Nexus*nex = net->pin(idx).nexus();
const Nexus*nex = net->pins_are_virtual() ? 0 : net->pin(idx).nexus();
if (nex == 0) {
// Special case: This pin is connected to
// nothing. This can happen, for example, if the
@ -2597,6 +2607,7 @@ void dll_target::signal(const NetNet*net)
obj->pin = tmp;
}
}
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: t-dll done with big nexus array" << endl;
}
bool dll_target::signal_paths(const NetNet*net)

View File

@ -2,7 +2,6 @@
FPGA LOADABLE CODE GENERATOR FOR Icarus Verilog
Copyright 2001 Stephen Williams
$Id: fpga.txt,v 1.12 2005/09/19 21:45:36 steve Exp $
The FPGA code generator supports a variety of FPGA devices, writing
XNF or EDIF depending on the target. You can select the architecture
@ -186,42 +185,3 @@ Compile a single-file design with command line tools like so:
% map -o map.ncd foo.ngd
% par -w map.ncd foo.ncd
---
$Log: fpga.txt,v $
Revision 1.12 2005/09/19 21:45:36 steve
Spelling patches from Larry.
Revision 1.11 2003/08/07 05:17:34 steve
Add arch=lpm to the documentation.
Revision 1.10 2003/07/04 03:57:19 steve
Allow attributes on Verilog 2001 port declarations.
Revision 1.9 2003/07/04 01:08:03 steve
PAD attribute can be used to assign pins.
Revision 1.8 2003/07/02 00:26:49 steve
Fix spelling of part= flag.
Revision 1.7 2003/03/24 02:28:38 steve
Document the virtex2 architecture.
Revision 1.6 2003/03/24 00:47:54 steve
Add new virtex2 architecture family, and
also the new edif.h EDIF management functions.
Revision 1.5 2002/04/30 04:26:42 steve
Spelling errors.
Revision 1.4 2001/09/16 22:26:47 steve
Support the cellref attribute.
Revision 1.3 2001/09/16 01:48:16 steve
Suppor the PAD attribute on signals.
Revision 1.2 2001/09/06 04:28:40 steve
Separate the virtex and generic-edif code generators.
Revision 1.1 2001/09/02 23:58:49 steve
Add documentation for the code generator.

View File

@ -552,7 +552,7 @@ static void get_nexuses_from_expr(ivl_expr_t expr, set<ivl_nexus_t> &out)
/*
* Attempt to identify common forms of wait statements and produce
* more idiomatic VHDL than would be produced by the generic
* draw_wait funciton. The main application of this is a input to
* draw_wait function. The main application of this is a input to
* synthesis tools that don't synthesise the full VHDL language.
* If none of these patterns are matched, the function returns false
* and the default draw_wait is used.

View File

@ -1853,7 +1853,7 @@ static struct vector_info draw_number_expr(ivl_expr_t exp, unsigned wid)
/*
* This little helper function generates the instructions to pad a
* vector in place. It is assumed that the calling functio has set up
* vector in place. It is assumed that the calling function has set up
* the first sub_sidth bits of the dest vector, and the signed_flag is
* true if the extension is to be signed.
*/
@ -2456,7 +2456,7 @@ static void draw_select_expr_dest(ivl_expr_t exp, struct vector_info dest,
/* If the shift expression is not present, then this is really
a pad expression, and that can be handled pretty
easily. Evalutate the subexpression into the destination,
easily. Evaluate the subexpression into the destination,
then pad in place. */
if (shift == 0) {
struct vector_info subv;

View File

@ -10,11 +10,11 @@
#
Summary: Icarus Verilog
Name: verilog%{suff}
Version: 0.9.0.%{rev_date}
Version: 0.9.1
Release: 0
License: GPL
Group: Productivity/Scientific/Electronics
Source: verilog%{suff}-%{rev_date}.tar.gz
Source: verilog%{suff}-%{version}.tar.gz
URL: http://www.icarus.com/eda/verilog/index.html
Packager: Stephen Williams <steve@icarus.com>
@ -32,7 +32,7 @@ engineering formats, including simulation. It strives to be true
to the IEEE-1364 standard.
%prep
%setup -n verilog%{suff}-%{rev_date}
%setup -n verilog%{suff}-%{version}
%build
if test X%{suff} != X

View File

@ -419,6 +419,7 @@ uint64_t verinum::as_ulong64() const
*/
signed long verinum::as_long() const
{
#define IVLLBITS (8 * sizeof(long) - 1)
if (nbits_ == 0)
return 0;
@ -426,33 +427,43 @@ signed long verinum::as_long() const
return 0;
signed long val = 0;
unsigned diag_top = 0;
unsigned top = nbits_;
if (top > IVLLBITS) {
diag_top = top;
top = IVLLBITS;
}
int lost_bits=0;
if (has_sign_ && (bits_[nbits_-1] == V1)) {
unsigned top = nbits_;
if (top > (8 * sizeof(long) - 1))
top = 8 * sizeof(long) - 1;
val = -1;
signed long mask = ~1L;
for (unsigned idx = 0 ; idx < top ; idx += 1) {
if (bits_[idx] == V0)
val &= mask;
if (bits_[idx] == V0) val &= mask;
mask = (mask << 1) | 1L;
}
if (diag_top) {
for (unsigned idx = top; idx < diag_top; idx += 1) {
if (bits_[idx] == V0) lost_bits=1;
}
}
} else {
unsigned top = nbits_;
if (top > (8 * sizeof(long) - 1))
top = 8 * sizeof(long) - 1;
signed long mask = 1;
for (unsigned idx = 0 ; idx < top ; idx += 1, mask <<= 1)
if (bits_[idx] == V1)
val |= mask;
for (unsigned idx = 0 ; idx < top ; idx += 1, mask <<= 1) {
if (bits_[idx] == V1) val |= mask;
}
if (diag_top) {
for (unsigned idx = top; idx < diag_top; idx += 1) {
if (bits_[idx] == V1) lost_bits=1;
}
}
}
if (lost_bits) cerr << "warning: verinum::as_long() truncated " <<
diag_top << " bits to " << IVLLBITS << ", returns " << val << endl;
return val;
#undef IVLLBITS
}
double verinum::as_double() const

View File

@ -3,5 +3,5 @@
* Edit this definition in version_base.in to define the base version
* number for the compiled result.
*/
#define VERSION "0.9.devel"
#define VERSION "0.9.1"
#endif

View File

@ -328,7 +328,7 @@ static unsigned int get_format_char(char **rtn, int ljust, int plus,
if (ld_zero == 1) {
/* Strip the leading zeros if a width is not given. */
if (width == -1) while (*cp == '0') cp++;
if (width == -1) while (*cp == '0' && *(cp+1) != '\0') cp++;
/* Pad with leading zeros. */
else if (ljust == 0 && (signed)swidth < width) {
unsigned pad = (unsigned)width - swidth;
@ -337,7 +337,7 @@ static unsigned int get_format_char(char **rtn, int ljust, int plus,
strcpy(cp+pad, value.value.str);
free_flag = 1;
/* For a left aligned value also strip the leading zeros. */
} else if (ljust != 0) while (*cp == '0') cp++;
} else if (ljust != 0) while (*cp == '0' && *(cp+1) != '\0') cp++;
}
/* If a width was not given, use a width of zero. */

View File

@ -297,6 +297,8 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause)
static PLI_INT32 finish_cb(p_cb_data cause)
{
struct vcd_info *cur, *next;
if (finish_status != 0) return 0;
finish_status = 1;
@ -306,6 +308,17 @@ static PLI_INT32 finish_cb(p_cb_data cause)
lt_set_time64(dump_file, dumpvars_time);
}
for (cur = vcd_list ; cur ; cur = next) {
next = cur->next;
free(cur);
}
vcd_list = 0;
vcd_names_delete(&lxt_tab);
nexus_ident_delete();
free(dump_path);
dump_path = 0;
return 0;
}

View File

@ -299,6 +299,8 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause)
static PLI_INT32 finish_cb(p_cb_data cause)
{
struct vcd_info *cur, *next;
if (finish_status != 0) return 0;
finish_status = 1;
@ -308,6 +310,17 @@ static PLI_INT32 finish_cb(p_cb_data cause)
lxt2_wr_set_time64(dump_file, dumpvars_time);
}
for (cur = vcd_list ; cur ; cur = next) {
next = cur->next;
free(cur);
}
vcd_list = 0;
vcd_names_delete(&lxt_tab);
nexus_ident_delete();
free(dump_path);
dump_path = 0;
return 0;
}

View File

@ -264,6 +264,7 @@ static PLI_INT32 finish_cb(p_cb_data cause)
free((char *)cur->ident);
free(cur);
}
vcd_list = 0;
vcd_names_delete(&vcd_tab);
vcd_names_delete(&vcd_var);
nexus_ident_delete();

View File

@ -1,7 +1,6 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.82 2007/03/22 16:08:19 steve Exp $
*/
VVP SIMULATION ENGINE

View File

@ -50,7 +50,7 @@
# undef HAVE_NAN
/*
* Define this is you want to compile vvp with memory freeing and
* Define this if you want to compile vvp with memory freeing and
* special valgrind hooks for the memory pools.
*/
# undef CHECK_WITH_VALGRIND
@ -68,29 +68,55 @@
#endif
#ifdef HAVE_INTTYPES_H
/* This is needed in C++ to get the PRI?64 formats. */
# ifndef __STDC_FORMAT_MACROS
# define __STDC_FORMAT_MACROS
# endif
# include <inttypes.h>
#endif
typedef uint64_t vvp_time64_t;
# define TIME_FMT_O PRIo64
# define TIME_FMT_U PRIu64
# define TIME_FMT_X PRIx64
# if SIZEOF_UNSIGNED_LONG == 8
# define UL_AND_TIME64_SAME
# endif
#else /* HAVE_INTTYPES_H */
#if SIZEOF_UNSIGNED >= 8
typedef unsigned vvp_time64_t;
# define TIME_FMT ""
# define TIME_FMT_O "o"
# define TIME_FMT_U "u"
# define TIME_FMT_X "x"
#else
# if SIZEOF_UNSIGNED_LONG >= 8
typedef unsigned long vvp_time64_t;
# define UL_AND_TIME64_SAME
# define TIME_FMT "l"
# define TIME_FMT_O "lo"
# define TIME_FMT_U "lu"
# define TIME_FMT_X "lx"
# else
# if SIZEOF_UNSIGNED_LONG_LONG > SIZEOF_UNSIGNED_LONG
typedef unsigned long long vvp_time64_t;
# define TIME_FMT "ll"
# define TIME_FMT_O "llo"
# define TIME_FMT_U "llu"
# define TIME_FMT_X "llx"
# else
typedef unsigned long vvp_time64_t;
# define UL_AND_TIME64_SAME
# define TIME_FMT "l"
# define TIME_FMT_O "lo"
# define TIME_FMT_U "lu"
# define TIME_FMT_X "lx"
# endif
# endif
#endif
#endif /* HAVE_INTTYPES_H */
# include <math.h>
/* getrusage, /proc/self/statm */

View File

@ -483,7 +483,7 @@ void stop_handler(int rc)
}
vpi_mcd_printf(1,"** VVP Stop(%d) **\n", rc);
vpi_mcd_printf(1,"** Current simulation time is %" TIME_FMT "u ticks.\n",
vpi_mcd_printf(1,"** Current simulation time is %" TIME_FMT_U " ticks.\n",
schedule_simtime());
interact_flag = true;

View File

@ -1,7 +1,6 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: vpi.txt,v 1.8 2007/03/22 16:08:19 steve Exp $
*/

View File

@ -265,17 +265,17 @@ static void timevar_get_value(vpiHandle ref, s_vpi_value*vp, bool is_int_func,
break;
case vpiDecStrVal:
sprintf(rbuf, "%" TIME_FMT "u", simtime);
sprintf(rbuf, "%" TIME_FMT_U, simtime);
vp->value.str = rbuf;
break;
case vpiOctStrVal:
sprintf(rbuf, "%" TIME_FMT "o", simtime);
sprintf(rbuf, "%" TIME_FMT_O, simtime);
vp->value.str = rbuf;
break;
case vpiHexStrVal:
sprintf(rbuf, "%" TIME_FMT "x", simtime);
sprintf(rbuf, "%" TIME_FMT_X, simtime);
vp->value.str = rbuf;
break;

View File

@ -1974,7 +1974,8 @@ static unsigned long divide2words(unsigned long a, unsigned long b,
static unsigned long* divide_bits(unsigned long*ap, unsigned long*bp, unsigned wid)
{
// Do all our work a cpu-word at a time. The "words" variable
// is the number of words of the wid.
unsigned words = (wid+CPU_WORD_BITS-1) / CPU_WORD_BITS;
unsigned btop = words-1;
@ -1985,6 +1986,8 @@ static unsigned long* divide_bits(unsigned long*ap, unsigned long*bp, unsigned w
if (btop==0 && bp[0]==0)
return 0;
// The result array will eventually accumulate the result. The
// diff array is a difference that we use in the intermediate.
unsigned long*diff = new unsigned long[words];
unsigned long*result= new unsigned long[words];
for (unsigned idx = 0 ; idx < words ; idx += 1)
@ -2012,10 +2015,11 @@ static unsigned long* divide_bits(unsigned long*ap, unsigned long*bp, unsigned w
// cur_res is a guestimate of the result this far. It
// may be 1 too big. (But it will also be >0) Try it,
// and if the difference comes out negative, then adjust
// then.
// and if the difference comes out negative, then adjust.
// diff = (bp * cur_res) << cur_ptr;
multiply_array_imm(diff+cur_ptr, bp, words-cur_ptr, cur_res);
// ap -= diff
unsigned long carry = 1;
for (unsigned idx = cur_ptr ; idx < words ; idx += 1)
ap[idx] = add_with_carry(ap[idx], ~diff[idx], carry);
@ -2027,12 +2031,14 @@ static unsigned long* divide_bits(unsigned long*ap, unsigned long*bp, unsigned w
// case, we know that cur_res was too large by 1. Correct by
// adding 1b back in and reducing cur_res.
if ((carry&1) == 0) {
cur_res -= 1;
carry = 0;
for (unsigned idx = cur_ptr ; idx < words ; idx += 1)
ap[idx] = add_with_carry(ap[idx], bp[idx-cur_ptr], carry);
// The sign *must* have changed again.
assert(carry == 1);
// Keep adding b back in until the remainder
// becomes positive again.
do {
cur_res -= 1;
carry = 0;
for (unsigned idx = cur_ptr ; idx < words ; idx += 1)
ap[idx] = add_with_carry(ap[idx], bp[idx-cur_ptr], carry);
} while (carry == 0);
}
result[cur_ptr] = cur_res;

View File

@ -1,7 +1,6 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: vthread.txt,v 1.6 2005/09/19 21:45:37 steve Exp $
*/

View File

@ -3399,7 +3399,7 @@ ostream& operator <<(ostream&out, vvp_scalar_t a)
/*
* This function is only called if the actual interface function rules
* out some of the eazy cases. If we get here, we can assume that
* out some of the easy cases. If we get here, we can assume that
* neither of the values is HiZ, and the values are not exactly equal.
*/
vvp_scalar_t fully_featured_resolv_(vvp_scalar_t a, vvp_scalar_t b)