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
|
||||
* 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
|
||||
{
|
||||
/* This is a constructed hierarchical name. */
|
||||
o << scope_path(this);
|
||||
o << scope_path(this) << " ";
|
||||
|
||||
switch (type_) {
|
||||
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;
|
||||
}
|
||||
print_type(o);
|
||||
if (is_auto()) o << " (automatic)";
|
||||
o << endl;
|
||||
|
||||
|
|
|
|||
|
|
@ -1936,7 +1936,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
if (!name_tail.index.empty()) {
|
||||
probe_index_expr_width(des, scope, name_tail);
|
||||
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;
|
||||
|
|
|
|||
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 ++ ) {
|
||||
|
||||
hname_t use_name( (*cur).first );
|
||||
if (scope->child(use_name)) {
|
||||
cerr << loc.get_fileline() << ": error: task/scope name "
|
||||
<< use_name << " already used in this context."
|
||||
<< endl;
|
||||
// A task can not have the same name as another scope object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
if (child) {
|
||||
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;
|
||||
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);
|
||||
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 ++ ) {
|
||||
|
||||
hname_t use_name( (*cur).first );
|
||||
if (scope->child(use_name)) {
|
||||
cerr << loc.get_fileline() << ": error: function/scope name "
|
||||
<< use_name << " already used in this context."
|
||||
<< endl;
|
||||
// A function can not have the same name as another scope object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
if (child) {
|
||||
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;
|
||||
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);
|
||||
func_scope->is_auto((*cur).second->is_auto());
|
||||
|
|
@ -488,6 +521,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
// genvar statement.
|
||||
|
||||
// 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...
|
||||
int genvar;
|
||||
|
|
@ -507,15 +544,46 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
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
|
||||
// to each instances scope. We need to make sure a parameter does
|
||||
// not already exist.
|
||||
const NetExpr*tmsb;
|
||||
const NetExpr*tlsb;
|
||||
const NetExpr*texpr = container->get_parameter(loop_index, tmsb, tlsb);
|
||||
texpr = container->get_parameter(loop_index, tmsb, tlsb);
|
||||
if (texpr != 0) {
|
||||
cerr << get_fileline() << ": error: Cannot have a genvar "
|
||||
<< "and parameter with the same name: " << loop_index << endl;
|
||||
cerr << get_fileline() << ": error: genvar and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << loop_index << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -545,13 +613,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
// container. The format of using [] is part of the
|
||||
// Verilog standard.
|
||||
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)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "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);
|
||||
if (container->child(use_name)) {
|
||||
cerr << get_fileline() << ": error: block/scope name "
|
||||
<< scope_name << " already used in this context."
|
||||
<< endl;
|
||||
// A generate "if" can not have the same name as another scope object.
|
||||
const NetScope *child = container->child(use_name);
|
||||
if (child) {
|
||||
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;
|
||||
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)
|
||||
cerr << get_fileline() << ": debug: Generate condition "
|
||||
<< (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.
|
||||
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_();
|
||||
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)
|
||||
{
|
||||
hname_t use_name (scope_name);
|
||||
if (container->child(use_name)) {
|
||||
cerr << get_fileline() << ": error: block/scope name "
|
||||
<< scope_name << " already used in this context."
|
||||
<< endl;
|
||||
// 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 \"block\" and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
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)
|
||||
cerr << get_fileline() << ": debug: Generate named block "
|
||||
<< ": 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.
|
||||
assert(get_name() != "");
|
||||
|
||||
// Check for duplicate scopes. Simply look up the scope I'm
|
||||
// about to create, and if I find it then somebody beat me to
|
||||
// it.
|
||||
|
||||
if (sc->child(hname_t(get_name()))) {
|
||||
cerr << get_fileline() << ": error: Instance/Scope name " <<
|
||||
get_name() << " already used in this context." <<
|
||||
endl;
|
||||
// A module instance can not have the same name as another scope object.
|
||||
const NetScope *child = sc->child(hname_t(get_name()));
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||
<< "> instance and ";
|
||||
child->print_type(cerr);
|
||||
cerr << " in '" << sc->fullname()
|
||||
<< "' have the same name '" << get_name() << "'." << endl;
|
||||
des->errors += 1;
|
||||
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
|
||||
// scope and its parents. Look for a module instantiation of
|
||||
// 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
|
||||
{
|
||||
// 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_);
|
||||
ev->set_line(*this);
|
||||
scope->add_event(ev);
|
||||
|
|
@ -1233,13 +1402,29 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
|||
|
||||
if (pscope_name() != 0) {
|
||||
hname_t use_name(pscope_name());
|
||||
if (scope->child(use_name)) {
|
||||
cerr << get_fileline() << ": error: block/scope name "
|
||||
<< use_name << " already used in this context."
|
||||
<< endl;
|
||||
// A named block can not have the same name as another scope
|
||||
// object.
|
||||
const NetScope *child = scope->child(use_name);
|
||||
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;
|
||||
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)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "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_;
|
||||
|
||||
// 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_) {
|
||||
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
|
||||
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_;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
assert( type_ == TASK );
|
||||
|
|
|
|||
|
|
@ -738,6 +738,7 @@ class NetScope : public Attrib {
|
|||
const NetScope* child(const hname_t&name) const;
|
||||
|
||||
TYPE type() const;
|
||||
void print_type(ostream&) const;
|
||||
|
||||
void set_task_def(NetTaskDef*);
|
||||
void set_func_def(NetFuncDef*);
|
||||
|
|
|
|||
17
parse.y
17
parse.y
|
|
@ -2124,8 +2124,7 @@ module_item
|
|||
|
||||
| K_task automatic_opt IDENTIFIER ';'
|
||||
{ assert(current_task == 0);
|
||||
current_task = pform_push_task_scope($3, $2);
|
||||
FILE_NAME(current_task, @1);
|
||||
current_task = pform_push_task_scope(@1, $3, $2);
|
||||
}
|
||||
task_item_list_opt
|
||||
statement_or_null
|
||||
|
|
@ -2139,8 +2138,7 @@ module_item
|
|||
|
||||
| K_task automatic_opt IDENTIFIER '('
|
||||
{ assert(current_task == 0);
|
||||
current_task = pform_push_task_scope($3, $2);
|
||||
FILE_NAME(current_task, @1);
|
||||
current_task = pform_push_task_scope(@1, $3, $2);
|
||||
}
|
||||
task_port_decl_list ')' ';'
|
||||
block_item_decls_opt
|
||||
|
|
@ -2155,8 +2153,7 @@ module_item
|
|||
|
||||
| K_task automatic_opt IDENTIFIER '(' ')' ';'
|
||||
{ assert(current_task == 0);
|
||||
current_task = pform_push_task_scope($3, $2);
|
||||
FILE_NAME(current_task, @1);
|
||||
current_task = pform_push_task_scope(@1, $3, $2);
|
||||
}
|
||||
block_item_decls_opt
|
||||
statement_or_null
|
||||
|
|
@ -2184,8 +2181,7 @@ module_item
|
|||
|
||||
| K_function automatic_opt function_range_or_type_opt IDENTIFIER ';'
|
||||
{ assert(current_function == 0);
|
||||
current_function = pform_push_function_scope($4, $2);
|
||||
FILE_NAME(current_function, @1);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
function_item_list statement
|
||||
K_endfunction
|
||||
|
|
@ -2199,8 +2195,7 @@ module_item
|
|||
|
||||
| K_function automatic_opt function_range_or_type_opt IDENTIFIER
|
||||
{ assert(current_function == 0);
|
||||
current_function = pform_push_function_scope($4, $2);
|
||||
FILE_NAME(current_function, @1);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
'(' task_port_decl_list ')' ';'
|
||||
block_item_decls_opt
|
||||
|
|
@ -2262,7 +2257,7 @@ module_item
|
|||
}
|
||||
}
|
||||
| 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
|
||||
{ /* Detect and warn about anachronistic named begin/end use */
|
||||
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);
|
||||
|
||||
|
|
@ -111,11 +111,30 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
|
|||
if (pform_cur_generate) {
|
||||
task = new PTask(task_name, pform_cur_generate->lexical_scope,
|
||||
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->lexical_scope = task;
|
||||
} else {
|
||||
task = new PTask(task_name, lexical_scope,
|
||||
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;
|
||||
lexical_scope = task;
|
||||
}
|
||||
|
|
@ -123,7 +142,8 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
|
|||
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);
|
||||
|
||||
|
|
@ -131,11 +151,30 @@ PFunction* pform_push_function_scope(char*name, bool is_auto)
|
|||
if (pform_cur_generate) {
|
||||
func = new PFunction(func_name, pform_cur_generate->lexical_scope,
|
||||
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->lexical_scope = func;
|
||||
} else {
|
||||
func = new PFunction(func_name, lexical_scope,
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
|
|
@ -1768,13 +1819,32 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
bool signed_flag, svector<PExpr*>*range, PExpr*expr,
|
||||
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");
|
||||
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);
|
||||
Module::param_expr_t&parm = pform_get_cur_scope()->parameters[name];
|
||||
Module::param_expr_t&parm = scope->parameters[name];
|
||||
FILE_NAME(&parm, loc);
|
||||
|
||||
parm.expr = expr;
|
||||
|
|
@ -1793,7 +1863,7 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
parm.signed_flag = signed_flag;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -1801,6 +1871,26 @@ void pform_set_localparam(const struct vlltype&loc,
|
|||
perm_string name, ivl_variable_type_t type,
|
||||
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);
|
||||
Module::param_expr_t&parm = pform_get_cur_scope()->localparams[name];
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
pform_cur_module->specparams[name] = expr;
|
||||
}
|
||||
|
|
|
|||
8
pform.h
8
pform.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __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
|
||||
* 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 PTask*pform_push_task_scope(char*name, bool is_auto);
|
||||
extern PFunction*pform_push_function_scope(char*name, bool is_auto);
|
||||
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
|
||||
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 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 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;
|
||||
|
||||
name = vpi_get_str(vpiName, item);
|
||||
|
|
|
|||
|
|
@ -575,6 +575,15 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
case vpiTimeVar:
|
||||
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;
|
||||
|
||||
name = vpi_get_str(vpiName, item);
|
||||
|
|
|
|||
|
|
@ -539,6 +539,15 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
cur_vec4_.set_bit(0, init);
|
||||
cur_vec8_ = vvp_vector8_t(cur_vec4_, 6, 6);
|
||||
cur_real_ = 0.0;
|
||||
list_ = 0;
|
||||
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)
|
||||
{
|
||||
assert(port.port() == 0);
|
||||
|
||||
if (cur_vec8_.eeq(bit))
|
||||
return;
|
||||
|
||||
/* XXXX FIXME: For now, just use the minimum 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;
|
||||
|
||||
/* And propagate it. */
|
||||
if (use_delay == 0) {
|
||||
cur_vec8_ = bit;
|
||||
initial_ = false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue