Merge branch 'master' into elaborate-net-rework

This commit is contained in:
Stephen Williams 2008-09-06 17:20:14 -07:00
commit dd47599d55
48 changed files with 237 additions and 194 deletions

View File

@ -82,6 +82,8 @@ class Statement : public LineInfo {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
map<perm_string,PExpr*> attributes;
};
/*

View File

@ -3,7 +3,7 @@
`ifdef CONSTANTS_VAMS
`else
`define CONSTANTS_VAMS 1
// M_ is a mathematical constant
`define M_E 2.7182818284590452354
`define M_LOG2E 1.4426950408889634074

View File

@ -149,7 +149,7 @@ int cmdfile_stack_ptr = 0;
cflval.text = trim_trailing_white(yytext, 0);
BEGIN(0);
return TOK_STRING; }
/* Fallback match. */
. { return yytext[0]; }

View File

@ -221,7 +221,7 @@ implies the synthesis \fB-S\fP flag.
.TP 8
.B vhdl
This target produces a VHDL translation of the Verilog netlist. The
output is a single file containing VHDL entities corresponding to
output is a single file containing VHDL entities corresponding to
the modules in the Verilog source code. Note that only a subset of
the Verilog language is supported. See the wiki for more information.

View File

@ -341,7 +341,7 @@ static int t_default(char*cmd, unsigned ncmd)
} else {
fprintf(stderr, "Command signaled: %s\n", cmd);
rtn = -1;
}
}
}
free(cmd);
@ -523,7 +523,7 @@ int process_generation(const char*name)
void add_sft_file(const char *module)
{
char *file;
file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
sprintf(file, "%s%c%s.sft", base, sep, module);
if (access(file, R_OK) == 0)
@ -654,7 +654,7 @@ int main(int argc, char **argv)
case 'c':
case 'f':
add_cmd_file(optarg);
break;
break;
case 'D':
process_define(optarg);
break;
@ -673,9 +673,9 @@ int main(int argc, char **argv)
if (rc != 0)
return -1;
break;
case 'h':
fprintf(stderr, "%s\n", HELP);
return 1;
case 'h':
fprintf(stderr, "%s\n", HELP);
return 1;
case 'I':
process_include_dir(optarg);

View File

@ -682,7 +682,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, int expr_w
/* Elaborate the sub-expression to get its
self-determined width, and save that width. Then
delete the expression because we don't really want
the expression itself. */
the expression itself. */
long sub_expr_width = 0;
if (NetExpr*tmp = expr->elaborate_expr(des, scope, -1, true)) {
sub_expr_width = tmp->expr_width();

View File

@ -394,7 +394,7 @@ static NetNet* compare_eq_constant(Design*des, NetScope*scope,
if (zeros > 0) {
type = op_code == 'e'? NetUReduce::NOR : NetUReduce::OR;
if (debug_elaborate)
if (debug_elaborate)
cerr << lsig->get_fileline() << ": debug: "
<< "Replace net==" << val << " equality with "
<< zeros << "-input reduction [N]OR gate." << endl;
@ -402,7 +402,7 @@ static NetNet* compare_eq_constant(Design*des, NetScope*scope,
} else {
type = op_code == 'e'? NetUReduce::AND : NetUReduce::NAND;
if (debug_elaborate)
if (debug_elaborate)
cerr << lsig->get_fileline() << ": debug: "
<< "Replace net==" << val << " equality with "
<< ones << "-input reduction AND gate." << endl;
@ -1227,8 +1227,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
}
/* If all data bits get shifted away, connect the zero or
* padding bits directly to output, and stop before building the
* concatenation. */
* padding bits directly to output, and stop before building the
* concatenation. */
if (dist >= lwidth) {
connect(osig->pin(0), zero->pin(0));
return osig;
@ -1829,7 +1829,7 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
if (id_msb || id_lsb) {
assert(id_msb && id_lsb);
const NetEConst*tmp = dynamic_cast<const NetEConst*>(id_msb);
ivl_assert(*this, tmp);
ivl_assert(*this, tmp);
msb = tmp->value().as_long();
tmp = dynamic_cast<const NetEConst*>(id_lsb);
@ -2997,7 +2997,7 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope,
if (value_->get(width-1) != verinum::V0)
break;
width -= 1;
}
} else if (value_->has_sign() == false) {
@ -3406,7 +3406,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
tmp->decay_time(decay);
connect(tmp->pin(1), sub_sig->pin(0));
connect(tmp->pin(0), sig->pin(0));
connect(tmp->pin(0), sig->pin(0));
}
break;
@ -3662,7 +3662,7 @@ NetNet* PEUnary::elab_net_unary_real_(Design*des, NetScope*scope,
" for real values." << endl;
des->errors += 1;
break;
case 'm': { // abs()
NetAbs*tmp = new NetAbs(scope, scope->local_symbol(), 1);
tmp->set_line(*this);

View File

@ -670,7 +670,7 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
<< "Generate case matches item at "
<< item->get_fileline() << endl;
// The name of the scope to generate, whatever that item is.
// The name of the scope to generate, whatever that item is.
hname_t use_name (item->scope_name);
NetScope*scope = new NetScope(container, use_name,

View File

@ -143,7 +143,7 @@ static void elaborate_sig_tasks(Design*des, NetScope*scope,
}
}
bool Module::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
@ -361,7 +361,7 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
continue;
flag = tmp->elaborate_sig(des, scope) && flag;
}
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];

View File

@ -1377,7 +1377,7 @@ NetExpr* NetETernary::eval_tree(int prune_to_width)
case C_0:
eval_expr(false_val_);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluate ternary with "
<< "constant condition value: ";
print_ternary_cond(cond_);

View File

@ -1269,7 +1269,7 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope)
/* Connect the pins to the arguments. */
NetFuncDef*def = func_->func_def();
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
NetNet*tmp = pad_to_width(des, eparms[idx],
NetNet*tmp = pad_to_width(des, eparms[idx],
def->port(idx)->vector_width());
connect(net->pin(idx+1), tmp->pin(0));
}

View File

@ -282,7 +282,7 @@ int main(int argc, char*argv[])
fclose(src);
break;
}
case 'v':
fprintf(stderr, "Icarus Verilog Preprocessor version %s\n",
VERSION);

View File

@ -35,7 +35,7 @@ int acc_object_of_type(handle object, PLI_INT32 type)
if (pli_trace) {
fprintf(pli_trace, "acc_object_of_type(%p \"%s\", %d)",
object, vpi_get_str(vpiName, object), type);
object, vpi_get_str(vpiName, object), type);
fflush(pli_trace);
}

View File

@ -230,16 +230,16 @@ static void process_generation_flag(const char*gen)
} else if (strcmp(gen,"specify") == 0) {
gn_specify_blocks_flag = true;
} else if (strcmp(gen,"no-specify") == 0) {
gn_specify_blocks_flag = false;
} else if (strcmp(gen,"verilog-ams") == 0) {
gn_verilog_ams_flag = true;
} else if (strcmp(gen,"no-verilog-ams") == 0) {
gn_verilog_ams_flag = false;
} else if (strcmp(gen,"io-range-error") == 0) {
gn_io_range_error_flag = true;

View File

@ -736,7 +736,7 @@ class NetScope : public Attrib {
bool in_func();
/* Is the task or function automatic. */
void is_auto(bool is_auto) { is_auto_ = is_auto; };
bool is_auto() const { return is_auto_; };
bool is_auto() const { return is_auto_; };
const NetTaskDef* task_def() const;
const NetFuncDef* func_def() const;
@ -773,7 +773,7 @@ class NetScope : public Attrib {
void evaluate_parameters(class Design*);
// Look for defparams that never matched, and print warnings.
// Look for defparams that never matched, and print warnings.
void residual_defparams(class Design*);
/* This method generates a non-hierarchical name that is

64
parse.y
View File

@ -355,7 +355,7 @@ number : BASED_NUMBER
based_size = 0; }
;
/* real and realtime are exactly the same so save some code
/* real and realtime are exactly the same so save some code
* with a common matching rule. */
real_or_realtime
: K_real
@ -3591,28 +3591,31 @@ statement
FILE_NAME(tmp, @1);
$$ = tmp;
}
| event_control statement_or_null
{ PEventStatement*tmp = $1;
if (tmp == 0) {
yyerror(@1, "error: Invalid event control.");
$$ = 0;
} else {
tmp->set_statement($2);
$$ = tmp;
}
}
| '@' '*' statement_or_null
{ PEventStatement*tmp = new PEventStatement;
FILE_NAME(tmp, @1);
tmp->set_statement($3);
$$ = tmp;
}
| '@' '(' '*' ')' statement_or_null
{ PEventStatement*tmp = new PEventStatement;
FILE_NAME(tmp, @1);
tmp->set_statement($5);
$$ = tmp;
}
| event_control attribute_list_opt statement_or_null
{ PEventStatement*tmp = $1;
if (tmp == 0) {
yyerror(@1, "error: Invalid event control.");
$$ = 0;
} else {
if ($3) pform_bind_attributes($3->attributes,$2);
tmp->set_statement($3);
$$ = tmp;
}
}
| '@' '*' attribute_list_opt statement_or_null
{ PEventStatement*tmp = new PEventStatement;
FILE_NAME(tmp, @1);
if ($4) pform_bind_attributes($4->attributes,$3);
tmp->set_statement($4);
$$ = tmp;
}
| '@' '(' '*' ')' attribute_list_opt statement_or_null
{ PEventStatement*tmp = new PEventStatement;
FILE_NAME(tmp, @1);
if ($6) pform_bind_attributes($6->attributes,$5);
tmp->set_statement($6);
$$ = tmp;
}
| lpvalue '=' expression ';'
{ PAssign*tmp = new PAssign($1,$3);
FILE_NAME(tmp, @1);
@ -3737,14 +3740,15 @@ statement_list
;
statement_or_null
: statement
| ';' { $$ = 0; }
;
: statement
{ $$ = $1; }
| ';'
{ $$ = 0; }
;
analog_statement
: branch_probe_expression K_CONTRIBUTE expression ';'
{ $$ = pform_contribution_statement(@2, $1, $3); }
{ $$ = pform_contribution_statement(@2, $1, $3); }
;
/* Task items are, other than the statement, task port items and
@ -3970,7 +3974,7 @@ task_port_decl
}
/* Ports can be integer with a width of [31:0]. */
| K_input K_integer IDENTIFIER
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
PExpr*re;
@ -4036,7 +4040,7 @@ task_port_decl
}
/* Ports can be time with a width of [63:0] (unsigned). */
| K_input K_time IDENTIFIER
{ svector<PExpr*>*range_stub = new svector<PExpr*>(2);
PExpr*re;

View File

@ -157,6 +157,19 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
return block;
}
void pform_bind_attributes(map<perm_string,PExpr*>&attributes,
svector<named_pexpr_t*>*attr)
{
if (attr == 0)
return;
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) {
named_pexpr_t*tmp = (*attr)[idx];
attributes[tmp->name] = tmp->parm;
}
delete attr;
}
PWire*pform_get_wire_in_scope(perm_string name)
{
/* Note that if we are processing a generate, then the
@ -1951,13 +1964,7 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st,
{
PProcess*pp = new PProcess(type, st);
if (attr) {
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) {
named_pexpr_t*tmp = (*attr)[idx];
pp->attributes[tmp->name] = tmp->parm;
}
delete attr;
}
pform_bind_attributes(pp->attributes, attr);
pform_put_behavior_in_scope(pp);
return pp;

View File

@ -117,6 +117,10 @@ struct lgate {
unsigned lineno;
};
/* Use this function to transform the parted form of the attribute
list to the attribute map that is used later. */
extern void pform_bind_attributes(map<perm_string,PExpr*>&attributes,
svector<named_pexpr_t*>*attr);
/* The lexor calls this function to change the default nettype. */
extern void pform_set_default_nettype(NetNet::Type net,

View File

@ -155,6 +155,21 @@ std::ostream& operator << (std::ostream&out, ddomain_t dom)
return out;
}
static void dump_attributes_map(ostream&out,
const map<perm_string,PExpr*>&attributes,
int ind)
{
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin()
; idx != attributes.end() ; idx++ ) {
out << setw(ind) << "" << "(* " << (*idx).first;
if ((*idx).second) {
out << " = " << *(*idx).second;
}
out << " *)" << endl;
}
}
void PExpr::dump(ostream&out) const
{
out << typeid(*this).name();
@ -363,14 +378,7 @@ void PWire::dump(ostream&out, unsigned ind) const
}
out << ";" << endl;
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin()
; idx != attributes.end()
; idx ++) {
out << " " << (*idx).first;
if ((*idx).second)
out << " = " << *(*idx).second;
out << endl;
}
dump_attributes_map(out, attributes, 8);
}
void PGate::dump_pins(ostream&out) const
@ -541,6 +549,7 @@ void Statement::dump(ostream&out, unsigned ind) const
out << setw(ind) << "";
out << "/* " << get_fileline() << ": " << typeid(*this).name()
<< " */ ;" << endl;
dump_attributes_map(out, attributes, ind+2);
}
void AStatement::dump(ostream&out, unsigned ind) const
@ -634,6 +643,7 @@ void PCase::dump(ostream&out, unsigned ind) const
break;
}
out << " (" << *expr_ << ") /* " << get_fileline() << " */" << endl;
dump_attributes_map(out, attributes, ind+2);
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
PCase::Item*cur = (*items_)[idx];
@ -882,15 +892,7 @@ void PProcess::dump(ostream&out, unsigned ind) const
out << " /* " << get_fileline() << " */" << endl;
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin()
; idx != attributes.end() ; idx++ ) {
out << setw(ind+2) << "" << "(* " << (*idx).first;
if ((*idx).second) {
out << " = " << *(*idx).second;
}
out << " *)" << endl;
}
dump_attributes_map(out, attributes, ind+2);
statement_->dump(out, ind+2);
}
@ -908,15 +910,7 @@ void AProcess::dump(ostream&out, unsigned ind) const
out << " /* " << get_fileline() << " */" << endl;
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin()
; idx != attributes.end() ; idx++ ) {
out << setw(ind+2) << "" << "(* " << (*idx).first;
if ((*idx).second) {
out << " = " << *(*idx).second;
}
out << " *)" << endl;
}
dump_attributes_map(out, attributes, ind+2);
statement_->dump(out, ind+2);
}

View File

@ -1688,7 +1688,7 @@ extern "C" ivl_switch_t ivl_scope_switch(ivl_scope_t net, unsigned idx)
assert(idx < net->switches.size());
return net->switches[idx];
}
extern "C" int ivl_scope_time_precision(ivl_scope_t net)
{
assert(net);

View File

@ -219,6 +219,7 @@ void dll_target::expr_const(const NetEConst*net)
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
assert(expr_);
expr_->value_= net->expr_type();
FILE_NAME(expr_, net);
if (net->value().is_string()) {
expr_->type_ = IVL_EX_STRING;
@ -276,6 +277,7 @@ void dll_target::expr_creal(const NetECReal*net)
expr_->width_ = net->expr_width();
expr_->signed_ = 1;
expr_->type_ = IVL_EX_REALNUM;
FILE_NAME(expr_, net);
expr_->value_= IVL_VT_REAL;
expr_->u_.real_.value = net->value().as_double();
}

View File

@ -857,7 +857,7 @@ bool dll_target::bufz(const NetBUFZ*net)
logic_attributes(obj, net);
make_logic_delays_(obj, net);
scope_add_logic(scope, obj);
return true;

View File

@ -1042,7 +1042,7 @@ static void signal_nexus_const(ivl_signal_t sig,
switch (ivl_const_type(con)) {
case IVL_VT_LOGIC:
bits = ivl_const_bits(con);
for (idx = 0 ; idx < width ; idx += 1) {
for (idx = 0 ; idx < width ; idx += 1) {
fprintf(out, "%c", bits[width-idx-1]);
}
break;

View File

@ -32,6 +32,11 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
// << " (" << type_->get_width() << ") "
// << " to=" << to->get_string() << " ("
// << to->get_width() << ")" << std::endl;
// If this expression hasn't been given a type then
// we can't generate any type conversion code
if (NULL == type_)
return this;
if (to->get_name() == type_->get_name()) {
if (to->get_width() == type_->get_width())

View File

@ -241,6 +241,8 @@ static vhdl_expr *lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
return concat_lpm_to_expr(scope, lpm);
case IVL_LPM_CMP_GE:
return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_GEQ);
case IVL_LPM_CMP_GT:
return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_GT);
case IVL_LPM_CMP_EQ:
case IVL_LPM_CMP_EEQ:
return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_EQ);
@ -323,7 +325,7 @@ int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm)
out->set_slice(off, ivl_lpm_width(lpm) - 1);
}
arch->add_stmt(new vhdl_cassign_stmt(out, f));
arch->add_stmt(new vhdl_cassign_stmt(out, f->cast(out->get_type())));
return 0;
}

View File

@ -362,10 +362,10 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
assert(number_is_immediate(d_rise, 64, 0));
assert(number_is_immediate(d_fall, 64, 0));
assert(number_is_immediate(d_decay, 64, 0));
fprintf(vvp_out, "L_%p/d .functor BUFZ 1, %s, "
"C4<0>, C4<0>, C4<0>;\n", cptr, result);
fprintf(vvp_out, "L_%p .delay (%lu,%lu,%lu) L_%p/d;\n",
cptr, get_number_immediate(d_rise),
get_number_immediate(d_rise),

View File

@ -2169,7 +2169,7 @@ static struct vector_info draw_select_signal(ivl_expr_t sube,
assert(res.base);
fprintf(vvp_out, " %%load/v %u, v%p_%u, %u; Only need %u of %u bits\n",
res.base, sig, use_word, bit_wid, bit_wid, ivl_expr_width(sube));
save_signal_lookaside(res.base, sig, use_word, bit_wid);
/* Pad the part select to the desired width. Note that
this *should* always turn into an unsigned pad

View File

@ -187,7 +187,7 @@ static int draw_number_real(ivl_expr_t exp)
/* If this is actually a negative number, then get the
positive equivalent, and set the sign bit in the exponent
field.
field.
To get the positive equivalent of mant we need to take the
negative of the mantissa (0-mant) but also be aware that

View File

@ -539,7 +539,7 @@ static int show_stmt_assign_nb_real(ivl_statement_t net)
lval = ivl_stmt_lval(net, 0);
sig = ivl_lval_sig(lval);
assert(sig);
if (ivl_signal_dimensions(sig) > 0) {
word_ix = ivl_lval_idx(lval);
assert(word_ix);

View File

@ -1,6 +1,6 @@
#norootforbuild
#
%define rev_date 20080830
%define rev_date 20080905
#
#
Summary: Icarus Verilog
@ -82,6 +82,9 @@ rm -rf $RPM_BUILD_ROOT
%attr(-,root,root) /usr/include/_pli_types.h
%changelog -n verilog
* Fri Sep 03 2008 - steve@icarus.com
- New snapshot 20080905
* Sat Aug 30 2008 - steve@icarus.com
- Add vhdl target files
- Add V/AMS header files.

View File

@ -77,7 +77,7 @@ V = va_math.o
LIBS = @LIBS@
SYSTEM_VPI_LDFLAGS = $(LIBS)
VA_MATH_LDFLAGS =
VA_MATH_LDFLAGS =
ifeq (@MINGW32@,yes)
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
VA_MATH_LDFLAGS += @EXTRALIBS@

View File

@ -252,8 +252,8 @@ static PLI_INT32 variable_cb_1(p_cb_data cause)
struct t_cb_data cb;
struct vcd_info*info = (struct vcd_info*)cause->user_data;
if (dump_is_full) return 0;
if (dump_is_off) return 0;
if (dump_is_full) return 0;
if (dump_is_off) return 0;
if (dump_header_pending()) return 0;
if (info->scheduled) return 0;

View File

@ -721,7 +721,7 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
for ( ; item; item = vpi_scan(argv)) {
const char *scname;
int add_var = 0;
vcd_names_sort(&vcd_tab);
/* If this is a signal make sure it has not already

View File

@ -76,7 +76,7 @@ typedef struct t_vpi_vlog_info
typedef struct t_vpi_time {
/*
Type can be :
@ -124,52 +124,52 @@ typedef struct t_vpi_value {
/*
Conform the IEEE 1364, We add the
Standard vpi_delay structure to
Conform the IEEE 1364, We add the
Standard vpi_delay structure to
enable the modpath delay values
Conform IEEE 1364, Pg 670 :
The "da" field of the s_vpi_delay
structure shall be a user allocated
array of "s_vpi_time" structure
The array shall store delay values returned
by vpi_get_delay(). The number of elements in
the array shall be determined by
(1) The number of delays to be retrieved
( normally this is used in vpi_get_delays (..) )
{
{
(1.1) Set by "no_of_delays" field
(1.2) For the primitive_object, the no_of_delays
shall be 2 or 3
(1.3) For path_delay object the no_of_delays shall
be 1,2,3,6, 12
(1.4) For timing_check_object, the no_of_delays shall
be match the number of limits existing in the
be match the number of limits existing in the
Time Check
(1.5) For intermodule_path object, the no_of_delays shall
be 2 or 3
}
(2) The "mtm_flag" && "pulsere_flag"
Normally, if you set mtm = X, pulsere = Y
then, you will need allocate (num * no_of_delay)
s_vpi_time elements for 'da' array before calling
the vpi_get/put_delays (..)
---------------------------------------------------------------------------
| | | |
| mtm_flag | No of s_vpi_time array | order in which delay |
@ -197,7 +197,7 @@ typedef struct t_vpi_value {
| | | .... |
|----------------|-------------------------|------------------------------|
| | | 1o delay da[0]--> min delay |
| mtm = true | | da[1]--> typ delay |
| mtm = true | | da[1]--> typ delay |
| pulere = true | 9*no_of_delay | da[2]--> max delay |
| | | da[3]--> min delay |
| | | da[4]--> typ delay |
@ -206,14 +206,14 @@ typedef struct t_vpi_value {
| | | da[7]--> typ delay |
| | | da[8]--> max delay |
| | | 2o delay da[9]--> min delay |
| | | .... |
| | | .... |
-------------------------------------------------------------------------
IMPORTANT :
The delay Structure has to be allocated before passing a pointer to
"vpi_get_delays ( )".
The delay Structure has to be allocated before passing a pointer to
"vpi_get_delays ( )".
*/
@ -296,7 +296,7 @@ typedef struct t_vpi_delay {
#define vpiArgument 89
#define vpiInternalScope 92
#define vpiModPathIn 95
#define vpiModPathOut 96
#define vpiModPathOut 96
#define vpiVariables 100
#define vpiExpr 102
@ -500,7 +500,7 @@ extern vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value,
extern PLI_INT32 vpi_free_object(vpiHandle ref);
extern PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p);
/*
/*
These Routines will enable the modpath vpiHandle
to read/write delay values
*/

View File

@ -977,12 +977,18 @@ void array_word_change(vvp_array_t array, unsigned long addr)
struct __vpiCallback*cur = next;
next = cur->next;
// Skip callbacks for callbacks not for me.
if (cur->extra_data != (long)addr) {
// Skip callbacks that are not for me. -1 is for every element.
if (cur->extra_data != (long)addr && cur->extra_data != -1) {
prev = cur;
continue;
}
// For whole array callbacks we need to set the index.
if (cur->extra_data == -1) {
cur->cb_data.index = (PLI_INT32) ((int)addr +
array->first_addr.value);
}
if (cur->cb_data.cb_rtn != 0) {
if (cur->cb_data.value)
vpip_vec4_get_value(array->vals->get_word(addr),
@ -1058,6 +1064,15 @@ void vpip_array_word_change(struct __vpiCallback*cb, vpiHandle obj)
parent->vpi_callbacks = cb;
}
void vpip_array_change(struct __vpiCallback*cb, vpiHandle obj)
{
struct __vpiArray*arr = ARRAY_HANDLE(obj);
cb->extra_data = -1; // This is a callback for every element.
cb->next = arr->vpi_callbacks;
arr->vpi_callbacks = cb;
}
void compile_array_port(char*label, char*array, char*addr)
{
array_port_resolv_list_t*resolv_mem

View File

@ -48,6 +48,7 @@ extern vvp_vector4_t array_get_word(vvp_array_t array, unsigned address);
/* VPI hooks */
extern void vpip_array_word_change(struct __vpiCallback*cb, vpiHandle word);
extern void vpip_array_change(struct __vpiCallback*cb, vpiHandle word);
/* Compile hooks */
extern void compile_variablew(char*label, vvp_array_t array,

View File

@ -64,7 +64,7 @@ enum operand_e {
OA_CODE_PTR,
/* The operand is a variable or net pointer */
OA_FUNC_PTR,
/* The operand is a second functor pointer */
/* The operand is a second functor pointer */
OA_FUNC_PTR2,
/* The operand is a VPI handle */
OA_VPI_PTR,
@ -700,7 +700,7 @@ void compile_vpi_time_precision(long pre)
/*
* Convert a Cr string value to double.
*
*
* The format is broken into mantissa and exponent.
* The exponent in turn includes a sign bit.
*
@ -1369,7 +1369,7 @@ static struct __vpiModPathSrc*make_modpath_src(struct __vpiModPath*path,
srcobj->path_term_in.edge = vpi_edge;
input_connect(net, 0, src.text);
dst->add_modpath_src(obj, ifnone);
return srcobj;
}
@ -1543,7 +1543,7 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
case OA_NONE:
break;
case OA_ARR_PTR:
case OA_ARR_PTR:
if (opa->argv[idx].ltype != L_SYMB) {
yyerror("operand format");
break;

View File

@ -719,7 +719,7 @@ static void modpath_src_put_delays (vpiHandle ref, p_vpi_delay delays)
/*
* This routine will retrieve the delay[12] values
* of a vpiHandle. In this case, he will get an
* specific delays values from a vpiModPathIn
* specific delays values from a vpiModPathIn
* object
*
*/
@ -841,7 +841,7 @@ struct __vpiModPath* vpip_make_modpath(vvp_net_t *net)
/*
* This function will construct a vpiModPathIn
* This function will construct a vpiModPathIn
* ( struct __vpiModPathSrc ) Object. will give
* a delays[12] values, and point to the specified functor
*
@ -883,6 +883,6 @@ struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref)
{
if (ref->vpi_type->type_code != vpiModPath)
return 0;
return (struct __vpiModPathSrc *) ref;
}

View File

@ -468,7 +468,7 @@ register.
* %load/x1p <bit>, <functor-label>, <wid>
This is an indexed load. It uses the contents of index register 1 to
select a part from a vector functor at <functor-label>. The
select a part from a vector functor at <functor-label>. The
part is pulled from the indexed bit of the addressed functor and loaded
into the destination thread bit. The <wid> is the width of the
part. If any bit of the desired value is outside the vector, then that

View File

@ -188,19 +188,19 @@ statement
| T_LABEL K_ARRAY T_STRING ',' signed_t_number signed_t_number ',' signed_t_number signed_t_number ';'
{ compile_var_array($1, $3, $5, $6, $8, $9, 0); }
| T_LABEL K_ARRAY_I T_STRING ',' signed_t_number signed_t_number ',' signed_t_number signed_t_number ';'
{ compile_var_array($1, $3, $5, $6, $8, $9, 2); }
| T_LABEL K_ARRAY_R T_STRING ',' signed_t_number signed_t_number ',' signed_t_number signed_t_number ';'
{ compile_real_array($1, $3, $5, $6, $8, $9); }
| T_LABEL K_ARRAY_S T_STRING ',' signed_t_number signed_t_number ',' signed_t_number signed_t_number ';'
{ compile_var_array($1, $3, $5, $6, $8, $9, 1); }
| T_LABEL K_ARRAY T_STRING ',' signed_t_number signed_t_number ';'
{ compile_net_array($1, $3, $5, $6); }
| T_LABEL K_ARRAY_PORT T_SYMBOL ',' T_SYMBOL ';'
{ compile_array_port($1, $3, $5); }
@ -831,7 +831,7 @@ argument
{ $$ = vpip_make_binary_const($1.idx, $1.text);
free($1.text);
}
| symbol_access
| symbol_access
{ $$ = $1; }
;

View File

@ -170,6 +170,10 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
vpip_array_word_change(obj, data->obj);
break;
case vpiMemory:
vpip_array_change(obj, data->obj);
break;
case vpiPartSelect:
vpip_part_select_value_change(obj, data->obj);
break;
@ -570,7 +574,7 @@ void vvp_fun_signal::get_value(struct t_vpi_value*vp)
switch (vp->format) {
case vpiScalarVal:
// This works because vvp_bit4_t has the same encoding
// as a scalar value! See vpip_vec4_get_value() for a
// as a scalar value! See vpip_vec4_get_value() for a
// more robust method.
vp->value.scalar = value(0);
break;

View File

@ -330,7 +330,7 @@ int vpip_time_units_from_handle(vpiHandle obj)
case vpiReg:
signal = vpip_signal_from_handle(obj);
scope = vpip_scope(signal);
return scope->time_units;
return scope->time_units;
default:
fprintf(stderr, "ERROR: vpip_time_units_from_handle called with "
@ -686,20 +686,20 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
assert(when != 0);
switch (when->type) {
case vpiScaledRealTime:
dly = (vvp_time64_t)(when->real *
switch (when->type) {
case vpiScaledRealTime:
dly = (vvp_time64_t)(when->real *
(pow(10.0L,
vpip_time_units_from_handle(obj) -
vpip_get_time_precision())));
break;
case vpiSimTime:
break;
case vpiSimTime:
dly = vpip_timestruct_to_time(when);
break;
default:
break;
default:
dly = 0;
break;
}
}
vpip_put_value_event*put = new vpip_put_value_event;
put->handle = obj;
@ -919,22 +919,22 @@ vpiHandle vpi_handle_by_name(const char *name, vpiHandle scope)
/*
We increment the two vpi methods to enable the
We increment the two vpi methods to enable the
read/write of SDF delay values from/into
the modpath vpiHandle
basically, they will redirect the generic vpi_interface
vpi_get_delay ( .. )
vpi_get_delay ( .. )
vpi_put_delay ( .. )
to the
modpath_get_delay ( .. ) ;
modpath_get_delay ( .. ) ;
modpath_put_delay ( .. ) ;
*/
@ -943,17 +943,17 @@ void vpi_get_delays(vpiHandle expr, p_vpi_delay delays)
{
assert(expr);
assert(delays);
if (expr->vpi_type->vpi_get_delays_)
if (expr->vpi_type->vpi_get_delays_)
{
(expr->vpi_type->vpi_get_delays_)(expr, delays);
if (vpi_trace)
if (vpi_trace)
{
fprintf(vpi_trace,
fprintf(vpi_trace,
"vpi_get_delays(%p, %p) -->\n", expr, delays);
}
}
}
}
@ -961,17 +961,17 @@ void vpi_put_delays(vpiHandle expr, p_vpi_delay delays)
{
assert(expr );
assert(delays );
if (expr->vpi_type->vpi_put_delays_)
if (expr->vpi_type->vpi_put_delays_)
{
(expr->vpi_type->vpi_put_delays_)(expr, delays);
if (vpi_trace)
if (vpi_trace)
{
fprintf(vpi_trace,
fprintf(vpi_trace,
"vpi_put_delays(%p, %p) -->\n", expr, delays);
}
}
}
}

View File

@ -267,7 +267,7 @@ struct __vpiModPathSrc {
/* This is the input expression for this modpath. */
struct __vpiModPathTerm path_term_in;
/* This is the input net for the modpath. signals on this net
are used to determine the modpath. They are *not* propagated
anywhere. */
@ -277,7 +277,7 @@ struct __vpiModPathSrc {
/*
*
* The vpiMoaPath vpiHandle will define
* The vpiMoaPath vpiHandle will define
* a vpiModPath of record .modpath as defined
* in the IEEE 1364
*
@ -285,7 +285,7 @@ struct __vpiModPathSrc {
struct __vpiModPath {
struct __vpiScope *scope ;
class vvp_fun_modpath*modpath;
struct __vpiModPathTerm path_term_out;
@ -297,12 +297,12 @@ extern struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref);
/*
* The Function is used to create the vpiHandle
* The Function is used to create the vpiHandle
* for vpiModPath && vpiModPathIn objects
*/
extern struct __vpiModPathSrc* vpip_make_modpath_src (struct __vpiModPath*path_dest,
vvp_time64_t use_delay[12] ,
extern struct __vpiModPathSrc* vpip_make_modpath_src (struct __vpiModPath*path_dest,
vvp_time64_t use_delay[12] ,
vvp_net_t *net ) ;
extern struct __vpiModPath* vpip_make_modpath(vvp_net_t *net) ;

View File

@ -198,7 +198,7 @@ static int compare_types(int code, int type)
(type == vpiIntegerVar ||
type == vpiTimeVar ||
type == vpiRealVar))
return 1;
return 1;
return 0;
}

View File

@ -351,7 +351,7 @@ static void format_vpiStringVal(vvp_fun_signal_vec*sig, int base, unsigned wid,
vp->value.str = rbuf;
}
static void format_vpiScalarVal(vvp_fun_signal_vec*sig, int base,
static void format_vpiScalarVal(vvp_fun_signal_vec*sig, int base,
s_vpi_value*vp)
{
if (base >= 0 && base < (signed)sig->size()) {

View File

@ -296,7 +296,7 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp)
case vpiRealVal:
vp->value.real = 0;
for (unsigned idx = wid ; idx > 0 ; idx -= 1) {
vp->value.real *= 2.0;
vp->value.real *= 2.0;
switch (get_bit(rfp, idx-1)) {
case BIT4_0:
break;

View File

@ -223,7 +223,7 @@ unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4,
void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
const char*buf, bool signed_flag)
{
/* The str string is the decimal value with the least
/* The str string is the decimal value with the least
significant digit first. This loop creates that string by
reversing the order of the buf string. For example, if the
input is "1234", str gets "4321". */

View File

@ -204,7 +204,7 @@ static unsigned long* vector_to_array(struct vthread_s*thr,
static vvp_vector4_t vthread_bits_to_vector(struct vthread_s*thr,
unsigned bit, unsigned wid)
{
/* Make a vector of the desired width. */
/* Make a vector of the desired width. */
if (bit >= 4) {
return vvp_vector4_t(thr->bits4, bit, wid);