Merge branch 'master' of github.com:steveicarus/iverilog
This commit is contained in:
commit
dd9d96eb07
|
|
@ -118,8 +118,8 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
|||
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
|
||||
PGenerate.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
|
||||
Statement.o AStatement.o $M $(FF) $(TT)
|
||||
PGenerate.o PModport.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o \
|
||||
PFunction.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
|
||||
|
||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
|
|
|
|||
10
Module.h
10
Module.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_Module_H
|
||||
#define IVL_Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2015 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
|
||||
|
|
@ -35,6 +35,7 @@ class PExpr;
|
|||
class PEIdent;
|
||||
class PGate;
|
||||
class PGenerate;
|
||||
class PModport;
|
||||
class PSpecPath;
|
||||
class PTask;
|
||||
class PFunction;
|
||||
|
|
@ -68,7 +69,7 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
|
||||
public:
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This make must be a permallocated string. */
|
||||
name. This name must be a permallocated string. */
|
||||
explicit Module(LexicalScope*parent, perm_string name);
|
||||
~Module();
|
||||
|
||||
|
|
@ -134,6 +135,11 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
unless they are instantiated, implicitly or explicitly. */
|
||||
std::map<perm_string,Module*> nested_modules;
|
||||
|
||||
/* An interface can contain one or more named modport lists.
|
||||
The parser will ensure these don't appear in modules or
|
||||
program blocks. */
|
||||
map<perm_string,PModport*> modports;
|
||||
|
||||
list<PSpecPath*> specify_paths;
|
||||
|
||||
// The mod_name() is the name of the module type.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2015 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
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PModport.h"
|
||||
|
||||
PModport::PModport(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PModport::~PModport()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef IVL_PModport_H
|
||||
#define IVL_PModport_H
|
||||
/*
|
||||
* Copyright (c) 2015 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
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PScope.h"
|
||||
# include "StringHeap.h"
|
||||
# include "netlist.h"
|
||||
# include <vector>
|
||||
|
||||
/*
|
||||
* The PModport class represents a parsed SystemVerilog modport list.
|
||||
*/
|
||||
class PModport : public LineInfo {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the modport, without any scope.
|
||||
explicit PModport(perm_string name);
|
||||
~PModport();
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
|
||||
typedef pair <NetNet::PortType,PExpr*> simple_port_t;
|
||||
map<perm_string,simple_port_t> simple_ports;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
||||
private: // not implemented
|
||||
PModport(const PModport&);
|
||||
PModport& operator= (const PModport&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PModport_H */
|
||||
133
parse.y
133
parse.y
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -49,6 +49,16 @@ static struct {
|
|||
data_type_t* data_type;
|
||||
} port_declaration_context = {NetNet::NONE, NetNet::NOT_A_PORT, 0};
|
||||
|
||||
/* Modport port declaration lists use this structure for context. */
|
||||
enum modport_port_type_t { MP_NONE, MP_SIMPLE, MP_TF, MP_CLOCKING };
|
||||
static struct {
|
||||
modport_port_type_t type;
|
||||
union {
|
||||
NetNet::PortType direction;
|
||||
bool is_import;
|
||||
};
|
||||
} last_modport_port = { MP_NONE, {NetNet::NOT_A_PORT}};
|
||||
|
||||
/* The task and function rules need to briefly hold the pointer to the
|
||||
task/function that is currently in progress. */
|
||||
static PTask* current_task = 0;
|
||||
|
|
@ -549,6 +559,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%type <flag> from_exclude block_item_decls_opt
|
||||
%type <number> number pos_neg_number
|
||||
%type <flag> signing unsigned_signed_opt signed_unsigned_opt
|
||||
%type <flag> import_export
|
||||
%type <flag> K_automatic_opt K_packed_opt K_reg_opt K_static_opt K_virtual_opt
|
||||
%type <flag> udp_reg_opt edge_operator
|
||||
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
||||
|
|
@ -583,7 +594,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%type <tf_ports> task_item task_item_list task_item_list_opt
|
||||
%type <tf_ports> tf_port_declaration tf_port_item tf_port_list tf_port_list_opt
|
||||
|
||||
%type <named_pexpr> port_name parameter_value_byname
|
||||
%type <named_pexpr> modport_simple_port port_name parameter_value_byname
|
||||
%type <named_pexprs> port_name_list parameter_value_byname_list
|
||||
|
||||
%type <named_pexpr> attribute
|
||||
|
|
@ -1270,6 +1281,11 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
|||
|
||||
;
|
||||
|
||||
import_export /* IEEE1800-2012: A.2.9 */
|
||||
: K_import { $$ = true; }
|
||||
| K_export { $$ = false; }
|
||||
;
|
||||
|
||||
implicit_class_handle /* IEEE1800-2005: A.8.4 */
|
||||
: K_this { $$ = pform_create_this(); }
|
||||
| K_super { $$ = pform_create_super(); }
|
||||
|
|
@ -1546,6 +1562,115 @@ method_qualifier_opt
|
|||
|
|
||||
;
|
||||
|
||||
modport_declaration /* IEEE1800-2012: A.2.9 */
|
||||
: K_modport
|
||||
{ if (!pform_in_interface())
|
||||
yyerror(@1, "error: modport declarations are only allowed "
|
||||
"in interfaces.");
|
||||
}
|
||||
modport_item_list ';'
|
||||
|
||||
modport_item_list
|
||||
: modport_item
|
||||
| modport_item_list ',' modport_item
|
||||
;
|
||||
|
||||
modport_item
|
||||
: IDENTIFIER
|
||||
{ pform_start_modport_item(@1, $1); }
|
||||
'(' modport_ports_list ')'
|
||||
{ pform_end_modport_item(@1); }
|
||||
;
|
||||
|
||||
/* The modport_ports_list is a LALR(2) grammar. When the parser sees a
|
||||
',' it needs to look ahead to the next token to decide whether it is
|
||||
a continuation of the preceeding modport_ports_declaration, or the
|
||||
start of a new modport_ports_declaration. bison only supports LALR(1),
|
||||
so we have to handcraft a mini parser for this part of the syntax.
|
||||
last_modport_port holds the state for this mini parser.*/
|
||||
|
||||
modport_ports_list
|
||||
: modport_ports_declaration
|
||||
| modport_ports_list ',' modport_ports_declaration
|
||||
| modport_ports_list ',' modport_simple_port
|
||||
{ if (last_modport_port.type == MP_SIMPLE) {
|
||||
pform_add_modport_port(@3, last_modport_port.direction,
|
||||
$3->name, $3->parm);
|
||||
} else {
|
||||
yyerror(@3, "error: modport expression not allowed here.");
|
||||
}
|
||||
delete $3;
|
||||
}
|
||||
| modport_ports_list ',' modport_tf_port
|
||||
{ if (last_modport_port.type != MP_TF)
|
||||
yyerror(@3, "error: task/function declaration not allowed here.");
|
||||
}
|
||||
| modport_ports_list ',' IDENTIFIER
|
||||
{ if (last_modport_port.type == MP_SIMPLE) {
|
||||
pform_add_modport_port(@3, last_modport_port.direction,
|
||||
lex_strings.make($3), 0);
|
||||
} else if (last_modport_port.type != MP_TF) {
|
||||
yyerror(@3, "error: list of identifiers not allowed here.");
|
||||
}
|
||||
delete[] $3;
|
||||
}
|
||||
| modport_ports_list ','
|
||||
{ yyerror(@2, "error: NULL port declarations are not allowed"); }
|
||||
;
|
||||
|
||||
modport_ports_declaration
|
||||
: attribute_list_opt port_direction IDENTIFIER
|
||||
{ last_modport_port.type = MP_SIMPLE;
|
||||
last_modport_port.direction = $2;
|
||||
pform_add_modport_port(@3, $2, lex_strings.make($3), 0);
|
||||
delete[] $3;
|
||||
delete $1;
|
||||
}
|
||||
| attribute_list_opt port_direction modport_simple_port
|
||||
{ last_modport_port.type = MP_SIMPLE;
|
||||
last_modport_port.direction = $2;
|
||||
pform_add_modport_port(@3, $2, $3->name, $3->parm);
|
||||
delete $3;
|
||||
delete $1;
|
||||
}
|
||||
| attribute_list_opt import_export IDENTIFIER
|
||||
{ last_modport_port.type = MP_TF;
|
||||
last_modport_port.is_import = $2;
|
||||
yyerror(@3, "sorry: modport task/function ports are not yet supported.");
|
||||
delete[] $3;
|
||||
delete $1;
|
||||
}
|
||||
| attribute_list_opt import_export modport_tf_port
|
||||
{ last_modport_port.type = MP_TF;
|
||||
last_modport_port.is_import = $2;
|
||||
yyerror(@3, "sorry: modport task/function ports are not yet supported.");
|
||||
delete $1;
|
||||
}
|
||||
| attribute_list_opt K_clocking IDENTIFIER
|
||||
{ last_modport_port.type = MP_CLOCKING;
|
||||
last_modport_port.direction = NetNet::NOT_A_PORT;
|
||||
yyerror(@3, "sorry: modport clocking declaration is not yet supported.");
|
||||
delete[] $3;
|
||||
delete $1;
|
||||
}
|
||||
;
|
||||
|
||||
modport_simple_port
|
||||
: '.' IDENTIFIER '(' expression ')'
|
||||
{ named_pexpr_t*tmp = new named_pexpr_t;
|
||||
tmp->name = lex_strings.make($2);
|
||||
tmp->parm = $4;
|
||||
delete[]$2;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
modport_tf_port
|
||||
: K_task IDENTIFIER
|
||||
| K_task IDENTIFIER '(' tf_port_list_opt ')'
|
||||
| K_function data_type_or_implicit_or_void IDENTIFIER
|
||||
| K_function data_type_or_implicit_or_void IDENTIFIER '(' tf_port_list_opt ')'
|
||||
;
|
||||
|
||||
non_integer_type /* IEEE1800-2005: A.2.2.1 */
|
||||
: K_real { $$ = real_type_t::REAL; }
|
||||
|
|
@ -4684,6 +4809,8 @@ module_item
|
|||
pform_endgenerate();
|
||||
}
|
||||
|
||||
| modport_declaration
|
||||
|
||||
| package_import_declaration
|
||||
|
||||
/* 1364-2001 and later allow specparam declarations outside specify blocks. */
|
||||
|
|
@ -6608,7 +6735,7 @@ udp_primitive
|
|||
presence is significant. This is a fairly common pattern so
|
||||
collect those rules here. */
|
||||
|
||||
K_automatic_opt: K_automatic { $$ = true; } | { $$ = false;} ;
|
||||
K_automatic_opt: K_automatic { $$ = true; } | { $$ = false; } ;
|
||||
K_packed_opt : K_packed { $$ = true; } | { $$ = false; } ;
|
||||
K_reg_opt : K_reg { $$ = true; } | { $$ = false; } ;
|
||||
K_static_opt : K_static { $$ = true; } | { $$ = false; } ;
|
||||
|
|
|
|||
47
pform.cc
47
pform.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
# include "PPackage.h"
|
||||
# include "PUdp.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PModport.h"
|
||||
# include "PSpec.h"
|
||||
# include "discipline.h"
|
||||
# include <list>
|
||||
|
|
@ -265,6 +266,10 @@ static unsigned scope_generate_counter = 1;
|
|||
always within a module. */
|
||||
static PGenerate*pform_cur_generate = 0;
|
||||
|
||||
/* This tracks the current modport list being processed. This is
|
||||
always within an interface. */
|
||||
static PModport*pform_cur_modport = 0;
|
||||
|
||||
static NetNet::Type pform_default_nettype = NetNet::WIRE;
|
||||
|
||||
/*
|
||||
|
|
@ -3356,6 +3361,46 @@ PProcess* pform_make_behavior(ivl_process_type_t type, Statement*st,
|
|||
return pp;
|
||||
}
|
||||
|
||||
void pform_start_modport_item(const struct vlltype&loc, const char*name)
|
||||
{
|
||||
Module*scope = pform_cur_module.front();
|
||||
ivl_assert(loc, scope && scope->is_interface);
|
||||
ivl_assert(loc, pform_cur_modport == 0);
|
||||
|
||||
perm_string use_name = lex_strings.make(name);
|
||||
pform_cur_modport = new PModport(use_name);
|
||||
FILE_NAME(pform_cur_modport, loc);
|
||||
if (scope->modports.find(use_name) != scope->modports.end()) {
|
||||
cerr << loc << ": error: duplicate declaration for modport '"
|
||||
<< name << "' in '" << scope->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
scope->modports[use_name] = pform_cur_modport;
|
||||
delete[] name;
|
||||
}
|
||||
|
||||
void pform_end_modport_item(const struct vlltype&loc)
|
||||
{
|
||||
ivl_assert(loc, pform_cur_modport);
|
||||
pform_cur_modport = 0;
|
||||
}
|
||||
|
||||
void pform_add_modport_port(const struct vlltype&loc,
|
||||
NetNet::PortType port_type,
|
||||
perm_string name, PExpr*expr)
|
||||
{
|
||||
ivl_assert(loc, pform_cur_modport);
|
||||
|
||||
if (pform_cur_modport->simple_ports.find(name)
|
||||
!= pform_cur_modport->simple_ports.end()) {
|
||||
cerr << loc << ": error: duplicate declaration of port '"
|
||||
<< name << "' in modport list '"
|
||||
<< pform_cur_modport->name() << "'." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
pform_cur_modport->simple_ports[name] = make_pair(port_type, expr);
|
||||
}
|
||||
|
||||
|
||||
FILE*vl_input = 0;
|
||||
extern void reset_lexor();
|
||||
|
|
|
|||
11
pform.h
11
pform.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_pform_H
|
||||
#define IVL_pform_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2015 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
|
||||
|
|
@ -219,6 +219,15 @@ extern void pform_package_import(const struct vlltype&loc,
|
|||
extern PExpr* pform_package_ident(const struct vlltype&loc,
|
||||
PPackage*pkg, pform_name_t*ident);
|
||||
|
||||
/*
|
||||
* Interface related functions.
|
||||
*/
|
||||
extern void pform_start_modport_item(const struct vlltype&loc, const char*name);
|
||||
extern void pform_end_modport_item(const struct vlltype&loc);
|
||||
extern void pform_add_modport_port(const struct vlltype&loc,
|
||||
NetNet::PortType port_type,
|
||||
perm_string name, PExpr*expr);
|
||||
|
||||
/*
|
||||
* This creates an identifier aware of names that may have been
|
||||
* imported from other packages.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2015 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
|
||||
|
|
@ -364,6 +364,7 @@ void dll_target::expr_last(const NetELast*net)
|
|||
esig->value_ = IVL_VT_DARRAY;
|
||||
esig->net_type= sig->net_type;
|
||||
esig->width_ = 1;
|
||||
esig->signed_ = sig->net_type->get_signed()? 1 : 0;
|
||||
FILE_NAME(esig, net);
|
||||
esig->u_.signal_.word = 0;
|
||||
esig->u_.signal_.sig = sig;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2015 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
|
||||
|
|
@ -372,6 +372,8 @@ static void open_dumpfile(vpiHandle callh)
|
|||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||
vpi_control(vpiFinish, 1);
|
||||
free(dump_path);
|
||||
dump_path = 0;
|
||||
return;
|
||||
} else {
|
||||
int prec = vpi_get(vpiTimePrecision, 0);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2015 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
|
||||
|
|
@ -450,6 +450,8 @@ static void open_dumpfile(vpiHandle callh)
|
|||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||
vpi_control(vpiFinish, 1);
|
||||
free(dump_path);
|
||||
dump_path = 0;
|
||||
return;
|
||||
} else {
|
||||
int prec = vpi_get(vpiTimePrecision, 0);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2015 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
|
||||
|
|
@ -503,6 +503,8 @@ static void open_dumpfile(vpiHandle callh)
|
|||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||
vpi_control(vpiFinish, 1);
|
||||
free(dump_path);
|
||||
dump_path = 0;
|
||||
return;
|
||||
} else {
|
||||
int prec = vpi_get(vpiTimePrecision, 0);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2015 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
|
||||
|
|
@ -410,6 +410,8 @@ static void open_dumpfile(vpiHandle callh)
|
|||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||
vpi_control(vpiFinish, 1);
|
||||
free(dump_path);
|
||||
dump_path = 0;
|
||||
return;
|
||||
} else {
|
||||
int prec = vpi_get(vpiTimePrecision, 0);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2015 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
|
||||
|
|
@ -344,6 +344,7 @@ vpiHandle vpip_make_queue_var(const char*name, vvp_net_t*net)
|
|||
void darray_delete(vpiHandle item)
|
||||
{
|
||||
class __vpiDarrayVar*obj = dynamic_cast<__vpiDarrayVar*>(item);
|
||||
if (obj->vals_words) delete [] (obj->vals_words-1);
|
||||
delete obj;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2015 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
|
||||
|
|
@ -1270,6 +1270,7 @@ static vpiHandle find_name(const char *name, vpiHandle handle)
|
|||
nm = vpi_get_str(vpiName, word_h);
|
||||
if (!strcmp(name, nm)) {
|
||||
rtn = word_h;
|
||||
vpi_free_object(word_i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2015 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
|
||||
|
|
@ -51,12 +51,16 @@ void vpip_make_root_iterator(__vpiHandle**&table, unsigned&ntable)
|
|||
#ifdef CHECK_WITH_VALGRIND
|
||||
void port_delete(__vpiHandle*handle);
|
||||
|
||||
/* Class definitions need to be cleaned up at the end. */
|
||||
static class_type **class_list = 0;
|
||||
static unsigned class_list_count = 0;
|
||||
|
||||
static void delete_sub_scopes(struct __vpiScope *scope)
|
||||
{
|
||||
for (unsigned idx = 0; idx < scope->nintern; idx += 1) {
|
||||
struct __vpiScope*lscope = static_cast<__vpiScope*>
|
||||
((scope->intern)[idx]);
|
||||
switch(scope->intern[idx]->get_type_code()) {
|
||||
vpiHandle item = (scope->intern)[idx];
|
||||
struct __vpiScope*lscope = static_cast<__vpiScope*>(item);
|
||||
switch(item->get_type_code()) {
|
||||
case vpiFunction:
|
||||
case vpiTask:
|
||||
contexts_delete(lscope);
|
||||
|
|
@ -66,18 +70,18 @@ static void delete_sub_scopes(struct __vpiScope *scope)
|
|||
case vpiNamedFork:
|
||||
delete_sub_scopes(lscope);
|
||||
vthreads_delete(lscope);
|
||||
delete (scope->intern)[idx];
|
||||
delete item;
|
||||
break;
|
||||
case vpiMemory:
|
||||
case vpiNetArray:
|
||||
memory_delete((scope->intern)[idx]);
|
||||
memory_delete(item);
|
||||
break;
|
||||
case vpiModPath:
|
||||
/* The destination ModPath is cleaned up later. */
|
||||
delete (scope->intern)[idx];
|
||||
delete item;
|
||||
break;
|
||||
case vpiNamedEvent:
|
||||
named_event_delete((scope->intern)[idx]);
|
||||
named_event_delete(item);
|
||||
break;
|
||||
case vpiNet:
|
||||
case vpiReg:
|
||||
|
|
@ -87,43 +91,58 @@ static void delete_sub_scopes(struct __vpiScope *scope)
|
|||
case vpiIntVar:
|
||||
case vpiByteVar:
|
||||
case vpiBitVar:
|
||||
signal_delete((scope->intern)[idx]);
|
||||
signal_delete(item);
|
||||
break;
|
||||
case vpiParameter:
|
||||
parameter_delete((scope->intern)[idx]);
|
||||
parameter_delete(item);
|
||||
break;
|
||||
case vpiRealVar:
|
||||
real_delete((scope->intern)[idx]);
|
||||
real_delete(item);
|
||||
break;
|
||||
case vpiEnumTypespec:
|
||||
enum_delete((scope->intern)[idx]);
|
||||
enum_delete(item);
|
||||
break;
|
||||
case vpiPort:
|
||||
port_delete((scope->intern)[idx]);
|
||||
port_delete(item);
|
||||
break;
|
||||
case vpiStringVar:
|
||||
string_delete((scope->intern)[idx]);
|
||||
string_delete(item);
|
||||
break;
|
||||
case vpiClassVar:
|
||||
class_delete((scope->intern)[idx]);
|
||||
class_delete(item);
|
||||
break;
|
||||
case vpiRegArray:
|
||||
darray_delete((scope->intern)[idx]);
|
||||
case vpiArrayVar:
|
||||
switch(item->vpi_get(vpiArrayType)) {
|
||||
case vpiQueueArray:
|
||||
queue_delete(item);
|
||||
break;
|
||||
case vpiDynamicArray:
|
||||
darray_delete(item);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Need support for array type: %d\n",
|
||||
item->vpi_get(vpiArrayType));
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Need support for type: %d\n",
|
||||
scope->intern[idx]->get_type_code());
|
||||
item->get_type_code());
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(scope->intern);
|
||||
|
||||
/* Clean up any class definitions. */
|
||||
/* Save any class definitions to clean up later. */
|
||||
map<std::string, class_type*>::iterator citer;
|
||||
for (citer = scope->classes.begin();
|
||||
citer != scope->classes.end(); ++ citer ) {
|
||||
class_def_delete(citer->second);
|
||||
class_list_count += 1;
|
||||
class_list = (class_type **) realloc(class_list,
|
||||
class_list_count*sizeof(class_type **));
|
||||
class_list[class_list_count-1] = citer->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,6 +158,14 @@ void root_table_delete(void)
|
|||
free(vpip_root_table_ptr);
|
||||
vpip_root_table_ptr = 0;
|
||||
vpip_root_table_cnt = 0;
|
||||
|
||||
/* Clean up all the class definitions. */
|
||||
for (unsigned idx = 0; idx < class_list_count; idx += 1) {
|
||||
class_def_delete(class_list[idx]);
|
||||
}
|
||||
free(class_list);
|
||||
class_list = 0;
|
||||
class_list_count = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -433,8 +433,7 @@ void __vpiVThrVec4Stack::vpi_get_value_hexstr_(p_vpi_value vp, const vvp_vector4
|
|||
void __vpiVThrVec4Stack::vpi_get_value_int_(p_vpi_value vp, const vvp_vector4_t&val)
|
||||
{
|
||||
int32_t vali = 0;
|
||||
int signed_flag = 0;
|
||||
vector4_to_value(val, vali, signed_flag, false);
|
||||
vector4_to_value(val, vali, signed_flag_, false);
|
||||
vp->value.integer = vali;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue