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*msb;
PExpr*lsb;
perm_string file;
unsigned lineno;
bool signed_flag;
};
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
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 definition. These are used at elaboration time. */
@ -156,7 +158,8 @@ class Module : public PScope, public LineInfo {
map<perm_string,PFunction*> funcs_;
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
Module(const Module&);

View File

@ -45,7 +45,8 @@
# include <assert.h>
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;
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,
msb, lsb, signed_flag);
msb, lsb, signed_flag, file, lineno);
assert(val);
delete val;
}
@ -119,7 +120,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
tmp->set_line(*((*cur).second.expr));
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()
@ -130,7 +132,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
if ((*cur).second.msb)
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()
; 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
@ -174,7 +178,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (mparm_it_t cur = localparams.begin()
; 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
@ -339,6 +344,11 @@ bool PGenerate::generate_scope(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...
int genvar;
@ -354,12 +364,24 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
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();
delete init_ex;
if (debug_scopes)
cerr << get_fileline() << ": debug: genvar init = " << genvar << endl;
container->genvar_tmp = loop_index;
container->genvar_tmp_val = genvar;
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,
loop_index,
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)
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
// 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
object, depending on the type of the expression. */

View File

@ -118,6 +118,8 @@ ivl_nexus_ptr_sig
ivl_parameter_basename
ivl_parameter_expr
ivl_parameter_file
ivl_parameter_lineno
ivl_path_condit
ivl_path_delay
@ -163,7 +165,9 @@ ivl_signal_attr_val
ivl_signal_basename
ivl_signal_data_type
ivl_signal_dimensions
ivl_signal_file
ivl_signal_integer
ivl_signal_lineno
ivl_signal_local
ivl_signal_lsb
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
* Return the value of the parameter. This should be a simple
* 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 ivl_scope_t ivl_parameter_scope(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
* 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
* function returns the attribute value for the given key. If the
* 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);
@ -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_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 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*msb, NetExpr*lsb, bool signed_flag)
NetExpr*msb, NetExpr*lsb, bool signed_flag,
perm_string file, unsigned lineno)
{
param_expr_t&ref = parameters[key];
NetExpr* res = ref.expr;
@ -112,6 +113,8 @@ NetExpr* NetScope::set_parameter(perm_string key, NetExpr*expr,
ref.msb = msb;
ref.lsb = lsb;
ref.signed_flag = signed_flag;
ref.file = file;
ref.lineno = lineno;
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 flag = true;
bool flag = false;
if (parameters.find(key) != parameters.end()) {
param_expr_t&ref = parameters[key];
NetExpr* res = ref.expr;
if (res) {
delete res;
} else {
flag = false;
ref.msb = 0;
ref.lsb = 0;
ref.signed_flag = false;
delete ref.expr;
ref.expr = expr;
flag = true;
}
ref.expr = expr;
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];
NetExpr* res = ref.expr;
@ -164,6 +168,8 @@ NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr)
ref.msb = 0;
ref.lsb = 0;
ref.signed_flag = false;
ref.file = file;
ref.lineno = lineno;
return res;
}

View File

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

View File

@ -2087,7 +2087,7 @@ module_item
| K_generate module_item_list_opt K_endgenerate
| K_genvar list_of_identifiers ';'
{ pform_genvars($2); }
{ pform_genvars(@1, $2); }
| K_for '(' IDENTIFIER '=' expression ';'
expression ';'
@ -2309,7 +2309,8 @@ parameter_assign
} else {
pform_set_parameter(lex_strings.make($1),
active_signed,
active_range, tmp);
active_range, tmp,
@1.text, @1.first_line);
}
delete[]$1;
}
@ -2331,7 +2332,8 @@ localparam_assign
} else {
pform_set_localparam(lex_strings.make($1),
active_signed,
active_range, tmp);
active_range, tmp,
@1.text, @1.first_line);
}
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
* 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;
}
void pform_genvars(list<perm_string>*names)
void pform_genvars(const struct vlltype&li, list<perm_string>*names)
{
list<perm_string>::const_iterator 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;
@ -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,
svector<PExpr*>*range, PExpr*expr)
svector<PExpr*>*range, PExpr*expr,
const char*file, unsigned lineno)
{
assert(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].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);
}
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);
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].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)
@ -1925,4 +1934,3 @@ void pform_error_nested_modules()
cerr << pform_cur_module->get_fileline() << ": error: original module "
"(" << pform_cur_module->mod_name() << ") defined here." << endl;
}

15
pform.h
View File

@ -1,7 +1,7 @@
#ifndef __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
* 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
* 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 "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,
const char*file, unsigned loneno);
const char*file, unsigned lineno);
/*
* This function takes the list of names as new genvars to declare in
* 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,
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,
bool signed_flag,
svector<PExpr*>*range,
PExpr*expr);
PExpr*expr,
const char*file, unsigned lineno);
extern void pform_set_localparam(perm_string name,
bool signed_flag,
svector<PExpr*>*range,
PExpr*expr);
PExpr*expr,
const char*file, unsigned lineno);
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
* 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;
}
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()
; cur != genvars.end() ; cur++) {
out << " genvar " << (*cur) << ";" << endl;
out << " genvar " << ((*cur).first) << ";" << endl;
}
typedef list<PGenerate*>::const_iterator genscheme_iter_t;
@ -1123,4 +1123,3 @@ void PUdp::dump(ostream&out) const
out << "endprimitive" << endl;
}

View File

@ -1344,6 +1344,18 @@ extern "C" ivl_expr_t ivl_parameter_expr(ivl_parameter_t net)
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)
{
assert(net);
@ -1739,6 +1751,18 @@ extern "C" int ivl_signal_signed(ivl_signal_t net)
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)
{
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;
cur_par->basename = (*cur_pit).first;
cur_par->scope = scope;
cur_par->file = (*cur_pit).second.file;
cur_par->lineno = (*cur_pit).second.lineno;
NetExpr*etmp = (*cur_pit).second.expr;
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;
cur_par->basename = (*cur_pit).first;
cur_par->scope = scope;
cur_par->file = (*cur_pit).second.file;
cur_par->lineno = (*cur_pit).second.lineno;
NetExpr*etmp = (*cur_pit).second.expr;
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
signal. */
obj->scope_ = find_scope(des_, net->scope());
obj->file = perm_string::literal("N/A");
obj->lineno = 0;
assert(obj->scope_);
if (obj->scope_->nsigs_ == 0) {

View File

@ -509,6 +509,8 @@ struct ivl_parameter_s {
perm_string basename;
ivl_scope_t scope;
ivl_expr_t value;
perm_string file;
unsigned lineno;
};
/*
* 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_port_t port_;
ivl_variable_type_t data_type;
perm_string file;
unsigned lineno;
unsigned width_;
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);
switch (ivl_expr_type(pex)) {
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),
ivl_file_table_index(ivl_parameter_file(par)),
ivl_parameter_lineno(par),
ivl_expr_string(pex));
break;
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),
ivl_file_table_index(ivl_parameter_file(par)),
ivl_parameter_lineno(par),
ivl_expr_signed(pex)? "+":"");
{ const char*bits = ivl_expr_bits(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");
break;
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),
ivl_file_table_index(ivl_parameter_file(par)),
ivl_parameter_lineno(par),
draw_Cr_to_string(ivl_expr_dvalue(pex)),
ivl_expr_dvalue(pex));
break;

View File

@ -1852,10 +1852,12 @@ void compile_thread(char*start_sym, char*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);
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);
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);
}
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);
vpip_attach_to_current_scope(obj);
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);
vpiHandle obj = vpip_make_real_param(name, dvalue);
vpiHandle obj = vpip_make_real_param(name, dvalue, file_idx, lineno);
compile_vpi_symbol(label, 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_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,
bool signed_flag);
extern void compile_param_real(char*label, char*name, char*value);
bool signed_flag,
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

View File

@ -658,17 +658,17 @@ statement
/* Parameter statements come in a few simple forms. The most basic
is the string parameter. */
| T_LABEL K_PARAM_STR T_STRING ',' T_STRING ';'
{ compile_param_string($1, $3, $5); }
| T_LABEL K_PARAM_STR T_STRING T_NUMBER T_NUMBER',' T_STRING ';'
{ compile_param_string($1, $3, $7, $4, $5); }
| T_LABEL K_PARAM_L T_STRING ',' T_SYMBOL ';'
{ compile_param_logic($1, $3, $5, false); }
| T_LABEL K_PARAM_L T_STRING T_NUMBER T_NUMBER',' T_SYMBOL ';'
{ compile_param_logic($1, $3, $7, false, $4, $5); }
| T_LABEL K_PARAM_L T_STRING ',' '+' T_SYMBOL ';'
{ compile_param_logic($1, $3, $6, true); }
| T_LABEL K_PARAM_L T_STRING T_NUMBER T_NUMBER',' '+' T_SYMBOL ';'
{ compile_param_logic($1, $3, $8, true, $4, $5); }
| T_LABEL K_PARAM_REAL T_STRING ',' T_SYMBOL ';'
{ compile_param_real($1, $3, $5); }
| T_LABEL K_PARAM_REAL T_STRING T_NUMBER T_NUMBER',' T_SYMBOL ';'
{ compile_param_real($1, $3, $7, $4, $5); }
/* 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;
switch (code) {
case vpiLineNo:
return 0; // Not implemented for now!
case vpiSize:
rfp = (struct __vpiStringConst*)ref;
@ -247,17 +244,33 @@ vpiHandle vpip_make_string_const(char*text, bool persistent_flag)
struct __vpiStringParam : public __vpiStringConst {
const char*basename;
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)
{
struct __vpiStringParam*rfp = (struct __vpiStringParam*)obj;
assert(obj->vpi_type->type_code == vpiParameter);
if (code == vpiFile) { // Not implemented for now!
return simple_set_rbuf_str(file_names[0]);
if (code == vpiFile) {
return simple_set_rbuf_str(file_names[rfp->file_idx]);
}
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 = {
vpiParameter,
string_get,
string_param_get,
string_param_get_str,
string_value,
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;
@ -302,6 +316,8 @@ vpiHandle vpip_make_string_param(char*name, char*text)
obj->value_len = 0;
obj->basename = name;
obj->scope = vpip_peek_current_scope();
obj->file_idx = (unsigned) file_idx;
obj->lineno = (unsigned) lineno;
vpip_process_string(obj);
@ -426,17 +442,33 @@ vpiHandle vpip_make_binary_const(unsigned wid, const char*bits)
struct __vpiBinaryParam : public __vpiBinaryConst {
const char*basename;
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)
{
struct __vpiBinaryParam*rfp = (struct __vpiBinaryParam*)obj;
assert(obj->vpi_type->type_code == vpiParameter);
if (code == vpiFile) { // Not implemented for now!
return simple_set_rbuf_str(file_names[0]);
if (code == vpiFile) {
return simple_set_rbuf_str(file_names[rfp->file_idx]);
}
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 = {
vpiParameter,
binary_get,
binary_param_get,
binary_param_get_str,
binary_value,
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,
bool signed_flag)
bool signed_flag,
long file_idx, long lineno)
{
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->basename = name;
obj->scope = vpip_peek_current_scope();
obj->file_idx = (unsigned) file_idx;
obj->lineno = (unsigned) lineno;
return &obj->base;
}
@ -654,17 +689,33 @@ vpiHandle vpip_make_real_const(double value)
struct __vpiRealParam : public __vpiRealConst {
const char*basename;
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)
{
struct __vpiRealParam*rfp = (struct __vpiRealParam*)obj;
assert(obj->vpi_type->type_code == vpiParameter);
if (code == vpiFile) { // Not implemented for now!
return simple_set_rbuf_str(file_names[0]);
if (code == vpiFile) {
return simple_set_rbuf_str(file_names[rfp->file_idx]);
}
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 = {
vpiParameter,
real_get,
real_param_get,
real_param_get_str,
real_value,
0,
@ -697,7 +748,8 @@ static const struct __vpirt vpip_real_param_rt = {
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;
@ -707,6 +759,8 @@ vpiHandle vpip_make_real_param(char*name, double value)
obj->value = value;
obj->basename = name;
obj->scope = vpip_peek_current_scope();
obj->file_idx = (unsigned) file_idx;
obj->lineno = (unsigned) lineno;
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_param(char*name, char*value);
vpiHandle vpip_make_string_param(char*name, char*value,
long file_idx, long lineno);
struct __vpiBinaryConst {
struct __vpiHandle base;
@ -403,7 +404,8 @@ struct __vpiBinaryConst {
vpiHandle vpip_make_binary_const(unsigned wid, const char*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 __vpiHandle base;
@ -419,7 +421,8 @@ struct __vpiRealConst {
};
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