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 NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const;
map<perm_string,PExpr*> attributes;
}; };
/* /*

View File

@ -654,7 +654,7 @@ int main(int argc, char **argv)
case 'c': case 'c':
case 'f': case 'f':
add_cmd_file(optarg); add_cmd_file(optarg);
break; break;
case 'D': case 'D':
process_define(optarg); process_define(optarg);
break; break;
@ -673,9 +673,9 @@ int main(int argc, char **argv)
if (rc != 0) if (rc != 0)
return -1; return -1;
break; break;
case 'h': case 'h':
fprintf(stderr, "%s\n", HELP); fprintf(stderr, "%s\n", HELP);
return 1; return 1;
case 'I': case 'I':
process_include_dir(optarg); process_include_dir(optarg);

View File

@ -1227,8 +1227,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
} }
/* If all data bits get shifted away, connect the zero or /* If all data bits get shifted away, connect the zero or
* padding bits directly to output, and stop before building the * padding bits directly to output, and stop before building the
* concatenation. */ * concatenation. */
if (dist >= lwidth) { if (dist >= lwidth) {
connect(osig->pin(0), zero->pin(0)); connect(osig->pin(0), zero->pin(0));
return osig; return osig;

View File

@ -670,7 +670,7 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
<< "Generate case matches item at " << "Generate case matches item at "
<< item->get_fileline() << endl; << 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); hname_t use_name (item->scope_name);
NetScope*scope = new NetScope(container, use_name, NetScope*scope = new NetScope(container, use_name,

View File

@ -35,7 +35,7 @@ int acc_object_of_type(handle object, PLI_INT32 type)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "acc_object_of_type(%p \"%s\", %d)", 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); fflush(pli_trace);
} }

View File

@ -773,7 +773,7 @@ class NetScope : public Attrib {
void evaluate_parameters(class Design*); 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*); void residual_defparams(class Design*);
/* This method generates a non-hierarchical name that is /* This method generates a non-hierarchical name that is

58
parse.y
View File

@ -3591,28 +3591,31 @@ statement
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| event_control statement_or_null | event_control attribute_list_opt statement_or_null
{ PEventStatement*tmp = $1; { PEventStatement*tmp = $1;
if (tmp == 0) { if (tmp == 0) {
yyerror(@1, "error: Invalid event control."); yyerror(@1, "error: Invalid event control.");
$$ = 0; $$ = 0;
} else { } else {
tmp->set_statement($2); if ($3) pform_bind_attributes($3->attributes,$2);
$$ = tmp; tmp->set_statement($3);
} $$ = tmp;
} }
| '@' '*' statement_or_null }
{ PEventStatement*tmp = new PEventStatement; | '@' '*' attribute_list_opt statement_or_null
FILE_NAME(tmp, @1); { PEventStatement*tmp = new PEventStatement;
tmp->set_statement($3); FILE_NAME(tmp, @1);
$$ = tmp; if ($4) pform_bind_attributes($4->attributes,$3);
} tmp->set_statement($4);
| '@' '(' '*' ')' statement_or_null $$ = tmp;
{ PEventStatement*tmp = new PEventStatement; }
FILE_NAME(tmp, @1); | '@' '(' '*' ')' attribute_list_opt statement_or_null
tmp->set_statement($5); { PEventStatement*tmp = new PEventStatement;
$$ = tmp; FILE_NAME(tmp, @1);
} if ($6) pform_bind_attributes($6->attributes,$5);
tmp->set_statement($6);
$$ = tmp;
}
| lpvalue '=' expression ';' | lpvalue '=' expression ';'
{ PAssign*tmp = new PAssign($1,$3); { PAssign*tmp = new PAssign($1,$3);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
@ -3737,14 +3740,15 @@ statement_list
; ;
statement_or_null statement_or_null
: statement : statement
| ';' { $$ = 0; } { $$ = $1; }
; | ';'
{ $$ = 0; }
;
analog_statement analog_statement
: branch_probe_expression K_CONTRIBUTE expression ';' : 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 /* Task items are, other than the statement, task port items and

View File

@ -157,6 +157,19 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
return block; 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) PWire*pform_get_wire_in_scope(perm_string name)
{ {
/* Note that if we are processing a generate, then the /* 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); PProcess*pp = new PProcess(type, st);
if (attr) { pform_bind_attributes(pp->attributes, 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_put_behavior_in_scope(pp); pform_put_behavior_in_scope(pp);
return pp; return pp;

View File

@ -117,6 +117,10 @@ struct lgate {
unsigned lineno; 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. */ /* The lexor calls this function to change the default nettype. */
extern void pform_set_default_nettype(NetNet::Type net, 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; 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 void PExpr::dump(ostream&out) const
{ {
out << typeid(*this).name(); out << typeid(*this).name();
@ -363,14 +378,7 @@ void PWire::dump(ostream&out, unsigned ind) const
} }
out << ";" << endl; out << ";" << endl;
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin() dump_attributes_map(out, attributes, 8);
; idx != attributes.end()
; idx ++) {
out << " " << (*idx).first;
if ((*idx).second)
out << " = " << *(*idx).second;
out << endl;
}
} }
void PGate::dump_pins(ostream&out) const void PGate::dump_pins(ostream&out) const
@ -541,6 +549,7 @@ void Statement::dump(ostream&out, unsigned ind) const
out << setw(ind) << ""; out << setw(ind) << "";
out << "/* " << get_fileline() << ": " << typeid(*this).name() out << "/* " << get_fileline() << ": " << typeid(*this).name()
<< " */ ;" << endl; << " */ ;" << endl;
dump_attributes_map(out, attributes, ind+2);
} }
void AStatement::dump(ostream&out, unsigned ind) const void AStatement::dump(ostream&out, unsigned ind) const
@ -634,6 +643,7 @@ void PCase::dump(ostream&out, unsigned ind) const
break; break;
} }
out << " (" << *expr_ << ") /* " << get_fileline() << " */" << endl; out << " (" << *expr_ << ") /* " << get_fileline() << " */" << endl;
dump_attributes_map(out, attributes, ind+2);
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) { for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
PCase::Item*cur = (*items_)[idx]; PCase::Item*cur = (*items_)[idx];
@ -882,15 +892,7 @@ void PProcess::dump(ostream&out, unsigned ind) const
out << " /* " << get_fileline() << " */" << endl; out << " /* " << get_fileline() << " */" << endl;
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin() dump_attributes_map(out, attributes, ind+2);
; idx != attributes.end() ; idx++ ) {
out << setw(ind+2) << "" << "(* " << (*idx).first;
if ((*idx).second) {
out << " = " << *(*idx).second;
}
out << " *)" << endl;
}
statement_->dump(out, ind+2); statement_->dump(out, ind+2);
} }
@ -908,15 +910,7 @@ void AProcess::dump(ostream&out, unsigned ind) const
out << " /* " << get_fileline() << " */" << endl; out << " /* " << get_fileline() << " */" << endl;
for (map<perm_string,PExpr*>::const_iterator idx = attributes.begin() dump_attributes_map(out, attributes, ind+2);
; idx != attributes.end() ; idx++ ) {
out << setw(ind+2) << "" << "(* " << (*idx).first;
if ((*idx).second) {
out << " = " << *(*idx).second;
}
out << " *)" << endl;
}
statement_->dump(out, ind+2); statement_->dump(out, ind+2);
} }

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

View File

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

View File

@ -33,6 +33,11 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
// << " to=" << to->get_string() << " (" // << " to=" << to->get_string() << " ("
// << to->get_width() << ")" << std::endl; // << 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_name() == type_->get_name()) {
if (to->get_width() == type_->get_width()) if (to->get_width() == type_->get_width())
return this; // Identical return this; // Identical

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); return concat_lpm_to_expr(scope, lpm);
case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GE:
return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_GEQ); 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_EQ:
case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EEQ:
return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_EQ); 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); 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; return 0;
} }

View File

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

View File

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

View File

@ -977,12 +977,18 @@ void array_word_change(vvp_array_t array, unsigned long addr)
struct __vpiCallback*cur = next; struct __vpiCallback*cur = next;
next = cur->next; next = cur->next;
// Skip callbacks for callbacks not for me. // Skip callbacks that are not for me. -1 is for every element.
if (cur->extra_data != (long)addr) { if (cur->extra_data != (long)addr && cur->extra_data != -1) {
prev = cur; prev = cur;
continue; 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.cb_rtn != 0) {
if (cur->cb_data.value) if (cur->cb_data.value)
vpip_vec4_get_value(array->vals->get_word(addr), 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; 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) void compile_array_port(char*label, char*array, char*addr)
{ {
array_port_resolv_list_t*resolv_mem 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 */ /* VPI hooks */
extern void vpip_array_word_change(struct __vpiCallback*cb, vpiHandle word); extern void vpip_array_word_change(struct __vpiCallback*cb, vpiHandle word);
extern void vpip_array_change(struct __vpiCallback*cb, vpiHandle word);
/* Compile hooks */ /* Compile hooks */
extern void compile_variablew(char*label, vvp_array_t array, extern void compile_variablew(char*label, vvp_array_t array,

View File

@ -64,7 +64,7 @@ enum operand_e {
OA_CODE_PTR, OA_CODE_PTR,
/* The operand is a variable or net pointer */ /* The operand is a variable or net pointer */
OA_FUNC_PTR, OA_FUNC_PTR,
/* The operand is a second functor pointer */ /* The operand is a second functor pointer */
OA_FUNC_PTR2, OA_FUNC_PTR2,
/* The operand is a VPI handle */ /* The operand is a VPI handle */
OA_VPI_PTR, OA_VPI_PTR,
@ -1543,7 +1543,7 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
case OA_NONE: case OA_NONE:
break; break;
case OA_ARR_PTR: case OA_ARR_PTR:
if (opa->argv[idx].ltype != L_SYMB) { if (opa->argv[idx].ltype != L_SYMB) {
yyerror("operand format"); yyerror("operand format");
break; break;

View File

@ -170,6 +170,10 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
vpip_array_word_change(obj, data->obj); vpip_array_word_change(obj, data->obj);
break; break;
case vpiMemory:
vpip_array_change(obj, data->obj);
break;
case vpiPartSelect: case vpiPartSelect:
vpip_part_select_value_change(obj, data->obj); vpip_part_select_value_change(obj, data->obj);
break; break;

View File

@ -330,7 +330,7 @@ int vpip_time_units_from_handle(vpiHandle obj)
case vpiReg: case vpiReg:
signal = vpip_signal_from_handle(obj); signal = vpip_signal_from_handle(obj);
scope = vpip_scope(signal); scope = vpip_scope(signal);
return scope->time_units; return scope->time_units;
default: default:
fprintf(stderr, "ERROR: vpip_time_units_from_handle called with " 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); assert(when != 0);
switch (when->type) { switch (when->type) {
case vpiScaledRealTime: case vpiScaledRealTime:
dly = (vvp_time64_t)(when->real * dly = (vvp_time64_t)(when->real *
(pow(10.0L, (pow(10.0L,
vpip_time_units_from_handle(obj) - vpip_time_units_from_handle(obj) -
vpip_get_time_precision()))); vpip_get_time_precision())));
break; break;
case vpiSimTime: case vpiSimTime:
dly = vpip_timestruct_to_time(when); dly = vpip_timestruct_to_time(when);
break; break;
default: default:
dly = 0; dly = 0;
break; break;
} }
vpip_put_value_event*put = new vpip_put_value_event; vpip_put_value_event*put = new vpip_put_value_event;
put->handle = obj; put->handle = obj;

View File

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

View File

@ -296,7 +296,7 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp)
case vpiRealVal: case vpiRealVal:
vp->value.real = 0; vp->value.real = 0;
for (unsigned idx = wid ; idx > 0 ; idx -= 1) { for (unsigned idx = wid ; idx > 0 ; idx -= 1) {
vp->value.real *= 2.0; vp->value.real *= 2.0;
switch (get_bit(rfp, idx-1)) { switch (get_bit(rfp, idx-1)) {
case BIT4_0: case BIT4_0:
break; 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, void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
const char*buf, bool signed_flag) 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 significant digit first. This loop creates that string by
reversing the order of the buf string. For example, if the reversing the order of the buf string. For example, if the
input is "1234", str gets "4321". */ 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, static vvp_vector4_t vthread_bits_to_vector(struct vthread_s*thr,
unsigned bit, unsigned wid) unsigned bit, unsigned wid)
{ {
/* Make a vector of the desired width. */ /* Make a vector of the desired width. */
if (bit >= 4) { if (bit >= 4) {
return vvp_vector4_t(thr->bits4, bit, wid); return vvp_vector4_t(thr->bits4, bit, wid);