Add file and line information for parameters, etc.

This patch adds file and line information for parameters and
local parameters. It also adds file/line stubs for signals in
the tgt-* files. It adds the pform code needed to eventually
do genvar checks and passing of genvar file/line information.
It verifies that a genvar does not have the same name as a
parameter/local parameter.
This commit is contained in:
Cary R 2008-05-05 19:46:30 -07:00 committed by Stephen Williams
parent 5484ee1732
commit 4f8b91e65c
20 changed files with 261 additions and 88 deletions

View File

@ -82,6 +82,8 @@ class Module : public PScope, public LineInfo {
PExpr*expr; PExpr*expr;
PExpr*msb; PExpr*msb;
PExpr*lsb; PExpr*lsb;
perm_string file;
unsigned lineno;
bool signed_flag; bool signed_flag;
}; };
map<perm_string,param_expr_t>parameters; map<perm_string,param_expr_t>parameters;
@ -119,7 +121,7 @@ class Module : public PScope, public LineInfo {
/* The module has a list of genvars that may be used in /* The module has a list of genvars that may be used in
various generate schemes. */ various generate schemes. */
list<perm_string> genvars; list<pair<perm_string,LineInfo*> > genvars;
/* the module has a list of generate schemes that appear in /* the module has a list of generate schemes that appear in
the module definition. These are used at elaboration time. */ the module definition. These are used at elaboration time. */
@ -156,7 +158,8 @@ class Module : public PScope, public LineInfo {
map<perm_string,PFunction*> funcs_; map<perm_string,PFunction*> funcs_;
static void elaborate_parm_item_(perm_string name, const param_expr_t&cur, static void elaborate_parm_item_(perm_string name, const param_expr_t&cur,
Design*des, NetScope*scope); Design*des, NetScope*scope,
perm_string file, unsigned lineno);
private: // Not implemented private: // Not implemented
Module(const Module&); Module(const Module&);

View File

@ -45,7 +45,8 @@
# include <assert.h> # include <assert.h>
void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur, void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
Design*des, NetScope*scope) Design*des, NetScope*scope,
perm_string file, unsigned lineno)
{ {
PExpr*ex = cur.expr; PExpr*ex = cur.expr;
assert(ex); assert(ex);
@ -81,7 +82,7 @@ void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
} }
val = scope->set_parameter(name, val, val = scope->set_parameter(name, val,
msb, lsb, signed_flag); msb, lsb, signed_flag, file, lineno);
assert(val); assert(val);
delete val; delete val;
} }
@ -119,7 +120,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
tmp->set_line(*((*cur).second.expr)); tmp->set_line(*((*cur).second.expr));
tmp->cast_signed( (*cur).second.signed_flag ); tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false); scope->set_parameter((*cur).first, tmp, 0, 0, false,
(*cur).second.file, (*cur).second.lineno);
} }
for (mparm_it_t cur = localparams.begin() for (mparm_it_t cur = localparams.begin()
@ -130,7 +132,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
if ((*cur).second.msb) if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag ); tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false); scope->set_parameter((*cur).first, tmp, 0, 0, false,
(*cur).second.file, (*cur).second.lineno);
} }
@ -142,7 +145,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (mparm_it_t cur = parameters.begin() for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) { ; cur != parameters.end() ; cur ++) {
elaborate_parm_item_((*cur).first, (*cur).second, des, scope); elaborate_parm_item_((*cur).first, (*cur).second, des, scope,
(*cur).second.file, (*cur).second.lineno);
} }
/* run parameter replacements that were collected from the /* run parameter replacements that were collected from the
@ -174,7 +178,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (mparm_it_t cur = localparams.begin() for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) { ; cur != localparams.end() ; cur ++) {
elaborate_parm_item_((*cur).first, (*cur).second, des, scope); elaborate_parm_item_((*cur).first, (*cur).second, des, scope,
(*cur).second.file, (*cur).second.lineno);
} }
// Run through the defparams for this module, elaborate the // Run through the defparams for this module, elaborate the
@ -339,6 +344,11 @@ bool PGenerate::generate_scope(Design*des, NetScope*container)
*/ */
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container) bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
{ {
// Check that the loop_index variable was declared in a
// genvar statement.
// MISSING CODE!
// We're going to need a genvar... // We're going to need a genvar...
int genvar; int genvar;
@ -354,12 +364,24 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
return false; return false;
} }
// 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);
if (texpr != 0) {
cerr << get_fileline() << ": error: Cannot have a genvar "
<< "and parameter with the same name: " << loop_index << endl;
des->errors += 1;
return false;
}
genvar = init->value().as_long(); genvar = init->value().as_long();
delete init_ex; delete init_ex;
if (debug_scopes) if (debug_scopes)
cerr << get_fileline() << ": debug: genvar init = " << genvar << endl; cerr << get_fileline() << ": debug: genvar init = " << genvar << endl;
container->genvar_tmp = loop_index; container->genvar_tmp = loop_index;
container->genvar_tmp_val = genvar; container->genvar_tmp_val = genvar;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1); NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
@ -397,7 +419,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
NetEConstParam*gp = new NetEConstParam(scope, NetEConstParam*gp = new NetEConstParam(scope,
loop_index, loop_index,
genvar_verinum); genvar_verinum);
scope->set_localparam(loop_index, gp); // The file and line information should really come
// from the genvar statement, not the for loop.
scope->set_localparam(loop_index, gp, get_file(),
get_lineno());
if (debug_scopes) if (debug_scopes)
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "

View File

@ -1217,7 +1217,12 @@ NetExpr* NetEParam::eval_tree(int prune_to_width)
// The result can be saved as the value of the parameter for // The result can be saved as the value of the parameter for
// future reference, and return a copy to the caller. // future reference, and return a copy to the caller.
scope_->replace_parameter(name_, res); bool flag = scope_->replace_parameter(name_, res);
if (!flag) {
cerr << get_fileline() << ": internal error: Could not "
<< "replace parameter expression for " << name_ << endl;
return 0;
}
/* Return as a result a NetEConstParam or NetECRealParam /* Return as a result a NetEConstParam or NetECRealParam
object, depending on the type of the expression. */ object, depending on the type of the expression. */

View File

@ -118,6 +118,8 @@ ivl_nexus_ptr_sig
ivl_parameter_basename ivl_parameter_basename
ivl_parameter_expr ivl_parameter_expr
ivl_parameter_file
ivl_parameter_lineno
ivl_path_condit ivl_path_condit
ivl_path_delay ivl_path_delay
@ -163,7 +165,9 @@ ivl_signal_attr_val
ivl_signal_basename ivl_signal_basename
ivl_signal_data_type ivl_signal_data_type
ivl_signal_dimensions ivl_signal_dimensions
ivl_signal_file
ivl_signal_integer ivl_signal_integer
ivl_signal_lineno
ivl_signal_local ivl_signal_local
ivl_signal_lsb ivl_signal_lsb
ivl_signal_msb ivl_signal_msb

View File

@ -1339,11 +1339,18 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
* ivl_parameter_expr * ivl_parameter_expr
* Return the value of the parameter. This should be a simple * Return the value of the parameter. This should be a simple
* constant expression, an IVL_EX_STRING or IVL_EX_NUMBER. * constant expression, an IVL_EX_STRING or IVL_EX_NUMBER.
*
* ivl_parameter_file
* ivl_parameter_lineno
* Returns the file and line where this parameter is define
*/ */
extern const char* ivl_parameter_basename(ivl_parameter_t net); extern const char* ivl_parameter_basename(ivl_parameter_t net);
extern ivl_scope_t ivl_parameter_scope(ivl_parameter_t net); extern ivl_scope_t ivl_parameter_scope(ivl_parameter_t net);
extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net); extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net);
extern const char* ivl_parameter_file(ivl_parameter_t net);
extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
/* SCOPE /* SCOPE
* Scopes of various sort have these properties. Use these methods to * Scopes of various sort have these properties. Use these methods to
@ -1586,6 +1593,10 @@ extern int ivl_scope_time_units(ivl_scope_t net);
* the attribute value (a string) associated with a key. This * the attribute value (a string) associated with a key. This
* function returns the attribute value for the given key. If the * function returns the attribute value for the given key. If the
* key does not exist, the function returns 0. * key does not exist, the function returns 0.
*
* ivl_signal_file
* ivl_signal_lineno
* Returns the file and line where this signal is defined.
*/ */
extern ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word); extern ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word);
@ -1607,6 +1618,9 @@ extern const char* ivl_signal_name(ivl_signal_t net);
extern const char* ivl_signal_basename(ivl_signal_t net); extern const char* ivl_signal_basename(ivl_signal_t net);
extern const char* ivl_signal_attr(ivl_signal_t net, const char*key); extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
extern const char* ivl_signal_file(ivl_signal_t net);
extern unsigned ivl_signal_lineno(ivl_signal_t net);
extern unsigned ivl_signal_attr_cnt(ivl_signal_t net); extern unsigned ivl_signal_attr_cnt(ivl_signal_t net);
extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx); extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx);

View File

@ -104,7 +104,8 @@ void NetScope::set_line(perm_string file, perm_string def_file,
} }
NetExpr* NetScope::set_parameter(perm_string key, NetExpr*expr, NetExpr* NetScope::set_parameter(perm_string key, NetExpr*expr,
NetExpr*msb, NetExpr*lsb, bool signed_flag) NetExpr*msb, NetExpr*lsb, bool signed_flag,
perm_string file, unsigned lineno)
{ {
param_expr_t&ref = parameters[key]; param_expr_t&ref = parameters[key];
NetExpr* res = ref.expr; NetExpr* res = ref.expr;
@ -112,6 +113,8 @@ NetExpr* NetScope::set_parameter(perm_string key, NetExpr*expr,
ref.msb = msb; ref.msb = msb;
ref.lsb = lsb; ref.lsb = lsb;
ref.signed_flag = signed_flag; ref.signed_flag = signed_flag;
ref.file = file;
ref.lineno = lineno;
return res; return res;
} }
@ -134,29 +137,30 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix)
} }
/* /*
* Return false if this creates a new parameter. * Return false if the parameter does not already exist.
* A parameter is not automatically created.
*/ */
bool NetScope::replace_parameter(perm_string key, NetExpr*expr) bool NetScope::replace_parameter(perm_string key, NetExpr*expr)
{ {
bool flag = true; bool flag = false;
param_expr_t&ref = parameters[key];
NetExpr* res = ref.expr; if (parameters.find(key) != parameters.end()) {
param_expr_t&ref = parameters[key];
if (res) { delete ref.expr;
delete res; ref.expr = expr;
} else { flag = true;
flag = false;
ref.msb = 0;
ref.lsb = 0;
ref.signed_flag = false;
} }
ref.expr = expr;
return flag; return flag;
} }
NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr) /*
* This is not really complete (msb, lsb, sign). It is currently only
* used to add a genver to the local parameter list.
*/
NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr,
perm_string file, unsigned lineno)
{ {
param_expr_t&ref = localparams[key]; param_expr_t&ref = localparams[key];
NetExpr* res = ref.expr; NetExpr* res = ref.expr;
@ -164,6 +168,8 @@ NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr)
ref.msb = 0; ref.msb = 0;
ref.lsb = 0; ref.lsb = 0;
ref.signed_flag = false; ref.signed_flag = false;
ref.file = file;
ref.lineno = lineno;
return res; return res;
} }

View File

@ -3294,8 +3294,10 @@ class NetScope : public Attrib {
previous expression, if there was one. */ previous expression, if there was one. */
NetExpr* set_parameter(perm_string name, NetExpr*val, NetExpr* set_parameter(perm_string name, NetExpr*val,
NetExpr*msb, NetExpr*lsb, bool signed_flag); NetExpr*msb, NetExpr*lsb, bool signed_flag,
NetExpr* set_localparam(perm_string name, NetExpr*val); perm_string file, unsigned lineno);
NetExpr* set_localparam(perm_string name, NetExpr*val,
perm_string file, unsigned lineno);
const NetExpr*get_parameter(const char* name, const NetExpr*get_parameter(const char* name,
const NetExpr*&msb, const NetExpr*&msb,
@ -3410,6 +3412,8 @@ class NetScope : public Attrib {
NetExpr*expr; NetExpr*expr;
NetExpr*msb; NetExpr*msb;
NetExpr*lsb; NetExpr*lsb;
perm_string file;
unsigned lineno;
bool signed_flag; bool signed_flag;
}; };
map<perm_string,param_expr_t>parameters; map<perm_string,param_expr_t>parameters;

View File

@ -2087,7 +2087,7 @@ module_item
| K_generate module_item_list_opt K_endgenerate | K_generate module_item_list_opt K_endgenerate
| K_genvar list_of_identifiers ';' | K_genvar list_of_identifiers ';'
{ pform_genvars($2); } { pform_genvars(@1, $2); }
| K_for '(' IDENTIFIER '=' expression ';' | K_for '(' IDENTIFIER '=' expression ';'
expression ';' expression ';'
@ -2309,7 +2309,8 @@ parameter_assign
} else { } else {
pform_set_parameter(lex_strings.make($1), pform_set_parameter(lex_strings.make($1),
active_signed, active_signed,
active_range, tmp); active_range, tmp,
@1.text, @1.first_line);
} }
delete[]$1; delete[]$1;
} }
@ -2331,7 +2332,8 @@ localparam_assign
} else { } else {
pform_set_localparam(lex_strings.make($1), pform_set_localparam(lex_strings.make($1),
active_signed, active_signed,
active_range, tmp); active_range, tmp,
@1.text, @1.first_line);
} }
delete[]$1; delete[]$1;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2008 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
@ -363,11 +363,14 @@ void pform_endmodule(const char*name)
pform_cur_module = 0; pform_cur_module = 0;
} }
void pform_genvars(list<perm_string>*names) void pform_genvars(const struct vlltype&li, list<perm_string>*names)
{ {
list<perm_string>::const_iterator cur; list<perm_string>::const_iterator cur;
for (cur = names->begin(); cur != names->end() ; *cur++) { for (cur = names->begin(); cur != names->end() ; *cur++) {
pform_cur_module->genvars.push_back( *cur ); LineInfo*lni = new LineInfo();
FILE_NAME(lni, li);
pform_cur_module->genvars.push_back(
pair<perm_string,LineInfo*>(*cur, lni));
} }
delete names; delete names;
@ -1639,7 +1642,8 @@ void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r)
} }
void pform_set_parameter(perm_string name, bool signed_flag, void pform_set_parameter(perm_string name, bool signed_flag,
svector<PExpr*>*range, PExpr*expr) svector<PExpr*>*range, PExpr*expr,
const char*file, unsigned lineno)
{ {
assert(expr); assert(expr);
pform_cur_module->parameters[name].expr = expr; pform_cur_module->parameters[name].expr = expr;
@ -1655,12 +1659,15 @@ void pform_set_parameter(perm_string name, bool signed_flag,
pform_cur_module->parameters[name].lsb = 0; pform_cur_module->parameters[name].lsb = 0;
} }
pform_cur_module->parameters[name].signed_flag = signed_flag; pform_cur_module->parameters[name].signed_flag = signed_flag;
pform_cur_module->parameters[name].file = filename_strings.make(file);
pform_cur_module->parameters[name].lineno = lineno;
pform_cur_module->param_names.push_back(name); pform_cur_module->param_names.push_back(name);
} }
void pform_set_localparam(perm_string name, bool signed_flag, void pform_set_localparam(perm_string name, bool signed_flag,
svector<PExpr*>*range, PExpr*expr) svector<PExpr*>*range, PExpr*expr,
const char*file, unsigned lineno)
{ {
assert(expr); assert(expr);
pform_cur_module->localparams[name].expr = expr; pform_cur_module->localparams[name].expr = expr;
@ -1676,6 +1683,8 @@ void pform_set_localparam(perm_string name, bool signed_flag,
pform_cur_module->localparams[name].lsb = 0; pform_cur_module->localparams[name].lsb = 0;
} }
pform_cur_module->localparams[name].signed_flag = signed_flag; pform_cur_module->localparams[name].signed_flag = signed_flag;
pform_cur_module->localparams[name].file = filename_strings.make(file);
pform_cur_module->localparams[name].lineno = lineno;
} }
void pform_set_specparam(perm_string name, PExpr*expr) void pform_set_specparam(perm_string name, PExpr*expr)
@ -1925,4 +1934,3 @@ void pform_error_nested_modules()
cerr << pform_cur_module->get_fileline() << ": error: original module " cerr << pform_cur_module->get_fileline() << ": error: original module "
"(" << pform_cur_module->mod_name() << ") defined here." << endl; "(" << pform_cur_module->mod_name() << ") defined here." << endl;
} }

19
pform.h
View File

@ -1,7 +1,7 @@
#ifndef __pform_H #ifndef __pform_H
#define __pform_H #define __pform_H
/* /*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2008 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
@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform.h,v 1.91 2007/05/24 04:07:12 steve Exp $"
#endif
# include "netlist.h" # include "netlist.h"
# include "HName.h" # include "HName.h"
@ -175,13 +172,13 @@ extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
extern verinum* pform_verinum_with_size(verinum*s, verinum*val, extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
const char*file, unsigned loneno); const char*file, unsigned lineno);
/* /*
* This function takes the list of names as new genvars to declare in * This function takes the list of names as new genvars to declare in
* the current module scope. * the current module scope.
*/ */
extern void pform_genvars(list<perm_string>*names); extern void pform_genvars(const struct vlltype&li, list<perm_string>*names);
extern void pform_start_generate_for(const struct vlltype&li, extern void pform_start_generate_for(const struct vlltype&li,
char*ident1, char*ident1,
@ -263,11 +260,13 @@ extern void pform_set_type_attrib(perm_string name, const string&key,
extern void pform_set_parameter(perm_string name, extern void pform_set_parameter(perm_string name,
bool signed_flag, bool signed_flag,
svector<PExpr*>*range, svector<PExpr*>*range,
PExpr*expr); PExpr*expr,
const char*file, unsigned lineno);
extern void pform_set_localparam(perm_string name, extern void pform_set_localparam(perm_string name,
bool signed_flag, bool signed_flag,
svector<PExpr*>*range, svector<PExpr*>*range,
PExpr*expr); PExpr*expr,
const char*file, unsigned lineno);
extern void pform_set_defparam(const pform_name_t&name, PExpr*expr); extern void pform_set_defparam(const pform_name_t&name, PExpr*expr);
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2006 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2008 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
@ -995,10 +995,10 @@ void Module::dump(ostream&out) const
out << "/* ERROR */;" << endl; out << "/* ERROR */;" << endl;
} }
typedef list<perm_string>::const_iterator genvar_iter_t; typedef list<pair<perm_string,LineInfo*> >::const_iterator genvar_iter_t;
for (genvar_iter_t cur = genvars.begin() for (genvar_iter_t cur = genvars.begin()
; cur != genvars.end() ; cur++) { ; cur != genvars.end() ; cur++) {
out << " genvar " << (*cur) << ";" << endl; out << " genvar " << ((*cur).first) << ";" << endl;
} }
typedef list<PGenerate*>::const_iterator genscheme_iter_t; typedef list<PGenerate*>::const_iterator genscheme_iter_t;
@ -1123,4 +1123,3 @@ void PUdp::dump(ostream&out) const
out << "endprimitive" << endl; out << "endprimitive" << endl;
} }

View File

@ -1344,6 +1344,18 @@ extern "C" ivl_expr_t ivl_parameter_expr(ivl_parameter_t net)
return net->value; return net->value;
} }
extern "C" const char* ivl_parameter_file(ivl_parameter_t net)
{
assert(net);
return net->file.str();
}
extern "C" unsigned ivl_parameter_lineno(ivl_parameter_t net)
{
assert(net);
return net->lineno;
}
extern "C" ivl_scope_t ivl_parameter_scope(ivl_parameter_t net) extern "C" ivl_scope_t ivl_parameter_scope(ivl_parameter_t net)
{ {
assert(net); assert(net);
@ -1739,6 +1751,18 @@ extern "C" int ivl_signal_signed(ivl_signal_t net)
return net->signed_; return net->signed_;
} }
extern "C" const char* ivl_signal_file(ivl_signal_t net)
{
assert(net);
return net->file.str();
}
extern "C" unsigned ivl_signal_lineno(ivl_signal_t net)
{
assert(net);
return net->lineno;
}
extern "C" int ivl_signal_integer(ivl_signal_t net) extern "C" int ivl_signal_integer(ivl_signal_t net)
{ {
return net->isint_; return net->isint_;

View File

@ -470,6 +470,8 @@ void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
ivl_parameter_t cur_par = scope->param_ + idx; ivl_parameter_t cur_par = scope->param_ + idx;
cur_par->basename = (*cur_pit).first; cur_par->basename = (*cur_pit).first;
cur_par->scope = scope; cur_par->scope = scope;
cur_par->file = (*cur_pit).second.file;
cur_par->lineno = (*cur_pit).second.lineno;
NetExpr*etmp = (*cur_pit).second.expr; NetExpr*etmp = (*cur_pit).second.expr;
make_scope_param_expr(cur_par, etmp); make_scope_param_expr(cur_par, etmp);
@ -482,6 +484,8 @@ void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
ivl_parameter_t cur_par = scope->param_ + idx; ivl_parameter_t cur_par = scope->param_ + idx;
cur_par->basename = (*cur_pit).first; cur_par->basename = (*cur_pit).first;
cur_par->scope = scope; cur_par->scope = scope;
cur_par->file = (*cur_pit).second.file;
cur_par->lineno = (*cur_pit).second.lineno;
NetExpr*etmp = (*cur_pit).second.expr; NetExpr*etmp = (*cur_pit).second.expr;
make_scope_param_expr(cur_par, etmp); make_scope_param_expr(cur_par, etmp);
@ -2216,6 +2220,8 @@ void dll_target::signal(const NetNet*net)
object, or creating the sigs_ array if this is the first object, or creating the sigs_ array if this is the first
signal. */ signal. */
obj->scope_ = find_scope(des_, net->scope()); obj->scope_ = find_scope(des_, net->scope());
obj->file = perm_string::literal("N/A");
obj->lineno = 0;
assert(obj->scope_); assert(obj->scope_);
if (obj->scope_->nsigs_ == 0) { if (obj->scope_->nsigs_ == 0) {

View File

@ -509,6 +509,8 @@ struct ivl_parameter_s {
perm_string basename; perm_string basename;
ivl_scope_t scope; ivl_scope_t scope;
ivl_expr_t value; ivl_expr_t value;
perm_string file;
unsigned lineno;
}; };
/* /*
* All we know about a process it its type (initial or always) and the * All we know about a process it its type (initial or always) and the
@ -581,6 +583,8 @@ struct ivl_signal_s {
ivl_signal_type_t type_; ivl_signal_type_t type_;
ivl_signal_port_t port_; ivl_signal_port_t port_;
ivl_variable_type_t data_type; ivl_variable_type_t data_type;
perm_string file;
unsigned lineno;
unsigned width_; unsigned width_;
unsigned signed_ : 1; unsigned signed_ : 1;

View File

@ -2466,13 +2466,17 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
ivl_expr_t pex = ivl_parameter_expr(par); ivl_expr_t pex = ivl_parameter_expr(par);
switch (ivl_expr_type(pex)) { switch (ivl_expr_type(pex)) {
case IVL_EX_STRING: case IVL_EX_STRING:
fprintf(vvp_out, "P_%p .param/str \"%s\", \"%s\";\n", fprintf(vvp_out, "P_%p .param/str \"%s\" %d %d, \"%s\";\n",
par, ivl_parameter_basename(par), par, ivl_parameter_basename(par),
ivl_file_table_index(ivl_parameter_file(par)),
ivl_parameter_lineno(par),
ivl_expr_string(pex)); ivl_expr_string(pex));
break; break;
case IVL_EX_NUMBER: case IVL_EX_NUMBER:
fprintf(vvp_out, "P_%p .param/l \"%s\", %sC4<", fprintf(vvp_out, "P_%p .param/l \"%s\" %d %d, %sC4<",
par, ivl_parameter_basename(par), par, ivl_parameter_basename(par),
ivl_file_table_index(ivl_parameter_file(par)),
ivl_parameter_lineno(par),
ivl_expr_signed(pex)? "+":""); ivl_expr_signed(pex)? "+":"");
{ const char*bits = ivl_expr_bits(pex); { const char*bits = ivl_expr_bits(pex);
unsigned nbits = ivl_expr_width(pex); unsigned nbits = ivl_expr_width(pex);
@ -2483,8 +2487,10 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
fprintf(vvp_out, ">;\n"); fprintf(vvp_out, ">;\n");
break; break;
case IVL_EX_REALNUM: case IVL_EX_REALNUM:
fprintf(vvp_out, "P_%p .param/real \"%s\", %s; value=%g\n", fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; value=%g\n",
par, ivl_parameter_basename(par), par, ivl_parameter_basename(par),
ivl_file_table_index(ivl_parameter_file(par)),
ivl_parameter_lineno(par),
draw_Cr_to_string(ivl_expr_dvalue(pex)), draw_Cr_to_string(ivl_expr_dvalue(pex)),
ivl_expr_dvalue(pex)); ivl_expr_dvalue(pex));
break; break;

View File

@ -1852,10 +1852,12 @@ void compile_thread(char*start_sym, char*flag)
free(flag); free(flag);
} }
void compile_param_logic(char*label, char*name, char*value, bool signed_flag) void compile_param_logic(char*label, char*name, char*value, bool signed_flag,
long file_idx, long lineno)
{ {
vvp_vector4_t value4 = c4string_to_vector4(value); vvp_vector4_t value4 = c4string_to_vector4(value);
vpiHandle obj = vpip_make_binary_param(name, value4, signed_flag); vpiHandle obj = vpip_make_binary_param(name, value4, signed_flag,
file_idx, lineno);
compile_vpi_symbol(label, obj); compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj); vpip_attach_to_current_scope(obj);
@ -1863,19 +1865,21 @@ void compile_param_logic(char*label, char*name, char*value, bool signed_flag)
free(value); free(value);
} }
void compile_param_string(char*label, char*name, char*value) void compile_param_string(char*label, char*name, char*value,
long file_idx, long lineno)
{ {
vpiHandle obj = vpip_make_string_param(name, value); vpiHandle obj = vpip_make_string_param(name, value, file_idx, lineno);
compile_vpi_symbol(label, obj); compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj); vpip_attach_to_current_scope(obj);
free(label); free(label);
} }
void compile_param_real(char*label, char*name, char*value) void compile_param_real(char*label, char*name, char*value,
long file_idx, long lineno)
{ {
double dvalue = crstring_to_double(value); double dvalue = crstring_to_double(value);
vpiHandle obj = vpip_make_real_param(name, dvalue); vpiHandle obj = vpip_make_real_param(name, dvalue, file_idx, lineno);
compile_vpi_symbol(label, obj); compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj); vpip_attach_to_current_scope(obj);

View File

@ -233,10 +233,13 @@ extern void compile_timescale(long units, long precision);
extern void compile_vpi_symbol(const char*label, vpiHandle obj); extern void compile_vpi_symbol(const char*label, vpiHandle obj);
extern void compile_vpi_lookup(vpiHandle *objref, char*label); extern void compile_vpi_lookup(vpiHandle *objref, char*label);
extern void compile_param_string(char*label, char*name, char*value); extern void compile_param_string(char*label, char*name, char*value,
long file_idx, long lineno);
extern void compile_param_logic(char*label, char*name, char*value, extern void compile_param_logic(char*label, char*name, char*value,
bool signed_flag); bool signed_flag,
extern void compile_param_real(char*label, char*name, char*value); long file_idx, long lineno);
extern void compile_param_real(char*label, char*name, char*value,
long file_idx, long lineno);
/* /*
* This function schedules a lookup of an indexed label. The ref * This function schedules a lookup of an indexed label. The ref

View File

@ -658,17 +658,17 @@ statement
/* Parameter statements come in a few simple forms. The most basic /* Parameter statements come in a few simple forms. The most basic
is the string parameter. */ is the string parameter. */
| T_LABEL K_PARAM_STR T_STRING ',' T_STRING ';' | T_LABEL K_PARAM_STR T_STRING T_NUMBER T_NUMBER',' T_STRING ';'
{ compile_param_string($1, $3, $5); } { compile_param_string($1, $3, $7, $4, $5); }
| T_LABEL K_PARAM_L T_STRING ',' T_SYMBOL ';' | T_LABEL K_PARAM_L T_STRING T_NUMBER T_NUMBER',' T_SYMBOL ';'
{ compile_param_logic($1, $3, $5, false); } { compile_param_logic($1, $3, $7, false, $4, $5); }
| T_LABEL K_PARAM_L T_STRING ',' '+' T_SYMBOL ';' | T_LABEL K_PARAM_L T_STRING T_NUMBER T_NUMBER',' '+' T_SYMBOL ';'
{ compile_param_logic($1, $3, $6, true); } { compile_param_logic($1, $3, $8, true, $4, $5); }
| T_LABEL K_PARAM_REAL T_STRING ',' T_SYMBOL ';' | T_LABEL K_PARAM_REAL T_STRING T_NUMBER T_NUMBER',' T_SYMBOL ';'
{ compile_param_real($1, $3, $5); } { compile_param_real($1, $3, $7, $4, $5); }
/* Oh and by the way, empty statements are OK as well. */ /* Oh and by the way, empty statements are OK as well. */

View File

@ -32,9 +32,6 @@ static int string_get(int code, vpiHandle ref)
struct __vpiStringConst*rfp; struct __vpiStringConst*rfp;
switch (code) { switch (code) {
case vpiLineNo:
return 0; // Not implemented for now!
case vpiSize: case vpiSize:
rfp = (struct __vpiStringConst*)ref; rfp = (struct __vpiStringConst*)ref;
@ -247,17 +244,33 @@ vpiHandle vpip_make_string_const(char*text, bool persistent_flag)
struct __vpiStringParam : public __vpiStringConst { struct __vpiStringParam : public __vpiStringConst {
const char*basename; const char*basename;
struct __vpiScope* scope; struct __vpiScope* scope;
unsigned file_idx;
unsigned lineno;
}; };
static int string_param_get(int code, vpiHandle ref)
{
struct __vpiStringParam*rfp = (struct __vpiStringParam*)ref;
assert(ref->vpi_type->type_code == vpiParameter);
if (code == vpiLineNo) {
return rfp->lineno;
}
return string_get(code, ref);
}
static char* string_param_get_str(int code, vpiHandle obj) static char* string_param_get_str(int code, vpiHandle obj)
{ {
struct __vpiStringParam*rfp = (struct __vpiStringParam*)obj; struct __vpiStringParam*rfp = (struct __vpiStringParam*)obj;
assert(obj->vpi_type->type_code == vpiParameter); assert(obj->vpi_type->type_code == vpiParameter);
if (code == vpiFile) { // Not implemented for now! if (code == vpiFile) {
return simple_set_rbuf_str(file_names[0]); return simple_set_rbuf_str(file_names[rfp->file_idx]);
} }
return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL); return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL);
} }
@ -278,7 +291,7 @@ static vpiHandle string_param_handle(int code, vpiHandle obj)
static const struct __vpirt vpip_string_param_rt = { static const struct __vpirt vpip_string_param_rt = {
vpiParameter, vpiParameter,
string_get, string_param_get,
string_param_get_str, string_param_get_str,
string_value, string_value,
0, 0,
@ -291,7 +304,8 @@ static const struct __vpirt vpip_string_param_rt = {
}; };
vpiHandle vpip_make_string_param(char*name, char*text) vpiHandle vpip_make_string_param(char*name, char*text,
long file_idx, long lineno)
{ {
struct __vpiStringParam*obj; struct __vpiStringParam*obj;
@ -302,6 +316,8 @@ vpiHandle vpip_make_string_param(char*name, char*text)
obj->value_len = 0; obj->value_len = 0;
obj->basename = name; obj->basename = name;
obj->scope = vpip_peek_current_scope(); obj->scope = vpip_peek_current_scope();
obj->file_idx = (unsigned) file_idx;
obj->lineno = (unsigned) lineno;
vpip_process_string(obj); vpip_process_string(obj);
@ -426,17 +442,33 @@ vpiHandle vpip_make_binary_const(unsigned wid, const char*bits)
struct __vpiBinaryParam : public __vpiBinaryConst { struct __vpiBinaryParam : public __vpiBinaryConst {
const char*basename; const char*basename;
struct __vpiScope*scope; struct __vpiScope*scope;
unsigned file_idx;
unsigned lineno;
}; };
static int binary_param_get(int code, vpiHandle ref)
{
struct __vpiBinaryParam*rfp = (struct __vpiBinaryParam*)ref;
assert(ref->vpi_type->type_code == vpiParameter);
if (code == vpiLineNo) {
return rfp->lineno;
}
return binary_get(code, ref);
}
static char* binary_param_get_str(int code, vpiHandle obj) static char* binary_param_get_str(int code, vpiHandle obj)
{ {
struct __vpiBinaryParam*rfp = (struct __vpiBinaryParam*)obj; struct __vpiBinaryParam*rfp = (struct __vpiBinaryParam*)obj;
assert(obj->vpi_type->type_code == vpiParameter); assert(obj->vpi_type->type_code == vpiParameter);
if (code == vpiFile) { // Not implemented for now! if (code == vpiFile) {
return simple_set_rbuf_str(file_names[0]); return simple_set_rbuf_str(file_names[rfp->file_idx]);
} }
return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL); return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL);
} }
@ -457,7 +489,7 @@ static vpiHandle binary_param_handle(int code, vpiHandle obj)
static const struct __vpirt vpip_binary_param_rt = { static const struct __vpirt vpip_binary_param_rt = {
vpiParameter, vpiParameter,
binary_get, binary_param_get,
binary_param_get_str, binary_param_get_str,
binary_value, binary_value,
0, 0,
@ -470,7 +502,8 @@ static const struct __vpirt vpip_binary_param_rt = {
}; };
vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits, vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits,
bool signed_flag) bool signed_flag,
long file_idx, long lineno)
{ {
struct __vpiBinaryParam*obj = new __vpiBinaryParam; struct __vpiBinaryParam*obj = new __vpiBinaryParam;
@ -480,6 +513,8 @@ vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits,
obj->sized_flag = 0; obj->sized_flag = 0;
obj->basename = name; obj->basename = name;
obj->scope = vpip_peek_current_scope(); obj->scope = vpip_peek_current_scope();
obj->file_idx = (unsigned) file_idx;
obj->lineno = (unsigned) lineno;
return &obj->base; return &obj->base;
} }
@ -654,17 +689,33 @@ vpiHandle vpip_make_real_const(double value)
struct __vpiRealParam : public __vpiRealConst { struct __vpiRealParam : public __vpiRealConst {
const char*basename; const char*basename;
struct __vpiScope* scope; struct __vpiScope* scope;
unsigned file_idx;
unsigned lineno;
}; };
static int real_param_get(int code, vpiHandle ref)
{
struct __vpiRealParam*rfp = (struct __vpiRealParam*)ref;
assert(ref->vpi_type->type_code == vpiParameter);
if (code == vpiLineNo) {
return rfp->lineno;
}
return real_get(code, ref);
}
static char* real_param_get_str(int code, vpiHandle obj) static char* real_param_get_str(int code, vpiHandle obj)
{ {
struct __vpiRealParam*rfp = (struct __vpiRealParam*)obj; struct __vpiRealParam*rfp = (struct __vpiRealParam*)obj;
assert(obj->vpi_type->type_code == vpiParameter); assert(obj->vpi_type->type_code == vpiParameter);
if (code == vpiFile) { // Not implemented for now! if (code == vpiFile) {
return simple_set_rbuf_str(file_names[0]); return simple_set_rbuf_str(file_names[rfp->file_idx]);
} }
return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL); return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL);
} }
@ -685,7 +736,7 @@ static vpiHandle real_param_handle(int code, vpiHandle obj)
static const struct __vpirt vpip_real_param_rt = { static const struct __vpirt vpip_real_param_rt = {
vpiParameter, vpiParameter,
real_get, real_param_get,
real_param_get_str, real_param_get_str,
real_value, real_value,
0, 0,
@ -697,7 +748,8 @@ static const struct __vpirt vpip_real_param_rt = {
0 0
}; };
vpiHandle vpip_make_real_param(char*name, double value) vpiHandle vpip_make_real_param(char*name, double value,
long file_idx, long lineno)
{ {
struct __vpiRealParam*obj; struct __vpiRealParam*obj;
@ -707,6 +759,8 @@ vpiHandle vpip_make_real_param(char*name, double value)
obj->value = value; obj->value = value;
obj->basename = name; obj->basename = name;
obj->scope = vpip_peek_current_scope(); obj->scope = vpip_peek_current_scope();
obj->file_idx = (unsigned) file_idx;
obj->lineno = (unsigned) lineno;
return &obj->base; return &obj->base;
} }

View File

@ -390,7 +390,8 @@ struct __vpiStringConst {
}; };
vpiHandle vpip_make_string_const(char*text, bool persistent =true); vpiHandle vpip_make_string_const(char*text, bool persistent =true);
vpiHandle vpip_make_string_param(char*name, char*value); vpiHandle vpip_make_string_param(char*name, char*value,
long file_idx, long lineno);
struct __vpiBinaryConst { struct __vpiBinaryConst {
struct __vpiHandle base; struct __vpiHandle base;
@ -403,7 +404,8 @@ struct __vpiBinaryConst {
vpiHandle vpip_make_binary_const(unsigned wid, const char*bits); vpiHandle vpip_make_binary_const(unsigned wid, const char*bits);
vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits, vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits,
bool signed_flag); bool signed_flag,
long file_idx, long lineno);
struct __vpiDecConst { struct __vpiDecConst {
struct __vpiHandle base; struct __vpiHandle base;
@ -419,7 +421,8 @@ struct __vpiRealConst {
}; };
vpiHandle vpip_make_real_const(double value); vpiHandle vpip_make_real_const(double value);
vpiHandle vpip_make_real_param(char*name, double value); vpiHandle vpip_make_real_param(char*name, double value,
long file_idx, long lineno);
/* /*
* This one looks like a constant, but really is a vector in the current * This one looks like a constant, but really is a vector in the current