Merge branch 'master' into vvp-net-out-rework
This commit is contained in:
commit
79a5dde7c4
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -1077,28 +1077,9 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
|
||||||
void NetScope::dump(ostream&o) const
|
void NetScope::dump(ostream&o) const
|
||||||
{
|
{
|
||||||
/* This is a constructed hierarchical name. */
|
/* This is a constructed hierarchical name. */
|
||||||
o << scope_path(this);
|
o << scope_path(this) << " ";
|
||||||
|
|
||||||
switch (type_) {
|
print_type(o);
|
||||||
case BEGIN_END:
|
|
||||||
o << " sequential block";
|
|
||||||
break;
|
|
||||||
case FORK_JOIN:
|
|
||||||
o << " parallel block";
|
|
||||||
break;
|
|
||||||
case FUNC:
|
|
||||||
o << " function";
|
|
||||||
break;
|
|
||||||
case MODULE:
|
|
||||||
o << " module <" << (module_name_? module_name_.str() : "") << ">";
|
|
||||||
break;
|
|
||||||
case TASK:
|
|
||||||
o << " task";
|
|
||||||
break;
|
|
||||||
case GENBLOCK:
|
|
||||||
o << " generate block";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (is_auto()) o << " (automatic)";
|
if (is_auto()) o << " (automatic)";
|
||||||
o << endl;
|
o << endl;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1936,7 +1936,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
||||||
if (!name_tail.index.empty()) {
|
if (!name_tail.index.empty()) {
|
||||||
probe_index_expr_width(des, scope, name_tail);
|
probe_index_expr_width(des, scope, name_tail);
|
||||||
const index_component_t&index_tail = name_tail.index.back();
|
const index_component_t&index_tail = name_tail.index.back();
|
||||||
use_sel = index_tail.sel;
|
// Skip full array word net selects.
|
||||||
|
if (!net || (name_tail.index.size() > net->array_dimensions())) {
|
||||||
|
use_sel = index_tail.sel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned use_width = UINT_MAX;
|
unsigned use_width = UINT_MAX;
|
||||||
|
|
|
||||||
265
elab_scope.cc
265
elab_scope.cc
|
|
@ -238,13 +238,29 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
|
||||||
; cur != tasks.end() ; cur ++ ) {
|
; cur != tasks.end() ; cur ++ ) {
|
||||||
|
|
||||||
hname_t use_name( (*cur).first );
|
hname_t use_name( (*cur).first );
|
||||||
if (scope->child(use_name)) {
|
// A task can not have the same name as another scope object.
|
||||||
cerr << loc.get_fileline() << ": error: task/scope name "
|
const NetScope *child = scope->child(use_name);
|
||||||
<< use_name << " already used in this context."
|
if (child) {
|
||||||
<< endl;
|
cerr << cur->second->get_fileline() << ": error: task and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << scope->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A task can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
|
||||||
|
ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << cur->second->get_fileline()
|
||||||
|
<< ": error: task and parameter in '"
|
||||||
|
<< scope->fullname() << "' have the same name '"
|
||||||
|
<< (*cur).first << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
NetScope*task_scope = new NetScope(scope, use_name,
|
NetScope*task_scope = new NetScope(scope, use_name,
|
||||||
NetScope::TASK);
|
NetScope::TASK);
|
||||||
task_scope->is_auto((*cur).second->is_auto());
|
task_scope->is_auto((*cur).second->is_auto());
|
||||||
|
|
@ -268,13 +284,30 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
||||||
; cur != funcs.end() ; cur ++ ) {
|
; cur != funcs.end() ; cur ++ ) {
|
||||||
|
|
||||||
hname_t use_name( (*cur).first );
|
hname_t use_name( (*cur).first );
|
||||||
if (scope->child(use_name)) {
|
// A function can not have the same name as another scope object.
|
||||||
cerr << loc.get_fileline() << ": error: function/scope name "
|
const NetScope *child = scope->child(use_name);
|
||||||
<< use_name << " already used in this context."
|
if (child) {
|
||||||
<< endl;
|
cerr << cur->second->get_fileline()
|
||||||
|
<< ": error: function and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << scope->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A function can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
|
||||||
|
ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << cur->second->get_fileline()
|
||||||
|
<< ": error: function and parameter in '"
|
||||||
|
<< scope->fullname() << "' have the same name '"
|
||||||
|
<< (*cur).first << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
NetScope*func_scope = new NetScope(scope, use_name,
|
NetScope*func_scope = new NetScope(scope, use_name,
|
||||||
NetScope::FUNC);
|
NetScope::FUNC);
|
||||||
func_scope->is_auto((*cur).second->is_auto());
|
func_scope->is_auto((*cur).second->is_auto());
|
||||||
|
|
@ -488,6 +521,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
// genvar statement.
|
// genvar statement.
|
||||||
|
|
||||||
// MISSING CODE!
|
// MISSING CODE!
|
||||||
|
//
|
||||||
|
// Also the genvar checks below need to be moved/changed
|
||||||
|
// when this is implemented. They currently work, but do
|
||||||
|
// not reference the genvar statement.
|
||||||
|
|
||||||
// We're going to need a genvar...
|
// We're going to need a genvar...
|
||||||
int genvar;
|
int genvar;
|
||||||
|
|
@ -507,15 +544,46 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the generate block name.
|
||||||
|
|
||||||
|
// A generate "loop" can not have the same name as another scope object.
|
||||||
|
const NetScope *child = container->child(hname_t(scope_name));
|
||||||
|
if (child) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"loop\" and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << scope_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// A generate "loop" can not have the same name as a named event.
|
||||||
|
const NetEvent *event = container->find_event(scope_name);
|
||||||
|
if (event) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||||
|
"named event in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << scope_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A generate "loop" can not have the same name as a parameter.
|
||||||
|
const NetExpr*tmsb;
|
||||||
|
const NetExpr*tlsb;
|
||||||
|
const NetExpr*texpr = container->get_parameter(scope_name, tmsb, tlsb);
|
||||||
|
if (texpr != 0) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||||
|
"parameter in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << scope_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Since we will be adding the genvar value as a local parameter
|
// Since we will be adding the genvar value as a local parameter
|
||||||
// to each instances scope. We need to make sure a parameter does
|
// to each instances scope. We need to make sure a parameter does
|
||||||
// not already exist.
|
// not already exist.
|
||||||
const NetExpr*tmsb;
|
texpr = container->get_parameter(loop_index, tmsb, tlsb);
|
||||||
const NetExpr*tlsb;
|
|
||||||
const NetExpr*texpr = container->get_parameter(loop_index, tmsb, tlsb);
|
|
||||||
if (texpr != 0) {
|
if (texpr != 0) {
|
||||||
cerr << get_fileline() << ": error: Cannot have a genvar "
|
cerr << get_fileline() << ": error: genvar and "
|
||||||
<< "and parameter with the same name: " << loop_index << endl;
|
"parameter in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << loop_index << "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -545,13 +613,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
// container. The format of using [] is part of the
|
// container. The format of using [] is part of the
|
||||||
// Verilog standard.
|
// Verilog standard.
|
||||||
hname_t use_name (scope_name, genvar);
|
hname_t use_name (scope_name, genvar);
|
||||||
if (container->child(use_name)) {
|
|
||||||
cerr << get_fileline() << ": error: block/scope name "
|
|
||||||
<< use_name << " already used in this context."
|
|
||||||
<< endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: "
|
cerr << get_fileline() << ": debug: "
|
||||||
<< "Create generated scope " << use_name << endl;
|
<< "Create generated scope " << use_name << endl;
|
||||||
|
|
@ -642,14 +704,37 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
||||||
}
|
}
|
||||||
|
|
||||||
hname_t use_name (scope_name);
|
hname_t use_name (scope_name);
|
||||||
if (container->child(use_name)) {
|
// A generate "if" can not have the same name as another scope object.
|
||||||
cerr << get_fileline() << ": error: block/scope name "
|
const NetScope *child = container->child(use_name);
|
||||||
<< scope_name << " already used in this context."
|
if (child) {
|
||||||
<< endl;
|
cerr << get_fileline() << ": error: generate \"if\" and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A generate "if" can not have the same name as a named event.
|
||||||
|
const NetEvent *event = container->find_event(scope_name);
|
||||||
|
if (event) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||||
|
"named event in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A generate "if" can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = container->get_parameter(scope_name, ex_msb,
|
||||||
|
ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||||
|
"parameter in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: Generate condition "
|
cerr << get_fileline() << ": debug: Generate condition "
|
||||||
<< (else_flag? "(else)" : "(if)")
|
<< (else_flag? "(else)" : "(if)")
|
||||||
|
|
@ -757,6 +842,36 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||||
|
|
||||||
// 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);
|
||||||
|
// A generate "case" can not have the same name as another scope object.
|
||||||
|
const NetScope *child = container->child(use_name);
|
||||||
|
if (child) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"case\" and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A generate "case" can not have the same name as a named event.
|
||||||
|
const NetEvent *event = container->find_event(item->scope_name);
|
||||||
|
if (event) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||||
|
"named event in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A generate "case" can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = container->get_parameter(item->scope_name, ex_msb,
|
||||||
|
ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||||
|
"parameter in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
item->probe_for_direct_nesting_();
|
item->probe_for_direct_nesting_();
|
||||||
if (item->direct_nested_) {
|
if (item->direct_nested_) {
|
||||||
|
|
@ -778,13 +893,37 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
||||||
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
||||||
{
|
{
|
||||||
hname_t use_name (scope_name);
|
hname_t use_name (scope_name);
|
||||||
if (container->child(use_name)) {
|
// A generate "case" can not have the same name as another scope object.
|
||||||
cerr << get_fileline() << ": error: block/scope name "
|
const NetScope *child = container->child(use_name);
|
||||||
<< scope_name << " already used in this context."
|
if (child) {
|
||||||
<< endl;
|
cerr << get_fileline() << ": error: generate \"block\" and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A generate "block" can not have the same name as a named event.
|
||||||
|
const NetEvent *event = container->find_event(scope_name);
|
||||||
|
if (event) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||||
|
"named event in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A generate "block" can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = container->get_parameter(scope_name, ex_msb,
|
||||||
|
ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||||
|
"parameter in '" << container->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: Generate named block "
|
cerr << get_fileline() << ": debug: Generate named block "
|
||||||
<< ": Generate scope=" << use_name << endl;
|
<< ": Generate scope=" << use_name << endl;
|
||||||
|
|
@ -904,18 +1043,28 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||||
// Missing module instance names have already been rejected.
|
// Missing module instance names have already been rejected.
|
||||||
assert(get_name() != "");
|
assert(get_name() != "");
|
||||||
|
|
||||||
// Check for duplicate scopes. Simply look up the scope I'm
|
// A module instance can not have the same name as another scope object.
|
||||||
// about to create, and if I find it then somebody beat me to
|
const NetScope *child = sc->child(hname_t(get_name()));
|
||||||
// it.
|
if (child) {
|
||||||
|
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||||
if (sc->child(hname_t(get_name()))) {
|
<< "> instance and ";
|
||||||
cerr << get_fileline() << ": error: Instance/Scope name " <<
|
child->print_type(cerr);
|
||||||
get_name() << " already used in this context." <<
|
cerr << " in '" << sc->fullname()
|
||||||
endl;
|
<< "' have the same name '" << get_name() << "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A module instance can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = sc->get_parameter(get_name(), ex_msb, ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||||
|
<< "> instance and parameter in '" << sc->fullname()
|
||||||
|
<< "' have the same name '" << get_name() << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
// check for recursive instantiation by scanning the current
|
// check for recursive instantiation by scanning the current
|
||||||
// scope and its parents. Look for a module instantiation of
|
// scope and its parents. Look for a module instantiation of
|
||||||
// the same module, but farther up in the scope.
|
// the same module, but farther up in the scope.
|
||||||
|
|
@ -1153,6 +1302,26 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||||
*/
|
*/
|
||||||
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
|
// A named event can not have the same name as another scope object.
|
||||||
|
const NetScope *child = scope->child(hname_t(name_));
|
||||||
|
if (child) {
|
||||||
|
cerr << get_fileline() << ": error: named event and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << scope->fullname()
|
||||||
|
<< "' have the same name '" << name_ << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A named event can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << get_fileline() << ": error: named event and "
|
||||||
|
<< "parameter in '" << scope->fullname()
|
||||||
|
<< "' have the same name '" << name_ << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
NetEvent*ev = new NetEvent(name_);
|
NetEvent*ev = new NetEvent(name_);
|
||||||
ev->set_line(*this);
|
ev->set_line(*this);
|
||||||
scope->add_event(ev);
|
scope->add_event(ev);
|
||||||
|
|
@ -1233,13 +1402,29 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
if (pscope_name() != 0) {
|
if (pscope_name() != 0) {
|
||||||
hname_t use_name(pscope_name());
|
hname_t use_name(pscope_name());
|
||||||
if (scope->child(use_name)) {
|
// A named block can not have the same name as another scope
|
||||||
cerr << get_fileline() << ": error: block/scope name "
|
// object.
|
||||||
<< use_name << " already used in this context."
|
const NetScope *child = scope->child(use_name);
|
||||||
<< endl;
|
if (child) {
|
||||||
|
cerr << get_fileline() << ": error: named block and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << scope->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A named block can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = scope->get_parameter(pscope_name(), ex_msb,
|
||||||
|
ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << get_fileline() << ": error: named block and "
|
||||||
|
"parameter in '" << scope->fullname()
|
||||||
|
<< "' have the same name '" << use_name << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: "
|
cerr << get_fileline() << ": debug: "
|
||||||
<< "Elaborate block scope " << use_name
|
<< "Elaborate block scope " << use_name
|
||||||
|
|
|
||||||
27
elab_sig.cc
27
elab_sig.cc
|
|
@ -870,6 +870,33 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
des->errors += error_cnt_;
|
des->errors += error_cnt_;
|
||||||
|
|
||||||
|
// A signal can not have the same name as a scope object.
|
||||||
|
const NetScope *child = scope->child(hname_t(name_));
|
||||||
|
if (child) {
|
||||||
|
cerr << get_fileline() << ": error: signal and ";
|
||||||
|
child->print_type(cerr);
|
||||||
|
cerr << " in '" << scope->fullname()
|
||||||
|
<< "' have the same name '" << name_ << "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
// A signal can not have the same name as a parameter.
|
||||||
|
const NetExpr *ex_msb, *ex_lsb;
|
||||||
|
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
|
||||||
|
if (parm) {
|
||||||
|
cerr << get_fileline() << ": error: signal and parameter in '"
|
||||||
|
<< scope->fullname() << "' have the same name '" << name_
|
||||||
|
<< "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
// A signal can not have the same name as a named event.
|
||||||
|
const NetEvent *event = scope->find_event(name_);
|
||||||
|
if (event) {
|
||||||
|
cerr << get_fileline() << ": error: signal and named event in '"
|
||||||
|
<< scope->fullname() << "' have the same name '" << name_
|
||||||
|
<< "'." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (port_set_ || net_set_) {
|
if (port_set_ || net_set_) {
|
||||||
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
|
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
|
||||||
bool bad_lsb = false, bad_msb = false;
|
bool bad_lsb = false, bad_msb = false;
|
||||||
|
|
|
||||||
25
net_scope.cc
25
net_scope.cc
|
|
@ -232,6 +232,31 @@ NetScope::TYPE NetScope::type() const
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetScope::print_type(ostream&stream) const
|
||||||
|
{
|
||||||
|
switch (type_) {
|
||||||
|
case BEGIN_END:
|
||||||
|
stream << "sequential block";
|
||||||
|
break;
|
||||||
|
case FORK_JOIN:
|
||||||
|
stream << "parallel block";
|
||||||
|
break;
|
||||||
|
case FUNC:
|
||||||
|
stream << "function";
|
||||||
|
break;
|
||||||
|
case MODULE:
|
||||||
|
stream << "module <" << (module_name_ ? module_name_.str() : "")
|
||||||
|
<< "> instance";
|
||||||
|
break;
|
||||||
|
case TASK:
|
||||||
|
stream << "task";
|
||||||
|
break;
|
||||||
|
case GENBLOCK:
|
||||||
|
stream << "generate block";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NetScope::set_task_def(NetTaskDef*def)
|
void NetScope::set_task_def(NetTaskDef*def)
|
||||||
{
|
{
|
||||||
assert( type_ == TASK );
|
assert( type_ == TASK );
|
||||||
|
|
|
||||||
|
|
@ -738,6 +738,7 @@ class NetScope : public Attrib {
|
||||||
const NetScope* child(const hname_t&name) const;
|
const NetScope* child(const hname_t&name) const;
|
||||||
|
|
||||||
TYPE type() const;
|
TYPE type() const;
|
||||||
|
void print_type(ostream&) const;
|
||||||
|
|
||||||
void set_task_def(NetTaskDef*);
|
void set_task_def(NetTaskDef*);
|
||||||
void set_func_def(NetFuncDef*);
|
void set_func_def(NetFuncDef*);
|
||||||
|
|
|
||||||
17
parse.y
17
parse.y
|
|
@ -2124,8 +2124,7 @@ module_item
|
||||||
|
|
||||||
| K_task automatic_opt IDENTIFIER ';'
|
| K_task automatic_opt IDENTIFIER ';'
|
||||||
{ assert(current_task == 0);
|
{ assert(current_task == 0);
|
||||||
current_task = pform_push_task_scope($3, $2);
|
current_task = pform_push_task_scope(@1, $3, $2);
|
||||||
FILE_NAME(current_task, @1);
|
|
||||||
}
|
}
|
||||||
task_item_list_opt
|
task_item_list_opt
|
||||||
statement_or_null
|
statement_or_null
|
||||||
|
|
@ -2139,8 +2138,7 @@ module_item
|
||||||
|
|
||||||
| K_task automatic_opt IDENTIFIER '('
|
| K_task automatic_opt IDENTIFIER '('
|
||||||
{ assert(current_task == 0);
|
{ assert(current_task == 0);
|
||||||
current_task = pform_push_task_scope($3, $2);
|
current_task = pform_push_task_scope(@1, $3, $2);
|
||||||
FILE_NAME(current_task, @1);
|
|
||||||
}
|
}
|
||||||
task_port_decl_list ')' ';'
|
task_port_decl_list ')' ';'
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
|
|
@ -2155,8 +2153,7 @@ module_item
|
||||||
|
|
||||||
| K_task automatic_opt IDENTIFIER '(' ')' ';'
|
| K_task automatic_opt IDENTIFIER '(' ')' ';'
|
||||||
{ assert(current_task == 0);
|
{ assert(current_task == 0);
|
||||||
current_task = pform_push_task_scope($3, $2);
|
current_task = pform_push_task_scope(@1, $3, $2);
|
||||||
FILE_NAME(current_task, @1);
|
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
statement_or_null
|
statement_or_null
|
||||||
|
|
@ -2184,8 +2181,7 @@ module_item
|
||||||
|
|
||||||
| K_function automatic_opt function_range_or_type_opt IDENTIFIER ';'
|
| K_function automatic_opt function_range_or_type_opt IDENTIFIER ';'
|
||||||
{ assert(current_function == 0);
|
{ assert(current_function == 0);
|
||||||
current_function = pform_push_function_scope($4, $2);
|
current_function = pform_push_function_scope(@1, $4, $2);
|
||||||
FILE_NAME(current_function, @1);
|
|
||||||
}
|
}
|
||||||
function_item_list statement
|
function_item_list statement
|
||||||
K_endfunction
|
K_endfunction
|
||||||
|
|
@ -2199,8 +2195,7 @@ module_item
|
||||||
|
|
||||||
| K_function automatic_opt function_range_or_type_opt IDENTIFIER
|
| K_function automatic_opt function_range_or_type_opt IDENTIFIER
|
||||||
{ assert(current_function == 0);
|
{ assert(current_function == 0);
|
||||||
current_function = pform_push_function_scope($4, $2);
|
current_function = pform_push_function_scope(@1, $4, $2);
|
||||||
FILE_NAME(current_function, @1);
|
|
||||||
}
|
}
|
||||||
'(' task_port_decl_list ')' ';'
|
'(' task_port_decl_list ')' ';'
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
|
|
@ -2262,7 +2257,7 @@ module_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| K_generate K_begin ':' IDENTIFIER {
|
| K_generate K_begin ':' IDENTIFIER {
|
||||||
pform_start_generate_nblock(@1, $4);
|
pform_start_generate_nblock(@2, $4);
|
||||||
} module_item_list_opt K_end K_endgenerate
|
} module_item_list_opt K_end K_endgenerate
|
||||||
{ /* Detect and warn about anachronistic named begin/end use */
|
{ /* Detect and warn about anachronistic named begin/end use */
|
||||||
if (generation_flag > GN_VER2001) {
|
if (generation_flag > GN_VER2001) {
|
||||||
|
|
|
||||||
111
pform.cc
111
pform.cc
|
|
@ -103,7 +103,7 @@ void pform_pop_scope()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PTask* pform_push_task_scope(char*name, bool is_auto)
|
PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
|
||||||
{
|
{
|
||||||
perm_string task_name = lex_strings.make(name);
|
perm_string task_name = lex_strings.make(name);
|
||||||
|
|
||||||
|
|
@ -111,11 +111,30 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
|
||||||
if (pform_cur_generate) {
|
if (pform_cur_generate) {
|
||||||
task = new PTask(task_name, pform_cur_generate->lexical_scope,
|
task = new PTask(task_name, pform_cur_generate->lexical_scope,
|
||||||
is_auto);
|
is_auto);
|
||||||
|
FILE_NAME(task, loc);
|
||||||
|
// Check if the task is already in the dictionary.
|
||||||
|
if (pform_cur_generate->tasks.find(task->pscope_name()) !=
|
||||||
|
pform_cur_generate->tasks.end()) {
|
||||||
|
cerr << task->get_fileline() << ": error: duplicate "
|
||||||
|
" definition for task '" << name << "' in '"
|
||||||
|
<< pform_cur_module->mod_name() << "' (generate)."
|
||||||
|
<< endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
pform_cur_generate->tasks[task->pscope_name()] = task;
|
pform_cur_generate->tasks[task->pscope_name()] = task;
|
||||||
pform_cur_generate->lexical_scope = task;
|
pform_cur_generate->lexical_scope = task;
|
||||||
} else {
|
} else {
|
||||||
task = new PTask(task_name, lexical_scope,
|
task = new PTask(task_name, lexical_scope,
|
||||||
is_auto);
|
is_auto);
|
||||||
|
FILE_NAME(task, loc);
|
||||||
|
// Check if the task is already in the dictionary.
|
||||||
|
if (pform_cur_module->tasks.find(task->pscope_name()) !=
|
||||||
|
pform_cur_module->tasks.end()) {
|
||||||
|
cerr << task->get_fileline() << ": error: duplicate "
|
||||||
|
"definition for task '" << name << "' in '"
|
||||||
|
<< pform_cur_module->mod_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
pform_cur_module->tasks[task->pscope_name()] = task;
|
pform_cur_module->tasks[task->pscope_name()] = task;
|
||||||
lexical_scope = task;
|
lexical_scope = task;
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +142,8 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
PFunction* pform_push_function_scope(char*name, bool is_auto)
|
PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
|
||||||
|
bool is_auto)
|
||||||
{
|
{
|
||||||
perm_string func_name = lex_strings.make(name);
|
perm_string func_name = lex_strings.make(name);
|
||||||
|
|
||||||
|
|
@ -131,11 +151,30 @@ PFunction* pform_push_function_scope(char*name, bool is_auto)
|
||||||
if (pform_cur_generate) {
|
if (pform_cur_generate) {
|
||||||
func = new PFunction(func_name, pform_cur_generate->lexical_scope,
|
func = new PFunction(func_name, pform_cur_generate->lexical_scope,
|
||||||
is_auto);
|
is_auto);
|
||||||
|
FILE_NAME(func, loc);
|
||||||
|
// Check if the function is already in the dictionary.
|
||||||
|
if (pform_cur_generate->funcs.find(func->pscope_name()) !=
|
||||||
|
pform_cur_generate->funcs.end()) {
|
||||||
|
cerr << func->get_fileline() << ": error: duplicate "
|
||||||
|
"definition for function '" << name << "' in '"
|
||||||
|
<< pform_cur_module->mod_name() << "' (generate)."
|
||||||
|
<< endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
pform_cur_generate->funcs[func->pscope_name()] = func;
|
pform_cur_generate->funcs[func->pscope_name()] = func;
|
||||||
pform_cur_generate->lexical_scope = func;
|
pform_cur_generate->lexical_scope = func;
|
||||||
} else {
|
} else {
|
||||||
func = new PFunction(func_name, lexical_scope,
|
func = new PFunction(func_name, lexical_scope,
|
||||||
is_auto);
|
is_auto);
|
||||||
|
FILE_NAME(func, loc);
|
||||||
|
// Check if the function is already in the dictionary.
|
||||||
|
if (pform_cur_module->funcs.find(func->pscope_name()) !=
|
||||||
|
pform_cur_module->funcs.end()) {
|
||||||
|
cerr << func->get_fileline() << ": error: duplicate "
|
||||||
|
"definition for function '" << name << "' in '"
|
||||||
|
<< pform_cur_module->mod_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
pform_cur_module->funcs[func->pscope_name()] = func;
|
pform_cur_module->funcs[func->pscope_name()] = func;
|
||||||
lexical_scope = func;
|
lexical_scope = func;
|
||||||
}
|
}
|
||||||
|
|
@ -1071,9 +1110,21 @@ void pform_set_net_range(list<perm_string>*names,
|
||||||
*/
|
*/
|
||||||
static void pform_make_event(perm_string name, const char*fn, unsigned ln)
|
static void pform_make_event(perm_string name, const char*fn, unsigned ln)
|
||||||
{
|
{
|
||||||
|
LexicalScope*scope = pform_get_cur_scope();
|
||||||
|
|
||||||
|
// Check if the named event is already in the dictionary.
|
||||||
|
if (scope->events.find(name) != scope->events.end()) {
|
||||||
|
LineInfo tloc;
|
||||||
|
FILE_NAME(&tloc, fn, ln);
|
||||||
|
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
||||||
|
"for named event '" << name << "' in '"
|
||||||
|
<< pform_cur_module->mod_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
PEvent*event = new PEvent(name);
|
PEvent*event = new PEvent(name);
|
||||||
FILE_NAME(event, fn, ln);
|
FILE_NAME(event, fn, ln);
|
||||||
pform_get_cur_scope()->events[name] = event;
|
scope->events[name] = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_make_events(list<perm_string>*names, const char*fn, unsigned ln)
|
void pform_make_events(list<perm_string>*names, const char*fn, unsigned ln)
|
||||||
|
|
@ -1768,13 +1819,32 @@ void pform_set_parameter(const struct vlltype&loc,
|
||||||
bool signed_flag, svector<PExpr*>*range, PExpr*expr,
|
bool signed_flag, svector<PExpr*>*range, PExpr*expr,
|
||||||
LexicalScope::range_t*value_range)
|
LexicalScope::range_t*value_range)
|
||||||
{
|
{
|
||||||
if (pform_get_cur_scope() == pform_cur_generate) {
|
LexicalScope*scope = pform_get_cur_scope();
|
||||||
|
if (scope == pform_cur_generate) {
|
||||||
VLerror("parameter declarations are not permitted in generate blocks");
|
VLerror("parameter declarations are not permitted in generate blocks");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the parameter name is already in the dictionary.
|
||||||
|
if (scope->parameters.find(name) != scope->parameters.end()) {
|
||||||
|
LineInfo tloc;
|
||||||
|
FILE_NAME(&tloc, loc);
|
||||||
|
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
||||||
|
"for parameter '" << name << "' in '"
|
||||||
|
<< pform_cur_module->mod_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
if (scope->localparams.find(name) != scope->localparams.end()) {
|
||||||
|
LineInfo tloc;
|
||||||
|
FILE_NAME(&tloc, loc);
|
||||||
|
cerr << tloc.get_fileline() << ": error: localparam and "
|
||||||
|
"parameter in '" << pform_cur_module->mod_name()
|
||||||
|
<< "' have the same name '" << name << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
assert(expr);
|
assert(expr);
|
||||||
Module::param_expr_t&parm = pform_get_cur_scope()->parameters[name];
|
Module::param_expr_t&parm = scope->parameters[name];
|
||||||
FILE_NAME(&parm, loc);
|
FILE_NAME(&parm, loc);
|
||||||
|
|
||||||
parm.expr = expr;
|
parm.expr = expr;
|
||||||
|
|
@ -1793,7 +1863,7 @@ void pform_set_parameter(const struct vlltype&loc,
|
||||||
parm.signed_flag = signed_flag;
|
parm.signed_flag = signed_flag;
|
||||||
parm.range = value_range;
|
parm.range = value_range;
|
||||||
|
|
||||||
if (pform_get_cur_scope() == pform_cur_module)
|
if (scope == pform_cur_module)
|
||||||
pform_cur_module->param_names.push_back(name);
|
pform_cur_module->param_names.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1801,6 +1871,26 @@ void pform_set_localparam(const struct vlltype&loc,
|
||||||
perm_string name, ivl_variable_type_t type,
|
perm_string name, ivl_variable_type_t type,
|
||||||
bool signed_flag, svector<PExpr*>*range, PExpr*expr)
|
bool signed_flag, svector<PExpr*>*range, PExpr*expr)
|
||||||
{
|
{
|
||||||
|
LexicalScope*scope = pform_get_cur_scope();
|
||||||
|
|
||||||
|
// Check if the localparam name is already in the dictionary.
|
||||||
|
if (scope->localparams.find(name) != scope->localparams.end()) {
|
||||||
|
LineInfo tloc;
|
||||||
|
FILE_NAME(&tloc, loc);
|
||||||
|
cerr << tloc.get_fileline() << ": error: duplicate definition "
|
||||||
|
"for localparam '" << name << "' in '"
|
||||||
|
<< pform_cur_module->mod_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
if (scope->parameters.find(name) != scope->parameters.end()) {
|
||||||
|
LineInfo tloc;
|
||||||
|
FILE_NAME(&tloc, loc);
|
||||||
|
cerr << tloc.get_fileline() << ": error: parameter and "
|
||||||
|
"localparam in '" << pform_cur_module->mod_name()
|
||||||
|
<< "' have the same name '" << name << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
assert(expr);
|
assert(expr);
|
||||||
Module::param_expr_t&parm = pform_get_cur_scope()->localparams[name];
|
Module::param_expr_t&parm = pform_get_cur_scope()->localparams[name];
|
||||||
FILE_NAME(&parm, loc);
|
FILE_NAME(&parm, loc);
|
||||||
|
|
@ -1824,6 +1914,15 @@ void pform_set_localparam(const struct vlltype&loc,
|
||||||
|
|
||||||
void pform_set_specparam(perm_string name, PExpr*expr)
|
void pform_set_specparam(perm_string name, PExpr*expr)
|
||||||
{
|
{
|
||||||
|
// Check if the specparam name is already in the dictionary.
|
||||||
|
if (pform_cur_module->specparams.find(name) !=
|
||||||
|
pform_cur_module->specparams.end()) {
|
||||||
|
cerr << expr->get_fileline() << ": error: duplicate definition "
|
||||||
|
"for specparam '" << name << "' in '"
|
||||||
|
<< pform_cur_module->mod_name() << "'." << endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
assert(expr);
|
assert(expr);
|
||||||
pform_cur_module->specparams[name] = expr;
|
pform_cur_module->specparams[name] = expr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
pform.h
8
pform.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __pform_H
|
#ifndef __pform_H
|
||||||
#define __pform_H
|
#define __pform_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -180,8 +180,10 @@ extern void pform_make_udp(perm_string name,
|
||||||
*/
|
*/
|
||||||
extern void pform_pop_scope();
|
extern void pform_pop_scope();
|
||||||
|
|
||||||
extern PTask*pform_push_task_scope(char*name, bool is_auto);
|
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||||
extern PFunction*pform_push_function_scope(char*name, bool is_auto);
|
bool is_auto);
|
||||||
|
extern PFunction*pform_push_function_scope(const struct vlltype&loc, char*name,
|
||||||
|
bool is_auto);
|
||||||
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
|
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
|
||||||
|
|
||||||
extern void pform_put_behavior_in_scope(AProcess*proc);
|
extern void pform_put_behavior_in_scope(AProcess*proc);
|
||||||
|
|
|
||||||
|
|
@ -563,6 +563,15 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
||||||
case vpiTimeVar:
|
case vpiTimeVar:
|
||||||
case vpiReg: type = "reg"; }
|
case vpiReg: type = "reg"; }
|
||||||
|
|
||||||
|
/* An array word is implicitly escaped so look for an
|
||||||
|
* escaped identifier that this could conflict with. */
|
||||||
|
if (vpi_get(vpiType, item) == vpiMemoryWord &&
|
||||||
|
vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) {
|
||||||
|
vpi_printf("LXT warning: dumping array word %s will "
|
||||||
|
"conflict with an escaped identifier.\n",
|
||||||
|
vpi_get_str(vpiFullName, item));
|
||||||
|
}
|
||||||
|
|
||||||
if (skip || vpi_get(vpiAutomatic, item)) break;
|
if (skip || vpi_get(vpiAutomatic, item)) break;
|
||||||
|
|
||||||
name = vpi_get_str(vpiName, item);
|
name = vpi_get_str(vpiName, item);
|
||||||
|
|
|
||||||
|
|
@ -575,6 +575,15 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
||||||
case vpiTimeVar:
|
case vpiTimeVar:
|
||||||
case vpiReg: type = "reg"; }
|
case vpiReg: type = "reg"; }
|
||||||
|
|
||||||
|
/* An array word is implicitly escaped so look for an
|
||||||
|
* escaped identifier that this could conflict with. */
|
||||||
|
if (vpi_get(vpiType, item) == vpiMemoryWord &&
|
||||||
|
vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) {
|
||||||
|
vpi_printf("LXT2 warning: dumping array word %s will "
|
||||||
|
"conflict with an escaped identifier.\n",
|
||||||
|
vpi_get_str(vpiFullName, item));
|
||||||
|
}
|
||||||
|
|
||||||
if (skip || vpi_get(vpiAutomatic, item)) break;
|
if (skip || vpi_get(vpiAutomatic, item)) break;
|
||||||
|
|
||||||
name = vpi_get_str(vpiName, item);
|
name = vpi_get_str(vpiName, item);
|
||||||
|
|
|
||||||
|
|
@ -539,6 +539,15 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* An array word is implicitly escaped so look for an
|
||||||
|
* escaped identifier that this could conflict with. */
|
||||||
|
if (vpi_get(vpiType, item) == vpiMemoryWord &&
|
||||||
|
vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) {
|
||||||
|
vpi_printf("VCD warning: dumping array word %s will "
|
||||||
|
"conflict with an escaped identifier.\n",
|
||||||
|
vpi_get_str(vpiFullName, item));
|
||||||
|
}
|
||||||
|
|
||||||
if (skip || vpi_get(vpiAutomatic, item)) break;
|
if (skip || vpi_get(vpiAutomatic, item)) break;
|
||||||
|
|
||||||
name = vpi_get_str(vpiName, item);
|
name = vpi_get_str(vpiName, item);
|
||||||
|
|
|
||||||
42
vvp/delay.cc
42
vvp/delay.cc
|
|
@ -137,6 +137,7 @@ vvp_fun_delay::vvp_fun_delay(vvp_net_t*n, vvp_bit4_t init, const vvp_delay_t&d)
|
||||||
: net_(n), delay_(d), cur_vec4_(1)
|
: net_(n), delay_(d), cur_vec4_(1)
|
||||||
{
|
{
|
||||||
cur_vec4_.set_bit(0, init);
|
cur_vec4_.set_bit(0, init);
|
||||||
|
cur_vec8_ = vvp_vector8_t(cur_vec4_, 6, 6);
|
||||||
cur_real_ = 0.0;
|
cur_real_ = 0.0;
|
||||||
list_ = 0;
|
list_ = 0;
|
||||||
initial_ = true;
|
initial_ = true;
|
||||||
|
|
@ -263,18 +264,49 @@ void vvp_fun_delay::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See the recv_vec4 comment above. */
|
||||||
void vvp_fun_delay::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
|
void vvp_fun_delay::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
|
||||||
{
|
{
|
||||||
assert(port.port() == 0);
|
assert(port.port() == 0);
|
||||||
|
|
||||||
if (cur_vec8_.eeq(bit))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* XXXX FIXME: For now, just use the minimum delay. */
|
|
||||||
vvp_time64_t use_delay;
|
vvp_time64_t use_delay;
|
||||||
use_delay = delay_.get_min_delay();
|
/* This is an initial value so it needs to be compared to all the
|
||||||
|
bits (the order the bits are changed is not deterministic). */
|
||||||
|
if (initial_) {
|
||||||
|
vvp_bit4_t cur_val = cur_vec8_.value(0).value();
|
||||||
|
use_delay = delay_.get_delay(cur_val, bit.value(0).value());
|
||||||
|
for (unsigned idx = 1 ; idx < bit.size() ; idx += 1) {
|
||||||
|
vvp_time64_t tmp;
|
||||||
|
tmp = delay_.get_delay(cur_val, bit.value(idx).value());
|
||||||
|
if (tmp > use_delay) use_delay = tmp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* How many bits to compare? */
|
||||||
|
unsigned use_wid = cur_vec8_.size();
|
||||||
|
if (bit.size() < use_wid) use_wid = bit.size();
|
||||||
|
|
||||||
|
/* Scan the vectors looking for delays. Select the maximum
|
||||||
|
delay encountered. */
|
||||||
|
use_delay = delay_.get_delay(cur_vec8_.value(0).value(),
|
||||||
|
bit.value(0).value());
|
||||||
|
|
||||||
|
for (unsigned idx = 1 ; idx < use_wid ; idx += 1) {
|
||||||
|
vvp_time64_t tmp;
|
||||||
|
tmp = delay_.get_delay(cur_vec8_.value(idx).value(),
|
||||||
|
bit.value(idx).value());
|
||||||
|
if (tmp > use_delay) use_delay = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* what *should* happen here is we check to see if there is a
|
||||||
|
transaction in the queue. This would be a pulse that needs to be
|
||||||
|
eliminated. */
|
||||||
|
clean_pulse_events_(use_delay);
|
||||||
|
|
||||||
vvp_time64_t use_simtime = schedule_simtime() + use_delay;
|
vvp_time64_t use_simtime = schedule_simtime() + use_delay;
|
||||||
|
|
||||||
|
/* And propagate it. */
|
||||||
if (use_delay == 0) {
|
if (use_delay == 0) {
|
||||||
cur_vec8_ = bit;
|
cur_vec8_ = bit;
|
||||||
initial_ = false;
|
initial_ = false;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue