Merge branch 'master' into elaborate-net-rework
This commit is contained in:
commit
dd47599d55
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
28
parse.y
28
parse.y
|
|
@ -3591,26 +3591,29 @@ statement
|
|||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| event_control statement_or_null
|
||||
| event_control attribute_list_opt 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);
|
||||
if ($3) pform_bind_attributes($3->attributes,$2);
|
||||
tmp->set_statement($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
| '@' '(' '*' ')' statement_or_null
|
||||
}
|
||||
| '@' '*' attribute_list_opt statement_or_null
|
||||
{ PEventStatement*tmp = new PEventStatement;
|
||||
FILE_NAME(tmp, @1);
|
||||
tmp->set_statement($5);
|
||||
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 ';'
|
||||
|
|
@ -3738,10 +3741,11 @@ statement_list
|
|||
|
||||
statement_or_null
|
||||
: statement
|
||||
| ';' { $$ = 0; }
|
||||
{ $$ = $1; }
|
||||
| ';'
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
|
||||
analog_statement
|
||||
: branch_probe_expression K_CONTRIBUTE expression ';'
|
||||
{ $$ = pform_contribution_statement(@2, $1, $3); }
|
||||
|
|
|
|||
21
pform.cc
21
pform.cc
|
|
@ -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;
|
||||
|
|
|
|||
4
pform.h
4
pform.h
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
|
|||
// << " 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())
|
||||
return this; // Identical
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
19
vvp/array.cc
19
vvp/array.cc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue