Merge branch 'master' into cross_compile
This commit is contained in:
commit
c3575d379b
22
BUGS.txt
22
BUGS.txt
|
|
@ -116,13 +116,17 @@ programs.
|
|||
|
||||
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
|
||||
|
||||
The URL <http://sourceforge.net/tracker/?group_id=149850> is the main
|
||||
bug tracking system. Once you believe you have found a bug, you may
|
||||
browse the bugs database for existing bugs that may be related to
|
||||
yours. You might find that your bug has already been fixed in a later
|
||||
release or snapshot. If that's the case, then you are set. Also,
|
||||
consider if you are reporting a bug or really asking for a new
|
||||
feature, and use the appropriate tracker.
|
||||
The URL <https://sourceforge.net/p/iverilog/bugs/> is the main
|
||||
bug tracking system, although some users have reported bugs at
|
||||
<https://github.com/steveicarus/iverilog/issues/>. Once you believe
|
||||
you have found a bug, you may browse the bugs database for existing
|
||||
bugs that may be related to yours. You might find that your bug has
|
||||
already been fixed in a later release or snapshot. If that's the case,
|
||||
then you are set. Also, consider if you are reporting a bug or really
|
||||
asking for a new feature, and use the appropriate tracker.
|
||||
|
||||
system (although you will also find bug rep
|
||||
|
||||
|
||||
The bug database supports basic keyword searches, and you can
|
||||
optionally limit your search to active bugs, or fixed bugs. You may
|
||||
|
|
@ -145,7 +149,7 @@ version from git. Please see the developer documentation for more
|
|||
detailed instructions -- <http://iverilog.wikia.com/wiki/>.
|
||||
|
||||
When you make a patch, submit it to the "Patches" tracker at
|
||||
<http://sourceforge.net/tracker/?group_id=149850>. Patches added to
|
||||
<https://sourceforge.net/p/iverilog/patches/>. Patches added to
|
||||
the "Patches" tracker enter the developer workflow, are checked,
|
||||
applied to the appropriate git branch, and are pushed. Then the
|
||||
tracker item is closed.
|
||||
|
|
@ -158,7 +162,7 @@ clarification before applying it.)
|
|||
|
||||
COPYRIGHT ISSUES
|
||||
|
||||
Icarus Verilog is Copyright (c) 1998-2008 Stephen Williams except
|
||||
Icarus Verilog is Copyright (c) 1998-2018 Stephen Williams except
|
||||
where otherwise noted. Minor patches are covered as derivative works
|
||||
(or editorial comment or whatever the appropriate legal term is) and
|
||||
folded into the rest of ivl. However, if a submission can reasonably
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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,7 +35,6 @@ Module::Module(LexicalScope*parent, perm_string n)
|
|||
is_interface = false;
|
||||
program_block = false;
|
||||
uc_drive = UCD_NONE;
|
||||
timescale_warn_done = false;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
|
|
|
|||
4
Module.h
4
Module.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_Module_H
|
||||
#define IVL_Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -121,8 +121,6 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
bool timescale_warn_done;
|
||||
|
||||
/* The module has a list of generate schemes that appear in
|
||||
the module definition. These are used at elaboration time. */
|
||||
list<PGenerate*> generate_schemes;
|
||||
|
|
|
|||
21
PDelays.cc
21
PDelays.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -26,11 +26,6 @@
|
|||
# include "verinum.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
bool dly_used_no_timescale = false;
|
||||
bool dly_used_timescale = false;
|
||||
bool display_ts_dly_warning = true;
|
||||
|
||||
|
||||
PDelays::PDelays()
|
||||
{
|
||||
delete_flag_ = true;
|
||||
|
|
@ -80,19 +75,7 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
|
|||
{
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
check_for_inconsistent_delays(scope);
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
|
|
|
|||
2
PGate.h
2
PGate.h
|
|
@ -217,6 +217,8 @@ class PGModule : public PGate {
|
|||
// method to pass the range to the pform.
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008,2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2017 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
|
||||
|
|
@ -38,7 +38,8 @@ PScope::PScope(perm_string n, LexicalScope*parent)
|
|||
{
|
||||
time_unit = 0;
|
||||
time_precision = 0;
|
||||
time_from_timescale = false;
|
||||
time_unit_is_default = true;
|
||||
time_prec_is_default = true;
|
||||
}
|
||||
|
||||
PScope::~PScope()
|
||||
|
|
@ -51,6 +52,8 @@ PScope::~PScope()
|
|||
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
|
||||
: PScope(n, parent)
|
||||
{
|
||||
time_unit_is_local = false;
|
||||
time_prec_is_local = false;
|
||||
}
|
||||
|
||||
PScopeExtra::~PScopeExtra()
|
||||
|
|
|
|||
17
PScope.h
17
PScope.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_PScope_H
|
||||
#define IVL_PScope_H
|
||||
/*
|
||||
* Copyright (c) 2008-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2017 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
|
||||
|
|
@ -164,11 +164,18 @@ class PScope : public LexicalScope {
|
|||
|
||||
perm_string pscope_name() const { return name_; }
|
||||
|
||||
/* These are the timescale for this scope. The default is
|
||||
/* These are the timescale for this scope. The value is
|
||||
set by the `timescale directive or, in SystemVerilog,
|
||||
by timeunit and timeprecision statements. */
|
||||
int time_unit, time_precision;
|
||||
bool time_from_timescale;
|
||||
|
||||
/* Flags used to support warnings about timescales. */
|
||||
bool time_unit_is_default;
|
||||
bool time_prec_is_default;
|
||||
|
||||
bool has_explicit_timescale() const {
|
||||
return !(time_unit_is_default || time_prec_is_default);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
|
||||
|
|
@ -199,6 +206,10 @@ class PScopeExtra : public PScope {
|
|||
elaboration to choose an elaboration order. */
|
||||
std::vector<PClass*> classes_lexical;
|
||||
|
||||
/* Flags used to support warnings about timescales. */
|
||||
bool time_unit_is_local;
|
||||
bool time_prec_is_local;
|
||||
|
||||
protected:
|
||||
void dump_classes_(ostream&out, unsigned indent) const;
|
||||
void dump_tasks_(ostream&out, unsigned indent) const;
|
||||
|
|
|
|||
14
README.txt
14
README.txt
|
|
@ -1,5 +1,5 @@
|
|||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
Copyright 2000-2004 Stephen Williams
|
||||
Copyright 2000-2019 Stephen Williams
|
||||
|
||||
|
||||
1.0 What is ICARUS Verilog?
|
||||
|
|
@ -47,7 +47,7 @@ on a UNIX-like system:
|
|||
|
||||
- bison and flex
|
||||
|
||||
- gperf 2.7
|
||||
- gperf 2.7 or later
|
||||
The lexical analyzer doesn't recognize keywords directly,
|
||||
but instead matches symbols and looks them up in a hash
|
||||
table in order to get the proper lexical code. The gperf
|
||||
|
|
@ -56,7 +56,7 @@ on a UNIX-like system:
|
|||
A version problem with this program is the most common cause
|
||||
of difficulty. See the Icarus Verilog FAQ.
|
||||
|
||||
- readline 4.2
|
||||
- readline 4.2 or later
|
||||
On Linux systems, this usually means the readline-devel
|
||||
rpm. In any case, it is the development headers of readline
|
||||
that are needed.
|
||||
|
|
@ -67,7 +67,7 @@ on a UNIX-like system:
|
|||
If you are building from git, you will also need software to generate
|
||||
the configure scripts.
|
||||
|
||||
- autoconf 2.53
|
||||
- autoconf 2.53 or later
|
||||
This generates configure scripts from configure.in. The 2.53
|
||||
or later versions are known to work, autoconf 2.13 is
|
||||
reported to *not* work.
|
||||
|
|
@ -81,6 +81,12 @@ with the commands:
|
|||
./configure
|
||||
make
|
||||
|
||||
If you are building from git, you have to run the command below before
|
||||
compile the source. This will generate the "configure" file, which is
|
||||
automatically done when building from tarball.
|
||||
|
||||
sh autoconf.sh
|
||||
|
||||
Normally, this command automatically figures out everything it needs
|
||||
to know. It generally works pretty well. There are a few flags to the
|
||||
configure script that modify its behavior:
|
||||
|
|
|
|||
10
Statement.cc
10
Statement.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -294,20 +294,20 @@ PDoWhile::~PDoWhile()
|
|||
}
|
||||
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
: expr_(ee), statement_(0), search_funcs_(false)
|
||||
{
|
||||
assert(expr_.count() > 0);
|
||||
}
|
||||
|
||||
|
||||
PEventStatement::PEventStatement(PEEvent*ee)
|
||||
: expr_(1), statement_(0)
|
||||
: expr_(1), statement_(0), search_funcs_(false)
|
||||
{
|
||||
expr_[0] = ee;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(void)
|
||||
: statement_(0)
|
||||
PEventStatement::PEventStatement(bool search_funcs)
|
||||
: statement_(0), search_funcs_(search_funcs)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_Statement_H
|
||||
#define IVL_Statement_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -402,8 +402,9 @@ class PEventStatement : public Statement {
|
|||
|
||||
explicit PEventStatement(const svector<PEEvent*>&ee);
|
||||
explicit PEventStatement(PEEvent*ee);
|
||||
// Make an @* statement.
|
||||
explicit PEventStatement(void);
|
||||
// Make an @* statement or make a special @* version with the items
|
||||
// from functions added and ouputs removed for always_comb/latch.
|
||||
explicit PEventStatement(bool search_funcs = false);
|
||||
|
||||
~PEventStatement();
|
||||
|
||||
|
|
@ -429,6 +430,7 @@ class PEventStatement : public Statement {
|
|||
private:
|
||||
svector<PEEvent*>expr_;
|
||||
Statement*statement_;
|
||||
bool search_funcs_;
|
||||
};
|
||||
|
||||
ostream& operator << (ostream&o, const PEventStatement&obj);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_compiler_H
|
||||
#define IVL_compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -117,6 +117,13 @@ extern bool debug_emit;
|
|||
extern bool debug_synth2;
|
||||
extern bool debug_optimizer;
|
||||
|
||||
/* Ignore errors about missing modules */
|
||||
extern bool ignore_missing_modules;
|
||||
|
||||
/* Treat each source file as a separate compilation unit (as defined
|
||||
by SystemVerilog). */
|
||||
extern bool separate_compilation;
|
||||
|
||||
/* Control evaluation of functions at compile time:
|
||||
* 0 = only for functions in constant expressions
|
||||
* 1 = only for automatic functions
|
||||
|
|
|
|||
750
cppcheck.sup
750
cppcheck.sup
|
|
@ -1,613 +1,619 @@
|
|||
// These are correct and are used to find the base (zero) pin.
|
||||
thisSubtraction:netlist.h:5081
|
||||
thisSubtraction:netlist.h:5090
|
||||
thisSubtraction:netlist.h:5082
|
||||
thisSubtraction:netlist.h:5091
|
||||
|
||||
// These are the functions that the compiler exports to the targets.
|
||||
//ivl_branch_island()
|
||||
unusedFunction:t-dll-api.cc:38
|
||||
unusedFunction:t-dll-api.cc:39
|
||||
//ivl_branch_terminal()
|
||||
unusedFunction:t-dll-api.cc:43
|
||||
unusedFunction:t-dll-api.cc:45
|
||||
|
||||
//ivl_const_bits()
|
||||
unusedFunction:t-dll-api.cc:180
|
||||
unusedFunction:t-dll-api.cc:196
|
||||
//ivl_const_delay()
|
||||
unusedFunction:t-dll-api.cc:198
|
||||
unusedFunction:t-dll-api.cc:214
|
||||
//ivl_const_file()
|
||||
unusedFunction:t-dll-api.cc:204
|
||||
unusedFunction:t-dll-api.cc:221
|
||||
//ivl_const_lineno()
|
||||
unusedFunction:t-dll-api.cc:210
|
||||
unusedFunction:t-dll-api.cc:227
|
||||
//ivl_const_nex()
|
||||
unusedFunction:t-dll-api.cc:216
|
||||
unusedFunction:t-dll-api.cc:233
|
||||
//ivl_const_real()
|
||||
unusedFunction:t-dll-api.cc:222
|
||||
unusedFunction:t-dll-api.cc:239
|
||||
//ivl_const_scope()
|
||||
unusedFunction:t-dll-api.cc:229
|
||||
unusedFunction:t-dll-api.cc:246
|
||||
//ivl_const_signed()
|
||||
unusedFunction:t-dll-api.cc:235
|
||||
unusedFunction:t-dll-api.cc:252
|
||||
//ivl_const_type()
|
||||
unusedFunction:t-dll-api.cc:174
|
||||
unusedFunction:t-dll-api.cc:190
|
||||
//ivl_const_width()
|
||||
unusedFunction:t-dll-api.cc:241
|
||||
unusedFunction:t-dll-api.cc:258
|
||||
|
||||
//ivl_design_const()
|
||||
unusedFunction:t-dll-api.cc:116
|
||||
unusedFunction:t-dll-api.cc:127
|
||||
//ivl_design_consts()
|
||||
unusedFunction:t-dll-api.cc:111
|
||||
unusedFunction:t-dll-api.cc:121
|
||||
//ivl_design_delay_sel()
|
||||
unusedFunction:t-dll-api.cc:49
|
||||
unusedFunction:t-dll-api.cc:52
|
||||
//ivl_design_discipline()
|
||||
unusedFunction:t-dll-api.cc:128
|
||||
unusedFunction:t-dll-api.cc:140
|
||||
//ivl_design_disciplines()
|
||||
unusedFunction:t-dll-api.cc:122
|
||||
unusedFunction:t-dll-api.cc:134
|
||||
//ivl_design_flag()
|
||||
unusedFunction:t-dll-api.cc:54
|
||||
//ivl_design_process()
|
||||
unusedFunction:t-dll-api.cc:59
|
||||
//ivl_design_process()
|
||||
unusedFunction:t-dll-api.cc:66
|
||||
//ivl_design_root()
|
||||
unusedFunction:t-dll-api.cc:72
|
||||
unusedFunction:t-dll-api.cc:80
|
||||
//ivl_design_roots()
|
||||
unusedFunction:t-dll-api.cc:81
|
||||
unusedFunction:t-dll-api.cc:89
|
||||
//ivl_design_time_precision()
|
||||
unusedFunction:t-dll-api.cc:106
|
||||
unusedFunction:t-dll-api.cc:115
|
||||
|
||||
//ivl_discipline_domain()
|
||||
unusedFunction:t-dll-api.cc:135
|
||||
unusedFunction:t-dll-api.cc:147
|
||||
//ivl_discipline_flow()
|
||||
unusedFunction:t-dll-api.cc:140
|
||||
unusedFunction:t-dll-api.cc:153
|
||||
//ivl_discipline_name()
|
||||
unusedFunction:t-dll-api.cc:145
|
||||
unusedFunction:t-dll-api.cc:159
|
||||
//ivl_discipline_potential()
|
||||
unusedFunction:t-dll-api.cc:150
|
||||
unusedFunction:t-dll-api.cc:165
|
||||
|
||||
//ivl_enum_bits()
|
||||
unusedFunction:t-dll-api.cc:260
|
||||
unusedFunction:t-dll-api.cc:277
|
||||
//ivl_enum_file()
|
||||
unusedFunction:t-dll-api.cc:285
|
||||
unusedFunction:t-dll-api.cc:302
|
||||
//ivl_enum_lineno()
|
||||
unusedFunction:t-dll-api.cc:291
|
||||
unusedFunction:t-dll-api.cc:308
|
||||
//ivl_enum_name()
|
||||
unusedFunction:t-dll-api.cc:253
|
||||
unusedFunction:t-dll-api.cc:270
|
||||
//ivl_enum_names()
|
||||
unusedFunction:t-dll-api.cc:247
|
||||
unusedFunction:t-dll-api.cc:264
|
||||
//ivl_enum_signed()
|
||||
unusedFunction:t-dll-api.cc:279
|
||||
unusedFunction:t-dll-api.cc:296
|
||||
//ivl_enum_type()
|
||||
unusedFunction:t-dll-api.cc:267
|
||||
unusedFunction:t-dll-api.cc:284
|
||||
//ivl_enum_width()
|
||||
unusedFunction:t-dll-api.cc:273
|
||||
unusedFunction:t-dll-api.cc:290
|
||||
|
||||
//ivl_event_any()
|
||||
unusedFunction:t-dll-api.cc:349
|
||||
//ivl_event_file()
|
||||
unusedFunction:t-dll-api.cc:326
|
||||
//ivl_event_lineno()
|
||||
unusedFunction:t-dll-api.cc:332
|
||||
//ivl_event_name()
|
||||
unusedFunction:t-dll-api.cc:297
|
||||
//ivl_event_nany()
|
||||
unusedFunction:t-dll-api.cc:343
|
||||
//ivl_event_neg()
|
||||
unusedFunction:t-dll-api.cc:362
|
||||
//ivl_event_nneg()
|
||||
unusedFunction:t-dll-api.cc:356
|
||||
//ivl_event_npos()
|
||||
unusedFunction:t-dll-api.cc:369
|
||||
//ivl_event_file()
|
||||
unusedFunction:t-dll-api.cc:345
|
||||
//ivl_event_lineno()
|
||||
unusedFunction:t-dll-api.cc:351
|
||||
//ivl_event_name()
|
||||
unusedFunction:t-dll-api.cc:314
|
||||
//ivl_event_nany()
|
||||
unusedFunction:t-dll-api.cc:363
|
||||
//ivl_event_neg()
|
||||
unusedFunction:t-dll-api.cc:382
|
||||
//ivl_event_nneg()
|
||||
unusedFunction:t-dll-api.cc:376
|
||||
//ivl_event_npos()
|
||||
unusedFunction:t-dll-api.cc:389
|
||||
//ivl_event_pos()
|
||||
unusedFunction:t-dll-api.cc:375
|
||||
unusedFunction:t-dll-api.cc:395
|
||||
//ivl_event_scope()
|
||||
unusedFunction:t-dll-api.cc:338
|
||||
unusedFunction:t-dll-api.cc:357
|
||||
|
||||
//ivl_expr_bits()
|
||||
unusedFunction:t-dll-api.cc:382
|
||||
unusedFunction:t-dll-api.cc:402
|
||||
//ivl_expr_branch()
|
||||
unusedFunction:t-dll-api.cc:388
|
||||
unusedFunction:t-dll-api.cc:409
|
||||
//ivl_expr_def()
|
||||
unusedFunction:t-dll-api.cc:394
|
||||
//ivl_expr_delay_val()
|
||||
unusedFunction:t-dll-api.cc:410
|
||||
//ivl_expr_dvalue()
|
||||
unusedFunction:t-dll-api.cc:416
|
||||
//ivl_expr_delay_val()
|
||||
unusedFunction:t-dll-api.cc:432
|
||||
//ivl_expr_dvalue()
|
||||
unusedFunction:t-dll-api.cc:439
|
||||
//ivl_expr_enumtype()
|
||||
unusedFunction:t-dll-api.cc:422
|
||||
unusedFunction:t-dll-api.cc:446
|
||||
//ivl_expr_event()
|
||||
unusedFunction:t-dll-api.cc:628
|
||||
unusedFunction:t-dll-api.cc:656
|
||||
//ivl_expr_file()
|
||||
unusedFunction:t-dll-api.cc:162
|
||||
unusedFunction:t-dll-api.cc:178
|
||||
//ivl_expr_lineno()
|
||||
unusedFunction:t-dll-api.cc:168
|
||||
unusedFunction:t-dll-api.cc:184
|
||||
//ivl_expr_name()
|
||||
unusedFunction:t-dll-api.cc:433
|
||||
unusedFunction:t-dll-api.cc:459
|
||||
//ivl_expr_nature()
|
||||
unusedFunction:t-dll-api.cc:456
|
||||
unusedFunction:t-dll-api.cc:483
|
||||
//ivl_expr_net_type()
|
||||
unusedFunction:t-dll-api.cc:428
|
||||
unusedFunction:t-dll-api.cc:453
|
||||
//ivl_expr_opcode()
|
||||
unusedFunction:t-dll-api.cc:462
|
||||
unusedFunction:t-dll-api.cc:490
|
||||
//ivl_expr_oper1()
|
||||
unusedFunction:t-dll-api.cc:478
|
||||
unusedFunction:t-dll-api.cc:506
|
||||
//ivl_expr_oper2()
|
||||
unusedFunction:t-dll-api.cc:516
|
||||
unusedFunction:t-dll-api.cc:544
|
||||
//ivl_expr_oper3()
|
||||
unusedFunction:t-dll-api.cc:542
|
||||
unusedFunction:t-dll-api.cc:570
|
||||
//ivl_expr_parameter()
|
||||
unusedFunction:t-dll-api.cc:556
|
||||
unusedFunction:t-dll-api.cc:584
|
||||
//ivl_expr_parm()
|
||||
unusedFunction:t-dll-api.cc:571
|
||||
unusedFunction:t-dll-api.cc:599
|
||||
//ivl_expr_parms()
|
||||
unusedFunction:t-dll-api.cc:598
|
||||
unusedFunction:t-dll-api.cc:626
|
||||
//ivl_expr_repeat()
|
||||
unusedFunction:t-dll-api.cc:621
|
||||
//ivl_expr_scope()
|
||||
unusedFunction:t-dll-api.cc:642
|
||||
//ivl_expr_sel_type()
|
||||
unusedFunction:t-dll-api.cc:649
|
||||
//ivl_expr_scope()
|
||||
unusedFunction:t-dll-api.cc:670
|
||||
//ivl_expr_sel_type()
|
||||
unusedFunction:t-dll-api.cc:677
|
||||
//ivl_expr_signed()
|
||||
unusedFunction:t-dll-api.cc:674
|
||||
unusedFunction:t-dll-api.cc:702
|
||||
//ivl_expr_sized()
|
||||
unusedFunction:t-dll-api.cc:680
|
||||
unusedFunction:t-dll-api.cc:708
|
||||
//ivl_expr_string()
|
||||
unusedFunction:t-dll-api.cc:686
|
||||
unusedFunction:t-dll-api.cc:714
|
||||
//ivl_expr_type()
|
||||
unusedFunction:t-dll-api.cc:155
|
||||
unusedFunction:t-dll-api.cc:171
|
||||
//ivl_expr_uvalue()
|
||||
unusedFunction:t-dll-api.cc:692
|
||||
unusedFunction:t-dll-api.cc:721
|
||||
//ivl_expr_value()
|
||||
unusedFunction:t-dll-api.cc:717
|
||||
unusedFunction:t-dll-api.cc:747
|
||||
//ivl_expr_width()
|
||||
unusedFunction:t-dll-api.cc:753
|
||||
|
||||
unusedFunction:t-dll-api.cc:723
|
||||
//ivl_file_table_index()
|
||||
unusedFunction:t-dll-api.cc:765
|
||||
unusedFunction:t-dll-api.cc:795
|
||||
//ivl_file_table_item()
|
||||
unusedFunction:t-dll-api.cc:755
|
||||
unusedFunction:t-dll-api.cc:785
|
||||
//ivl_file_table_size()
|
||||
unusedFunction:t-dll-api.cc:783
|
||||
unusedFunction:t-dll-api.cc:813
|
||||
|
||||
//ivl_island_flag_set()
|
||||
unusedFunction:t-dll-api.cc:792
|
||||
unusedFunction:t-dll-api.cc:822
|
||||
//ivl_island_flag_test()
|
||||
unusedFunction:t-dll-api.cc:806
|
||||
unusedFunction:t-dll-api.cc:837
|
||||
|
||||
//ivl_logic_attr()
|
||||
unusedFunction:t-dll-api.cc:832
|
||||
unusedFunction:t-dll-api.cc:864
|
||||
//ivl_logic_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:848
|
||||
unusedFunction:t-dll-api.cc:880
|
||||
//ivl_logic_attr_val()
|
||||
unusedFunction:t-dll-api.cc:853
|
||||
unusedFunction:t-dll-api.cc:886
|
||||
//ivl_logic_basename()
|
||||
unusedFunction:t-dll-api.cc:901
|
||||
unusedFunction:t-dll-api.cc:935
|
||||
//ivl_logic_delay()
|
||||
unusedFunction:t-dll-api.cc:936
|
||||
unusedFunction:t-dll-api.cc:974
|
||||
//ivl_logic_drive0()
|
||||
unusedFunction:t-dll-api.cc:860
|
||||
//ivl_logic_drive1()
|
||||
unusedFunction:t-dll-api.cc:877
|
||||
//ivl_logic_file()
|
||||
unusedFunction:t-dll-api.cc:814
|
||||
//ivl_logic_is_cassign()
|
||||
unusedFunction:t-dll-api.cc:826
|
||||
//ivl_logic_lineno()
|
||||
unusedFunction:t-dll-api.cc:820
|
||||
//ivl_logic_name()
|
||||
unusedFunction:t-dll-api.cc:894
|
||||
//ivl_logic_drive1()
|
||||
unusedFunction:t-dll-api.cc:911
|
||||
//ivl_logic_file()
|
||||
unusedFunction:t-dll-api.cc:846
|
||||
//ivl_logic_is_cassign()
|
||||
unusedFunction:t-dll-api.cc:858
|
||||
//ivl_logic_lineno()
|
||||
unusedFunction:t-dll-api.cc:852
|
||||
//ivl_logic_name()
|
||||
unusedFunction:t-dll-api.cc:928
|
||||
//ivl_logic_pins()
|
||||
unusedFunction:t-dll-api.cc:918
|
||||
unusedFunction:t-dll-api.cc:953
|
||||
//ivl_logic_scope()
|
||||
unusedFunction:t-dll-api.cc:907
|
||||
unusedFunction:t-dll-api.cc:941
|
||||
//ivl_logic_type()
|
||||
unusedFunction:t-dll-api.cc:913
|
||||
unusedFunction:t-dll-api.cc:947
|
||||
//ivl_logic_udp()
|
||||
unusedFunction:t-dll-api.cc:929
|
||||
unusedFunction:t-dll-api.cc:966
|
||||
//ivl_logic_width()
|
||||
unusedFunction:t-dll-api.cc:942
|
||||
unusedFunction:t-dll-api.cc:981
|
||||
|
||||
//ivl_lpm_array()
|
||||
unusedFunction:t-dll-api.cc:1059
|
||||
unusedFunction:t-dll-api.cc:1109
|
||||
//ivl_lpm_aset_value()
|
||||
unusedFunction:t-dll-api.cc:1110
|
||||
unusedFunction:t-dll-api.cc:1160
|
||||
//ivl_lpm_async_clr()
|
||||
unusedFunction:t-dll-api.cc:1005
|
||||
unusedFunction:t-dll-api.cc:1054
|
||||
//ivl_lpm_async_set()
|
||||
unusedFunction:t-dll-api.cc:1035
|
||||
unusedFunction:t-dll-api.cc:1085
|
||||
//ivl_lpm_base()
|
||||
unusedFunction:t-dll-api.cc:1071
|
||||
//ivl_lpm_basename()
|
||||
unusedFunction:t-dll-api.cc:1000
|
||||
//ivl_lpm_clk()
|
||||
unusedFunction:t-dll-api.cc:1098
|
||||
//ivl_lpm_data()
|
||||
unusedFunction:t-dll-api.cc:1167
|
||||
//ivl_lpm_datab()
|
||||
unusedFunction:t-dll-api.cc:1264
|
||||
//ivl_lpm_define()
|
||||
unusedFunction:t-dll-api.cc:1133
|
||||
//ivl_lpm_delay()
|
||||
unusedFunction:t-dll-api.cc:1029
|
||||
//ivl_lpm_drive0()
|
||||
unusedFunction:t-dll-api.cc:1393
|
||||
//ivl_lpm_drive1()
|
||||
unusedFunction:t-dll-api.cc:1410
|
||||
//ivl_lpm_enable()
|
||||
unusedFunction:t-dll-api.cc:1145
|
||||
//ivl_lpm_file()
|
||||
unusedFunction:t-dll-api.cc:1157
|
||||
//ivl_lpm_lineno()
|
||||
unusedFunction:t-dll-api.cc:1162
|
||||
//ivl_lpm_name()
|
||||
unusedFunction:t-dll-api.cc:1298
|
||||
//ivl_lpm_negedge()
|
||||
unusedFunction:t-dll-api.cc:1086
|
||||
//ivl_lpm_select()
|
||||
unusedFunction:t-dll-api.cc:1433
|
||||
//ivl_lpm_selects()
|
||||
unusedFunction:t-dll-api.cc:1449
|
||||
//ivl_lpm_signed()
|
||||
unusedFunction:t-dll-api.cc:1466
|
||||
//ivl_lpm_size()
|
||||
unusedFunction:t-dll-api.cc:1525
|
||||
//ivl_lpm_sset_value()
|
||||
unusedFunction:t-dll-api.cc:1121
|
||||
//ivl_lpm_basename()
|
||||
unusedFunction:t-dll-api.cc:1048
|
||||
//ivl_lpm_clk()
|
||||
unusedFunction:t-dll-api.cc:1148
|
||||
//ivl_lpm_data()
|
||||
unusedFunction:t-dll-api.cc:1221
|
||||
//ivl_lpm_datab()
|
||||
unusedFunction:t-dll-api.cc:1321
|
||||
//ivl_lpm_define()
|
||||
unusedFunction:t-dll-api.cc:1183
|
||||
//ivl_lpm_delay()
|
||||
unusedFunction:t-dll-api.cc:1078
|
||||
//ivl_lpm_drive0()
|
||||
unusedFunction:t-dll-api.cc:1453
|
||||
//ivl_lpm_drive1()
|
||||
unusedFunction:t-dll-api.cc:1470
|
||||
//ivl_lpm_enable()
|
||||
unusedFunction:t-dll-api.cc:1195
|
||||
//ivl_lpm_file()
|
||||
unusedFunction:t-dll-api.cc:1209
|
||||
//ivl_lpm_lineno()
|
||||
unusedFunction:t-dll-api.cc:1215
|
||||
//ivl_lpm_name()
|
||||
unusedFunction:t-dll-api.cc:1355
|
||||
//ivl_lpm_negedge()
|
||||
unusedFunction:t-dll-api.cc:1136
|
||||
//ivl_lpm_select()
|
||||
unusedFunction:t-dll-api.cc:1493
|
||||
//ivl_lpm_selects()
|
||||
unusedFunction:t-dll-api.cc:1510
|
||||
//ivl_lpm_signed()
|
||||
unusedFunction:t-dll-api.cc:1528
|
||||
//ivl_lpm_size()
|
||||
unusedFunction:t-dll-api.cc:1587
|
||||
//ivl_lpm_sset_value()
|
||||
unusedFunction:t-dll-api.cc:1171
|
||||
//ivl_lpm_string()
|
||||
unusedFunction:t-dll-api.cc:1577
|
||||
unusedFunction:t-dll-api.cc:1640
|
||||
//ivl_lpm_sync_clr()
|
||||
unusedFunction:t-dll-api.cc:1017
|
||||
unusedFunction:t-dll-api.cc:1066
|
||||
//ivl_lpm_sync_set()
|
||||
unusedFunction:t-dll-api.cc:1047
|
||||
unusedFunction:t-dll-api.cc:1097
|
||||
//ivl_lpm_trigger()
|
||||
unusedFunction:t-dll-api.cc:1594
|
||||
unusedFunction:t-dll-api.cc:1659
|
||||
//ivl_lpm_type()
|
||||
unusedFunction:t-dll-api.cc:1583
|
||||
unusedFunction:t-dll-api.cc:1647
|
||||
//ivl_lpm_width()
|
||||
unusedFunction:t-dll-api.cc:1588
|
||||
unusedFunction:t-dll-api.cc:1653
|
||||
|
||||
//ivl_lval_idx()
|
||||
unusedFunction:t-dll-api.cc:1616
|
||||
unusedFunction:t-dll-api.cc:1681
|
||||
//ivl_lval_mux()
|
||||
unusedFunction:t-dll-api.cc:1611
|
||||
unusedFunction:t-dll-api.cc:1676
|
||||
//ivl_lval_nest()
|
||||
unusedFunction:t-dll-api.cc:1661
|
||||
unusedFunction:t-dll-api.cc:1726
|
||||
//ivl_lval_part_off()
|
||||
unusedFunction:t-dll-api.cc:1625
|
||||
unusedFunction:t-dll-api.cc:1690
|
||||
//ivl_lval_property_idx()
|
||||
unusedFunction:t-dll-api.cc:1643
|
||||
unusedFunction:t-dll-api.cc:1708
|
||||
//ivl_lval_sel_type()
|
||||
unusedFunction:t-dll-api.cc:1631
|
||||
unusedFunction:t-dll-api.cc:1696
|
||||
//ivl_lval_sig()
|
||||
unusedFunction:t-dll-api.cc:1649
|
||||
unusedFunction:t-dll-api.cc:1714
|
||||
|
||||
//ivl_nature_name()
|
||||
unusedFunction:t-dll-api.cc:1670
|
||||
unusedFunction:t-dll-api.cc:1735
|
||||
|
||||
//ivl_nexus_get_private()
|
||||
unusedFunction:t-dll-api.cc:1690
|
||||
unusedFunction:t-dll-api.cc:1756
|
||||
//ivl_nexus_name()
|
||||
unusedFunction:t-dll-api.cc:1679
|
||||
unusedFunction:t-dll-api.cc:1745
|
||||
//ivl_nexus_ptr_branch()
|
||||
unusedFunction:t-dll-api.cc:1733
|
||||
unusedFunction:t-dll-api.cc:1799
|
||||
//ivl_nexus_ptr_con()
|
||||
unusedFunction:t-dll-api.cc:1742
|
||||
unusedFunction:t-dll-api.cc:1808
|
||||
//ivl_nexus_ptr_sig()
|
||||
unusedFunction:t-dll-api.cc:1769
|
||||
unusedFunction:t-dll-api.cc:1835
|
||||
//ivl_nexus_ptr_switch()
|
||||
unusedFunction:t-dll-api.cc:1778
|
||||
unusedFunction:t-dll-api.cc:1844
|
||||
//ivl_nexus_set_private()
|
||||
unusedFunction:t-dll-api.cc:1696
|
||||
unusedFunction:t-dll-api.cc:1762
|
||||
|
||||
//ivl_parameter_basename()
|
||||
unusedFunction:t-dll-api.cc:1787
|
||||
unusedFunction:t-dll-api.cc:1853
|
||||
//ivl_parameter_expr()
|
||||
unusedFunction:t-dll-api.cc:1830
|
||||
unusedFunction:t-dll-api.cc:1896
|
||||
//ivl_parameter_file()
|
||||
unusedFunction:t-dll-api.cc:1836
|
||||
unusedFunction:t-dll-api.cc:1902
|
||||
//ivl_parameter_lineno()
|
||||
unusedFunction:t-dll-api.cc:1842
|
||||
unusedFunction:t-dll-api.cc:1908
|
||||
//ivl_parameter_local()
|
||||
unusedFunction:t-dll-api.cc:1793
|
||||
unusedFunction:t-dll-api.cc:1859
|
||||
//ivl_parameter_lsb()
|
||||
unusedFunction:t-dll-api.cc:1811
|
||||
unusedFunction:t-dll-api.cc:1877
|
||||
//ivl_parameter_msb()
|
||||
unusedFunction:t-dll-api.cc:1805
|
||||
unusedFunction:t-dll-api.cc:1871
|
||||
//ivl_parameter_scope()
|
||||
unusedFunction:t-dll-api.cc:1848
|
||||
unusedFunction:t-dll-api.cc:1914
|
||||
//ivl_parameter_signed()
|
||||
unusedFunction:t-dll-api.cc:1799
|
||||
unusedFunction:t-dll-api.cc:1865
|
||||
//ivl_parameter_width()
|
||||
unusedFunction:t-dll-api.cc:1821
|
||||
unusedFunction:t-dll-api.cc:1887
|
||||
|
||||
//ivl_path_condit()
|
||||
unusedFunction:t-dll-api.cc:1854
|
||||
unusedFunction:t-dll-api.cc:1920
|
||||
//ivl_path_delay()
|
||||
unusedFunction:t-dll-api.cc:1866
|
||||
unusedFunction:t-dll-api.cc:1932
|
||||
//ivl_path_is_condit()
|
||||
unusedFunction:t-dll-api.cc:1860
|
||||
unusedFunction:t-dll-api.cc:1926
|
||||
//ivl_path_scope()
|
||||
unusedFunction:t-dll-api.cc:1872
|
||||
unusedFunction:t-dll-api.cc:1938
|
||||
//ivl_path_source()
|
||||
unusedFunction:t-dll-api.cc:1879
|
||||
unusedFunction:t-dll-api.cc:1945
|
||||
//ivl_path_source_negedge()
|
||||
unusedFunction:t-dll-api.cc:1889
|
||||
unusedFunction:t-dll-api.cc:1957
|
||||
//ivl_path_source_posedge()
|
||||
unusedFunction:t-dll-api.cc:1884
|
||||
unusedFunction:t-dll-api.cc:1951
|
||||
|
||||
//ivl_process_analog()
|
||||
unusedFunction:t-dll-api.cc:1911
|
||||
unusedFunction:t-dll-api.cc:1981
|
||||
//ivl_process_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:1926
|
||||
unusedFunction:t-dll-api.cc:1999
|
||||
//ivl_process_attr_val()
|
||||
unusedFunction:t-dll-api.cc:1931
|
||||
unusedFunction:t-dll-api.cc:2005
|
||||
//ivl_process_file()
|
||||
unusedFunction:t-dll-api.cc:1894
|
||||
unusedFunction:t-dll-api.cc:1963
|
||||
//ivl_process_lineno()
|
||||
unusedFunction:t-dll-api.cc:1900
|
||||
unusedFunction:t-dll-api.cc:1969
|
||||
//ivl_process_scope()
|
||||
unusedFunction:t-dll-api.cc:1916
|
||||
unusedFunction:t-dll-api.cc:1987
|
||||
//ivl_process_stmt()
|
||||
unusedFunction:t-dll-api.cc:1921
|
||||
unusedFunction:t-dll-api.cc:1993
|
||||
//ivl_process_type()
|
||||
unusedFunction:t-dll-api.cc:1906
|
||||
unusedFunction:t-dll-api.cc:1975
|
||||
|
||||
//ivl_scope_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:1938
|
||||
unusedFunction:t-dll-api.cc:2013
|
||||
//ivl_scope_attr_val()
|
||||
unusedFunction:t-dll-api.cc:1944
|
||||
unusedFunction:t-dll-api.cc:2019
|
||||
//ivl_scope_basename()
|
||||
unusedFunction:t-dll-api.cc:1951
|
||||
//ivl_scope_child()
|
||||
unusedFunction:t-dll-api.cc:1978
|
||||
//ivl_scope_children()
|
||||
unusedFunction:t-dll-api.cc:1958
|
||||
//ivl_scope_childs()
|
||||
unusedFunction:t-dll-api.cc:1972
|
||||
//ivl_scope_class()
|
||||
unusedFunction:t-dll-api.cc:1984
|
||||
//ivl_scope_classes()
|
||||
unusedFunction:t-dll-api.cc:1990
|
||||
//ivl_scope_def()
|
||||
unusedFunction:t-dll-api.cc:1996
|
||||
//ivl_scope_def_file()
|
||||
unusedFunction:t-dll-api.cc:2002
|
||||
//ivl_scope_def_lineno()
|
||||
unusedFunction:t-dll-api.cc:2008
|
||||
//ivl_scope_enumerate()
|
||||
unusedFunction:t-dll-api.cc:2020
|
||||
//ivl_scope_enumerates()
|
||||
unusedFunction:t-dll-api.cc:2014
|
||||
//ivl_scope_event()
|
||||
unusedFunction:t-dll-api.cc:2033
|
||||
//ivl_scope_events()
|
||||
unusedFunction:t-dll-api.cc:2027
|
||||
//ivl_scope_child()
|
||||
unusedFunction:t-dll-api.cc:2054
|
||||
//ivl_scope_children()
|
||||
unusedFunction:t-dll-api.cc:2033
|
||||
//ivl_scope_childs()
|
||||
unusedFunction:t-dll-api.cc:2047
|
||||
//ivl_scope_class()
|
||||
unusedFunction:t-dll-api.cc:2061
|
||||
//ivl_scope_classes()
|
||||
unusedFunction:t-dll-api.cc:2068
|
||||
//ivl_scope_def()
|
||||
unusedFunction:t-dll-api.cc:2075
|
||||
//ivl_scope_def_file()
|
||||
unusedFunction:t-dll-api.cc:2081
|
||||
//ivl_scope_def_lineno()
|
||||
unusedFunction:t-dll-api.cc:2087
|
||||
//ivl_scope_enumerate()
|
||||
unusedFunction:t-dll-api.cc:2099
|
||||
//ivl_scope_enumerates()
|
||||
unusedFunction:t-dll-api.cc:2093
|
||||
//ivl_scope_event()
|
||||
unusedFunction:t-dll-api.cc:2112
|
||||
//ivl_scope_events()
|
||||
unusedFunction:t-dll-api.cc:2106
|
||||
//ivl_scope_file()
|
||||
unusedFunction:t-dll-api.cc:2040
|
||||
unusedFunction:t-dll-api.cc:2119
|
||||
//ivl_scope_func_signed
|
||||
unusedFunction:t-dll-api.cc:2132
|
||||
//ivl_scope_func_type
|
||||
unusedFunction:t-dll-api.cc:2125
|
||||
//ivl_scope_func_width
|
||||
unusedFunction:t-dll-api.cc:2140
|
||||
//ivl_scope_is_auto()
|
||||
unusedFunction:t-dll-api.cc:2046
|
||||
unusedFunction:t-dll-api.cc:2148
|
||||
//ivl_scope_is_cell()
|
||||
unusedFunction:t-dll-api.cc:2052
|
||||
unusedFunction:t-dll-api.cc:2154
|
||||
//ivl_scope_lineno()
|
||||
unusedFunction:t-dll-api.cc:2058
|
||||
//ivl_scope_log()
|
||||
unusedFunction:t-dll-api.cc:2070
|
||||
//ivl_scope_logs()
|
||||
unusedFunction:t-dll-api.cc:2064
|
||||
//ivl_scope_lpm()
|
||||
unusedFunction:t-dll-api.cc:2083
|
||||
//ivl_scope_lpms()
|
||||
unusedFunction:t-dll-api.cc:2077
|
||||
//ivl_scope_mod_module_port_name()
|
||||
unusedFunction:t-dll-api.cc:2160
|
||||
//ivl_scope_log()
|
||||
unusedFunction:t-dll-api.cc:2172
|
||||
//ivl_scope_logs()
|
||||
unusedFunction:t-dll-api.cc:2166
|
||||
//ivl_scope_lpm()
|
||||
unusedFunction:t-dll-api.cc:2185
|
||||
//ivl_scope_lpms()
|
||||
unusedFunction:t-dll-api.cc:2179
|
||||
//ivl_scope_mod_module_port_name()
|
||||
unusedFunction:t-dll-api.cc:2264
|
||||
//ivl_scope_mod_module_port_type()
|
||||
unusedFunction:t-dll-api.cc:2169
|
||||
unusedFunction:t-dll-api.cc:2273
|
||||
//ivl_scope_mod_module_port_width()
|
||||
unusedFunction:t-dll-api.cc:2180
|
||||
unusedFunction:t-dll-api.cc:2285
|
||||
//ivl_scope_mod_module_ports()
|
||||
unusedFunction:t-dll-api.cc:2153
|
||||
unusedFunction:t-dll-api.cc:2257
|
||||
//ivl_scope_mod_port()
|
||||
unusedFunction:t-dll-api.cc:2204
|
||||
unusedFunction:t-dll-api.cc:2310
|
||||
//ivl_scope_param()
|
||||
unusedFunction:t-dll-api.cc:2139
|
||||
unusedFunction:t-dll-api.cc:2243
|
||||
//ivl_scope_params()
|
||||
unusedFunction:t-dll-api.cc:2133
|
||||
unusedFunction:t-dll-api.cc:2237
|
||||
//ivl_scope_parent()
|
||||
unusedFunction:t-dll-api.cc:2146
|
||||
//ivl_scope_port()
|
||||
unusedFunction:t-dll-api.cc:2195
|
||||
//ivl_scope_ports()
|
||||
unusedFunction:t-dll-api.cc:2186
|
||||
//ivl_scope_sig()
|
||||
unusedFunction:t-dll-api.cc:2218
|
||||
//ivl_scope_sigs()
|
||||
unusedFunction:t-dll-api.cc:2212
|
||||
//ivl_scope_switch()
|
||||
unusedFunction:t-dll-api.cc:2231
|
||||
//ivl_scope_switches()
|
||||
unusedFunction:t-dll-api.cc:2225
|
||||
//ivl_scope_time_precision()
|
||||
unusedFunction:t-dll-api.cc:2238
|
||||
//ivl_scope_time_units()
|
||||
unusedFunction:t-dll-api.cc:2244
|
||||
//ivl_scope_tname()
|
||||
unusedFunction:t-dll-api.cc:2256
|
||||
//ivl_scope_type()
|
||||
unusedFunction:t-dll-api.cc:2250
|
||||
//ivl_scope_port()
|
||||
unusedFunction:t-dll-api.cc:2301
|
||||
//ivl_scope_ports()
|
||||
unusedFunction:t-dll-api.cc:2292
|
||||
//ivl_scope_sig()
|
||||
unusedFunction:t-dll-api.cc:2324
|
||||
//ivl_scope_sigs()
|
||||
unusedFunction:t-dll-api.cc:2318
|
||||
//ivl_scope_switch()
|
||||
unusedFunction:t-dll-api.cc:2337
|
||||
//ivl_scope_switches()
|
||||
unusedFunction:t-dll-api.cc:2331
|
||||
//ivl_scope_time_precision()
|
||||
unusedFunction:t-dll-api.cc:2344
|
||||
//ivl_scope_time_units()
|
||||
unusedFunction:t-dll-api.cc:2350
|
||||
//ivl_scope_tname()
|
||||
unusedFunction:t-dll-api.cc:2362
|
||||
//ivl_scope_type()
|
||||
unusedFunction:t-dll-api.cc:2356
|
||||
|
||||
//ivl_signal_array_addr_swapped()
|
||||
unusedFunction:t-dll-api.cc:2272
|
||||
//ivl_signal_array_base()
|
||||
unusedFunction:t-dll-api.cc:2262
|
||||
//ivl_signal_array_count()
|
||||
unusedFunction:t-dll-api.cc:2267
|
||||
//ivl_signal_attr()
|
||||
unusedFunction:t-dll-api.cc:2287
|
||||
//ivl_signal_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:2302
|
||||
//ivl_signal_attr_val()
|
||||
unusedFunction:t-dll-api.cc:2307
|
||||
//ivl_signal_basename()
|
||||
unusedFunction:t-dll-api.cc:2313
|
||||
//ivl_signal_data_type()
|
||||
unusedFunction:t-dll-api.cc:2447
|
||||
//ivl_signal_dimensions()
|
||||
unusedFunction:t-dll-api.cc:2277
|
||||
//ivl_signal_discipline()
|
||||
unusedFunction:t-dll-api.cc:2282
|
||||
//ivl_signal_file()
|
||||
unusedFunction:t-dll-api.cc:2425
|
||||
//ivl_signal_forced_net()
|
||||
unusedFunction:t-dll-api.cc:2420
|
||||
//ivl_signal_integer()
|
||||
unusedFunction:t-dll-api.cc:2437
|
||||
//ivl_signal_lineno()
|
||||
unusedFunction:t-dll-api.cc:2431
|
||||
//ivl_signal_local()
|
||||
unusedFunction:t-dll-api.cc:2410
|
||||
//ivl_signal_lsb()
|
||||
unusedFunction:t-dll-api.cc:2380
|
||||
//ivl_signal_array_base()
|
||||
unusedFunction:t-dll-api.cc:2368
|
||||
//ivl_signal_array_count()
|
||||
unusedFunction:t-dll-api.cc:2374
|
||||
//ivl_signal_attr()
|
||||
unusedFunction:t-dll-api.cc:2398
|
||||
//ivl_signal_attr_cnt()
|
||||
unusedFunction:t-dll-api.cc:2414
|
||||
//ivl_signal_attr_val()
|
||||
unusedFunction:t-dll-api.cc:2420
|
||||
//ivl_signal_basename()
|
||||
unusedFunction:t-dll-api.cc:2427
|
||||
//ivl_signal_data_type()
|
||||
unusedFunction:t-dll-api.cc:2578
|
||||
//ivl_signal_dimensions()
|
||||
unusedFunction:t-dll-api.cc:2386
|
||||
//ivl_signal_discipline()
|
||||
unusedFunction:t-dll-api.cc:2392
|
||||
//ivl_signal_file()
|
||||
unusedFunction:t-dll-api.cc:2555
|
||||
//ivl_signal_forced_net()
|
||||
unusedFunction:t-dll-api.cc:2549
|
||||
//ivl_signal_integer()
|
||||
unusedFunction:t-dll-api.cc:2567
|
||||
//ivl_signal_lineno()
|
||||
unusedFunction:t-dll-api.cc:2561
|
||||
//ivl_signal_local()
|
||||
unusedFunction:t-dll-api.cc:2536
|
||||
//ivl_signal_lsb()
|
||||
unusedFunction:t-dll-api.cc:2501
|
||||
//ivl_signal_module_port_index()
|
||||
unusedFunction:t-dll-api.cc:2405
|
||||
unusedFunction:t-dll-api.cc:2530
|
||||
//ivl_signal_msb()
|
||||
unusedFunction:t-dll-api.cc:2371
|
||||
unusedFunction:t-dll-api.cc:2491
|
||||
//ivl_signal_name()
|
||||
unusedFunction:t-dll-api.cc:2318
|
||||
unusedFunction:t-dll-api.cc:2433
|
||||
//ivl_signal_nex()
|
||||
unusedFunction:t-dll-api.cc:2338
|
||||
unusedFunction:t-dll-api.cc:2454
|
||||
//ivl_signal_npath()
|
||||
unusedFunction:t-dll-api.cc:2457
|
||||
unusedFunction:t-dll-api.cc:2591
|
||||
//ivl_signal_packed_dimensions()
|
||||
unusedFunction:t-dll-api.cc:2354
|
||||
unusedFunction:t-dll-api.cc:2471
|
||||
//ivl_signal_packed_lsb()
|
||||
unusedFunction:t-dll-api.cc:2365
|
||||
unusedFunction:t-dll-api.cc:2484
|
||||
//ivl_signal_packed_msb()
|
||||
unusedFunction:t-dll-api.cc:2359
|
||||
unusedFunction:t-dll-api.cc:2477
|
||||
//ivl_signal_path()
|
||||
unusedFunction:t-dll-api.cc:2462
|
||||
unusedFunction:t-dll-api.cc:2597
|
||||
//ivl_signal_port()
|
||||
unusedFunction:t-dll-api.cc:2400
|
||||
unusedFunction:t-dll-api.cc:2524
|
||||
//ivl_signal_scope()
|
||||
unusedFunction:t-dll-api.cc:2389
|
||||
unusedFunction:t-dll-api.cc:2511
|
||||
//ivl_signal_signed()
|
||||
unusedFunction:t-dll-api.cc:2415
|
||||
unusedFunction:t-dll-api.cc:2542
|
||||
//ivl_signal_width()
|
||||
unusedFunction:t-dll-api.cc:2395
|
||||
unusedFunction:t-dll-api.cc:2517
|
||||
|
||||
//ivl_statement_type()
|
||||
unusedFunction:t-dll-api.cc:2473
|
||||
unusedFunction:t-dll-api.cc:2610
|
||||
|
||||
//ivl_stmt_block_count()
|
||||
unusedFunction:t-dll-api.cc:2502
|
||||
unusedFunction:t-dll-api.cc:2643
|
||||
//ivl_stmt_block_scope()
|
||||
unusedFunction:t-dll-api.cc:2488
|
||||
unusedFunction:t-dll-api.cc:2628
|
||||
//ivl_stmt_block_stmt()
|
||||
unusedFunction:t-dll-api.cc:2516
|
||||
unusedFunction:t-dll-api.cc:2658
|
||||
//ivl_stmt_call()
|
||||
unusedFunction:t-dll-api.cc:2531
|
||||
unusedFunction:t-dll-api.cc:2674
|
||||
//ivl_stmt_case_count()
|
||||
unusedFunction:t-dll-api.cc:2551
|
||||
unusedFunction:t-dll-api.cc:2695
|
||||
//ivl_stmt_case_expr()
|
||||
unusedFunction:t-dll-api.cc:2565
|
||||
unusedFunction:t-dll-api.cc:2710
|
||||
//ivl_stmt_case_stmt()
|
||||
unusedFunction:t-dll-api.cc:2581
|
||||
unusedFunction:t-dll-api.cc:2727
|
||||
//ivl_stmt_cond_expr()
|
||||
unusedFunction:t-dll-api.cc:2597
|
||||
unusedFunction:t-dll-api.cc:2744
|
||||
//ivl_stmt_cond_false()
|
||||
unusedFunction:t-dll-api.cc:2623
|
||||
unusedFunction:t-dll-api.cc:2771
|
||||
//ivl_stmt_cond_true()
|
||||
unusedFunction:t-dll-api.cc:2632
|
||||
unusedFunction:t-dll-api.cc:2781
|
||||
//ivl_stmt_delay_expr()
|
||||
unusedFunction:t-dll-api.cc:2641
|
||||
unusedFunction:t-dll-api.cc:2791
|
||||
//ivl_stmt_delay_val()
|
||||
unusedFunction:t-dll-api.cc:2657
|
||||
unusedFunction:t-dll-api.cc:2808
|
||||
//ivl_stmt_events()
|
||||
unusedFunction:t-dll-api.cc:2681
|
||||
unusedFunction:t-dll-api.cc:2834
|
||||
//ivl_stmt_file()
|
||||
unusedFunction:t-dll-api.cc:2478
|
||||
unusedFunction:t-dll-api.cc:2616
|
||||
//ivl_stmt_lexp()
|
||||
unusedFunction:t-dll-api.cc:2708
|
||||
//ivl_stmt_lineno()
|
||||
unusedFunction:t-dll-api.cc:2483
|
||||
//ivl_stmt_lval()
|
||||
unusedFunction:t-dll-api.cc:2719
|
||||
//ivl_stmt_lvals()
|
||||
unusedFunction:t-dll-api.cc:2737
|
||||
//ivl_stmt_lwidth()
|
||||
unusedFunction:t-dll-api.cc:2754
|
||||
//ivl_stmt_name()
|
||||
unusedFunction:t-dll-api.cc:2786
|
||||
//ivl_stmt_nevent()
|
||||
unusedFunction:t-dll-api.cc:2663
|
||||
//ivl_stmt_opcode()
|
||||
unusedFunction:t-dll-api.cc:2798
|
||||
//ivl_stmt_parm()
|
||||
unusedFunction:t-dll-api.cc:2809
|
||||
//ivl_stmt_parm_count()
|
||||
unusedFunction:t-dll-api.cc:2822
|
||||
//ivl_stmt_rval()
|
||||
unusedFunction:t-dll-api.cc:2833
|
||||
//ivl_stmt_sfunc_as_task()
|
||||
unusedFunction:t-dll-api.cc:2850
|
||||
//ivl_stmt_sub_stmt()
|
||||
unusedFunction:t-dll-api.cc:2862
|
||||
//ivl_stmt_lineno()
|
||||
unusedFunction:t-dll-api.cc:2622
|
||||
//ivl_stmt_lval()
|
||||
unusedFunction:t-dll-api.cc:2874
|
||||
//ivl_stmt_lvals()
|
||||
unusedFunction:t-dll-api.cc:2893
|
||||
//ivl_stmt_lwidth()
|
||||
unusedFunction:t-dll-api.cc:2911
|
||||
//ivl_stmt_name()
|
||||
unusedFunction:t-dll-api.cc:2944
|
||||
//ivl_stmt_nevent()
|
||||
unusedFunction:t-dll-api.cc:2815
|
||||
//ivl_stmt_opcode()
|
||||
unusedFunction:t-dll-api.cc:2957
|
||||
//ivl_stmt_parm()
|
||||
unusedFunction:t-dll-api.cc:2969
|
||||
//ivl_stmt_parm_count()
|
||||
unusedFunction:t-dll-api.cc:2983
|
||||
//ivl_stmt_rval()
|
||||
unusedFunction:t-dll-api.cc:2995
|
||||
//ivl_stmt_sfunc_as_task()
|
||||
unusedFunction:t-dll-api.cc:3013
|
||||
//ivl_stmt_sub_stmt()
|
||||
unusedFunction:t-dll-api.cc:3026
|
||||
|
||||
//ivl_switch_a()
|
||||
unusedFunction:t-dll-api.cc:2899
|
||||
unusedFunction:t-dll-api.cc:3067
|
||||
//ivl_switch_b()
|
||||
unusedFunction:t-dll-api.cc:2904
|
||||
unusedFunction:t-dll-api.cc:3073
|
||||
//ivl_switch_basename()
|
||||
unusedFunction:t-dll-api.cc:2884
|
||||
unusedFunction:t-dll-api.cc:3049
|
||||
//ivl_switch_delay()
|
||||
unusedFunction:t-dll-api.cc:2929
|
||||
unusedFunction:t-dll-api.cc:3103
|
||||
//ivl_switch_enable()
|
||||
unusedFunction:t-dll-api.cc:2909
|
||||
unusedFunction:t-dll-api.cc:3079
|
||||
//ivl_switch_file()
|
||||
unusedFunction:t-dll-api.cc:2935
|
||||
unusedFunction:t-dll-api.cc:3110
|
||||
//ivl_switch_island()
|
||||
unusedFunction:t-dll-api.cc:2940
|
||||
unusedFunction:t-dll-api.cc:3116
|
||||
//ivl_switch_lineno()
|
||||
unusedFunction:t-dll-api.cc:2945
|
||||
unusedFunction:t-dll-api.cc:3122
|
||||
//ivl_switch_offset()
|
||||
unusedFunction:t-dll-api.cc:2924
|
||||
unusedFunction:t-dll-api.cc:3097
|
||||
//ivl_switch_part()
|
||||
unusedFunction:t-dll-api.cc:2919
|
||||
unusedFunction:t-dll-api.cc:3091
|
||||
//ivl_switch_scope()
|
||||
unusedFunction:t-dll-api.cc:2889
|
||||
unusedFunction:t-dll-api.cc:3055
|
||||
//ivl_switch_type()
|
||||
unusedFunction:t-dll-api.cc:2894
|
||||
unusedFunction:t-dll-api.cc:3061
|
||||
//ivl_switch_width()
|
||||
unusedFunction:t-dll-api.cc:2914
|
||||
unusedFunction:t-dll-api.cc:3085
|
||||
|
||||
//ivl_type_base()
|
||||
unusedFunction:t-dll-api.cc:2950
|
||||
unusedFunction:t-dll-api.cc:3128
|
||||
//ivl_type_element()
|
||||
unusedFunction:t-dll-api.cc:2956
|
||||
unusedFunction:t-dll-api.cc:3134
|
||||
//ivl_type_name()
|
||||
unusedFunction:t-dll-api.cc:2985
|
||||
unusedFunction:t-dll-api.cc:3166
|
||||
//ivl_type_packed_dimensions()
|
||||
unusedFunction:t-dll-api.cc:2965
|
||||
unusedFunction:t-dll-api.cc:3143
|
||||
//ivl_type_packed_lsb()
|
||||
unusedFunction:t-dll-api.cc:2971
|
||||
unusedFunction:t-dll-api.cc:3150
|
||||
//ivl_type_packed_msb()
|
||||
unusedFunction:t-dll-api.cc:2978
|
||||
unusedFunction:t-dll-api.cc:3158
|
||||
//ivl_type_prop_type()
|
||||
unusedFunction:t-dll-api.cc:3011
|
||||
unusedFunction:t-dll-api.cc:3191
|
||||
//ivl_type_properties()
|
||||
unusedFunction:t-dll-api.cc:2994
|
||||
unusedFunction:t-dll-api.cc:3174
|
||||
//ivl_type_signed()
|
||||
unusedFunction:t-dll-api.cc:3019
|
||||
unusedFunction:t-dll-api.cc:3199
|
||||
|
||||
//ivl_udp_file()
|
||||
unusedFunction:t-dll-api.cc:990
|
||||
unusedFunction:t-dll-api.cc:1036
|
||||
//ivl_udp_init()
|
||||
unusedFunction:t-dll-api.cc:958
|
||||
unusedFunction:t-dll-api.cc:999
|
||||
//ivl_udp_lineno()
|
||||
unusedFunction:t-dll-api.cc:995
|
||||
unusedFunction:t-dll-api.cc:1042
|
||||
//ivl_udp_name()
|
||||
unusedFunction:t-dll-api.cc:984
|
||||
unusedFunction:t-dll-api.cc:1029
|
||||
//ivl_udp_nin()
|
||||
unusedFunction:t-dll-api.cc:953
|
||||
unusedFunction:t-dll-api.cc:993
|
||||
//ivl_udp_port()
|
||||
unusedFunction:t-dll-api.cc:963
|
||||
unusedFunction:t-dll-api.cc:1005
|
||||
//ivl_udp_row()
|
||||
unusedFunction:t-dll-api.cc:971
|
||||
unusedFunction:t-dll-api.cc:1014
|
||||
//ivl_udp_rows()
|
||||
unusedFunction:t-dll-api.cc:979
|
||||
unusedFunction:t-dll-api.cc:1023
|
||||
// ivl_udp_sequ()
|
||||
unusedFunction:t-dll-api.cc:948
|
||||
unusedFunction:t-dll-api.cc:987
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -187,9 +187,15 @@ ostream& operator << (ostream&fd, NetCaseCmp::kind_t that)
|
|||
case NetCaseCmp::NEQ:
|
||||
fd << "!==";
|
||||
break;
|
||||
case NetCaseCmp::XEQ:
|
||||
case NetCaseCmp::WEQ:
|
||||
fd << "==?";
|
||||
break;
|
||||
case NetCaseCmp::WNE:
|
||||
fd << "!=?";
|
||||
break;
|
||||
case NetCaseCmp::XEQ:
|
||||
fd << "==x?";
|
||||
break;
|
||||
case NetCaseCmp::ZEQ:
|
||||
fd << "==z?";
|
||||
break;
|
||||
|
|
@ -984,6 +990,18 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
|
|||
o << "always /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
o << "always_comb /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
o << "always_ff /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
o << "always_latch /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case IVL_PR_FINAL:
|
||||
o << "final /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
|
|
@ -1011,6 +1029,13 @@ void NetAnalogTop::dump(ostream&o, unsigned ind) const
|
|||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
|
||||
// These are not used in an analog context.
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
case IVL_PR_FINAL:
|
||||
o << "analog final /* " << get_fileline() << " in "
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
|
|
@ -1390,6 +1415,8 @@ void NetScope::dump(ostream&o) const
|
|||
if (is_interface()) o << " (interface)";
|
||||
o << " " << children_.size() << " children, "
|
||||
<< classes_.size() << " classes" << endl;
|
||||
if (unit() && !is_unit())
|
||||
o << " in compilation unit " << unit()->basename() << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
||||
o << " (* " << attr_key(idx) << " = "
|
||||
|
|
@ -1629,11 +1656,14 @@ void NetEBinary::dump(ostream&o) const
|
|||
case 'A':
|
||||
o << "~&";
|
||||
break;
|
||||
case 'e':
|
||||
o << "==";
|
||||
break;
|
||||
case 'E':
|
||||
o << "===";
|
||||
break;
|
||||
case 'e':
|
||||
o << "==";
|
||||
case 'w':
|
||||
o << "==?";
|
||||
break;
|
||||
case 'G':
|
||||
o << ">=";
|
||||
|
|
@ -1650,6 +1680,9 @@ void NetEBinary::dump(ostream&o) const
|
|||
case 'N':
|
||||
o << "!==";
|
||||
break;
|
||||
case 'W':
|
||||
o << "!=?";
|
||||
break;
|
||||
case 'o':
|
||||
o << "||";
|
||||
break;
|
||||
|
|
@ -1902,18 +1935,6 @@ void Design::dump(ostream&o) const
|
|||
cur->second->dump(o);
|
||||
}
|
||||
|
||||
o << "$ROOT CLASSES:" << endl;
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
cur->second->dump_scope(o);
|
||||
}
|
||||
|
||||
o << "$ROOT TASKS/FUNCTIONS:" << endl;
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
cur->first->dump(o);
|
||||
}
|
||||
|
||||
o << "SCOPES:" << endl;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); ++ scope ) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -252,7 +252,7 @@ void destroy_lexor(void)
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
.TH iverilog 1 "Oct 2nd, 2016" "" "Version %M.%n%E"
|
||||
.TH iverilog 1 "Nov 8th, 2017" "" "Version %M.%n%E"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-ESuVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-Pparameter=value] [\-pflag=value] [\-dname]
|
||||
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g<feature>]
|
||||
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
|
||||
|
|
@ -222,6 +222,12 @@ will suppress the warning that the compiler is making a choice.
|
|||
Use this switch to specify the target output format. See the
|
||||
\fBTARGETS\fP section below for a list of valid output formats.
|
||||
.TP 8
|
||||
.B -u
|
||||
Treat each source file as a separate compilation unit (as defined in
|
||||
SystemVerilog). If compiling for an \fIIEEE1364\fP generation, this
|
||||
will just reset all compiler directives (including macro definitions)
|
||||
before each new file is processed.
|
||||
.TP 8
|
||||
.B -v
|
||||
Turn on verbose messages. This will print the command lines that are
|
||||
executed to perform the actual compilation, along with version
|
||||
|
|
@ -264,7 +270,7 @@ that contain Verilog source files. During elaboration, the compiler
|
|||
notices the instantiation of undefined module types. If the user
|
||||
specifies library search directories, the compiler will search the
|
||||
directory for files with the name of the missing module type. If it
|
||||
finds such a file, it loads it as a Verilog source file, they tries
|
||||
finds such a file, it loads it as a Verilog source file, then tries
|
||||
again to elaborate the module.
|
||||
|
||||
Library module files should contain only a single module, but this is
|
||||
|
|
@ -310,8 +316,9 @@ after a \fB\-Wall\fP argument to suppress isolated warning types.
|
|||
|
||||
.TP 8
|
||||
.B all
|
||||
This enables the anachronisms, implicit, portbind, select\-range,
|
||||
timescale, and sensitivity\-entire\-array warning categories.
|
||||
This enables the anachronisms, implicit, macro-replacement, portbind,
|
||||
select\-range, timescale, and sensitivity\-entire\-array warning
|
||||
categories.
|
||||
|
||||
.TP 8
|
||||
.B anachronisms
|
||||
|
|
@ -324,6 +331,13 @@ This enables warnings for creation of implicit declarations. For
|
|||
example, if a scalar wire X is used but not declared in the Verilog
|
||||
source, this will print a warning at its first use.
|
||||
|
||||
.TP 8
|
||||
.B macro-redefinition\fI | \fPmacro-replacement
|
||||
This enables preprocessor warnings when a macro is being redefined.
|
||||
The first variant prints a warning any time a macro is redefined.
|
||||
The second variant only prints a warning if the macro text changes.
|
||||
Use \fBno-macro-redefinition\fP to turn off all warnings of this type.
|
||||
|
||||
.TP 8
|
||||
.B portbind
|
||||
This enables warnings for ports of module instantiations that are not
|
||||
|
|
@ -564,7 +578,7 @@ Tips on using, debugging, and developing the compiler can be found at
|
|||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2016 Stephen Williams
|
||||
Copyright \(co 2002\-2017 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -38,7 +38,7 @@ const char NOTICE[] =
|
|||
;
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]\n"
|
||||
"Usage: iverilog [-EiSuvV] [-B base] [-c cmdfile|-f cmdfile]\n"
|
||||
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g<feature>]\n"
|
||||
" [-D macro[=defn]] [-I includedir]\n"
|
||||
" [-M [mode=]depfile] [-m module]\n"
|
||||
|
|
@ -138,7 +138,12 @@ int gen_std_include = 1;
|
|||
of the include list. */
|
||||
int gen_relative_include = 0;
|
||||
|
||||
char warning_flags[16] = "n";
|
||||
char warning_flags[17] = "n";
|
||||
|
||||
int separate_compilation_flag = 0;
|
||||
|
||||
/* Boolean: true means ignore errors about missing modules */
|
||||
int ignore_missing_modules = 0;
|
||||
|
||||
unsigned integer_width = 32;
|
||||
|
||||
|
|
@ -341,10 +346,15 @@ static int t_version_only(void)
|
|||
|
||||
static void build_preprocess_command(int e_flag)
|
||||
{
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\" ",
|
||||
ivlpp_dir, sep, verbose_flag?" -v":"",
|
||||
e_flag?"":" -L", defines_path, source_path,
|
||||
compiled_defines_path);
|
||||
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s",
|
||||
ivlpp_dir, sep,
|
||||
verbose_flag ? " -v" : "",
|
||||
e_flag ? "" : " -L",
|
||||
strchr(warning_flags, 'r') ? " -Wredef-all " :
|
||||
strchr(warning_flags, 'R') ? " -Wredef-chg " : "",
|
||||
defines_path, source_path,
|
||||
compiled_defines_path,
|
||||
e_flag ? "" : " | ");
|
||||
}
|
||||
|
||||
static int t_preprocess_only(void)
|
||||
|
|
@ -407,8 +417,12 @@ static int t_compile(void)
|
|||
{
|
||||
unsigned rc;
|
||||
|
||||
/* Start by building the preprocess command line. */
|
||||
build_preprocess_command(0);
|
||||
/* Start by building the preprocess command line, if required.
|
||||
This pipes into the main ivl command. */
|
||||
if (!separate_compilation_flag)
|
||||
build_preprocess_command(0);
|
||||
else
|
||||
strcpy(tmp, "");
|
||||
|
||||
size_t ncmd = strlen(tmp);
|
||||
char*cmd = malloc(ncmd + 1);
|
||||
|
|
@ -418,8 +432,8 @@ static int t_compile(void)
|
|||
int rtn;
|
||||
#endif
|
||||
|
||||
/* Build the ivl command and pipe it to the preprocessor. */
|
||||
snprintf(tmp, sizeof tmp, " | %s%civl", base, sep);
|
||||
/* Build the ivl command. */
|
||||
snprintf(tmp, sizeof tmp, "%s%civl", base, sep);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
|
|
@ -447,7 +461,16 @@ static int t_compile(void)
|
|||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
snprintf(tmp, sizeof tmp, " -C\"%s\" -- -", iconfig_common_path);
|
||||
snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_common_path);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
if (separate_compilation_flag)
|
||||
snprintf(tmp, sizeof tmp, " -F\"%s\"", source_path);
|
||||
else
|
||||
snprintf(tmp, sizeof tmp, " -- -");
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
|
|
@ -498,6 +521,7 @@ static void process_warning_switch(const char*name)
|
|||
process_warning_switch("anachronisms");
|
||||
process_warning_switch("implicit");
|
||||
process_warning_switch("implicit-dimensions");
|
||||
process_warning_switch("macro-replacement");
|
||||
process_warning_switch("portbind");
|
||||
process_warning_switch("select-range");
|
||||
process_warning_switch("timescale");
|
||||
|
|
@ -514,6 +538,12 @@ static void process_warning_switch(const char*name)
|
|||
} else if (strcmp(name,"implicit-dimensions") == 0) {
|
||||
if (! strchr(warning_flags, 'd'))
|
||||
strcat(warning_flags, "d");
|
||||
} else if (strcmp(name,"macro-redefinition") == 0) {
|
||||
if (! strchr(warning_flags, 'r'))
|
||||
strcat(warning_flags, "r");
|
||||
} else if (strcmp(name,"macro-replacement") == 0) {
|
||||
if (! strchr(warning_flags, 'R'))
|
||||
strcat(warning_flags, "R");
|
||||
} else if (strcmp(name,"portbind") == 0) {
|
||||
if (! strchr(warning_flags, 'p'))
|
||||
strcat(warning_flags, "p");
|
||||
|
|
@ -558,6 +588,17 @@ static void process_warning_switch(const char*name)
|
|||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-macro-redefinition") == 0) {
|
||||
char*cp = strchr(warning_flags, 'r');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
cp = strchr(warning_flags, 'R');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-portbind") == 0) {
|
||||
char*cp = strchr(warning_flags, 'p');
|
||||
if (cp) while (*cp) {
|
||||
|
|
@ -987,7 +1028,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hl:I:M:m:N:o:P:p:Ss:T:t:vVW:y:Y:")) != EOF) {
|
||||
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hl:I:iM:m:N:o:P:p:Ss:T:t:uvVW:y:Y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
|
|
@ -1042,6 +1083,10 @@ int main(int argc, char **argv)
|
|||
process_include_dir(optarg);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
ignore_missing_modules = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
process_file_name(optarg, 1);
|
||||
break;
|
||||
|
|
@ -1086,6 +1131,9 @@ int main(int argc, char **argv)
|
|||
case 't':
|
||||
targ = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
separate_compilation_flag = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose_flag = 1;
|
||||
break;
|
||||
|
|
@ -1128,7 +1176,7 @@ int main(int argc, char **argv)
|
|||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
||||
printf("Copyright 1998-2015 Stephen Williams\n\n");
|
||||
printf("Copyright 1998-2017 Stephen Williams\n\n");
|
||||
puts(NOTICE);
|
||||
}
|
||||
|
||||
|
|
@ -1184,6 +1232,7 @@ int main(int argc, char **argv)
|
|||
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
|
||||
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
|
||||
fprintf(iconfig_file, "ignore_missing_modules:%s\n", ignore_missing_modules ? "true" : "false");
|
||||
fprintf(iconfig_file, "out:%s\n", opath);
|
||||
if (depfile) {
|
||||
fprintf(iconfig_file, "depfile:%s\n", depfile);
|
||||
|
|
@ -1260,8 +1309,12 @@ int main(int argc, char **argv)
|
|||
will append to the file, so this is necessary to make sure
|
||||
it starts out empty. */
|
||||
if (depfile) {
|
||||
FILE*fd = fopen(depfile, "w");
|
||||
fclose(fd);
|
||||
FILE *fd = fopen(depfile, "w");
|
||||
if (!fd) {
|
||||
fprintf(stderr, "%s: can't open %s file.\n\n%s\n", argv[0], depfile, HELP);
|
||||
return 1;
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
if (source_count == 0 && !version_flag) {
|
||||
|
|
@ -1276,8 +1329,12 @@ int main(int argc, char **argv)
|
|||
/* Write the preprocessor command needed to preprocess a
|
||||
single file. This may be used to preprocess library
|
||||
files. */
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F\"%s\" -P\"%s\"\n",
|
||||
ivlpp_dir, sep, defines_path, compiled_defines_path);
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp %s -L -F\"%s\" -P\"%s\"\n",
|
||||
ivlpp_dir, sep,
|
||||
strchr(warning_flags, 'r') ? "-Wredef-all" :
|
||||
strchr(warning_flags, 'R') ? "-Wredef-chg" : "",
|
||||
defines_path, compiled_defines_path
|
||||
);
|
||||
|
||||
/* Done writing to the iconfig file. Close it now. */
|
||||
fclose(iconfig_file);
|
||||
|
|
|
|||
95
elab_expr.cc
95
elab_expr.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -329,10 +329,12 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
case '>': // > Should be handled by PEBComp
|
||||
case 'e': // == Should be handled by PEBComp
|
||||
case 'E': // === Should be handled by PEBComp
|
||||
case 'w': // ==? Should be handled by PEBComp
|
||||
case 'L': // <= Should be handled by PEBComp
|
||||
case 'G': // >= Should be handled by PEBComp
|
||||
case 'n': // != Should be handled by PEBComp
|
||||
case 'N': // !== Should be handled by PEBComp
|
||||
case 'W': // !=? Should be handled by PEBComp
|
||||
case 'p': // ** should be handled by PEBPower
|
||||
ivl_assert(*this, 0);
|
||||
default:
|
||||
|
|
@ -668,6 +670,18 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
break;
|
||||
case 'w': /* ==? */
|
||||
case 'W': /* !=? */
|
||||
if ((lp->expr_type() != IVL_VT_BOOL && lp->expr_type() != IVL_VT_LOGIC) ||
|
||||
(rp->expr_type() != IVL_VT_BOOL && rp->expr_type() != IVL_VT_LOGIC)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< human_readable_op(op_)
|
||||
<< " operator may only have INTEGRAL operands."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1442,6 +1456,13 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!type_is_vectorable(expr_type_)) {
|
||||
cerr << get_fileline() << ": error: The argument to "
|
||||
<< name << " must be a vector type." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
|
||||
<< name << " expression is the argument cast to expr_wid=" << expr_wid << endl;
|
||||
|
|
@ -2264,8 +2285,8 @@ NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*ds
|
|||
}
|
||||
|
||||
cerr << get_fileline() << ": internal error: Unable to locate "
|
||||
"function return value for " << path_
|
||||
<< " in " << dscope->basename() << "." << endl;
|
||||
"function return value for " << path_
|
||||
<< " in " << dscope->basename() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2536,7 +2557,13 @@ NetExpr* PECastSize::elaborate_expr(Design*des, NetScope*scope,
|
|||
ivl_assert(*this, size_);
|
||||
ivl_assert(*this, base_);
|
||||
|
||||
NetExpr*sub = base_->elaborate_expr(des, scope, base_->expr_width(), flags);
|
||||
// When changing size, a cast behaves exactly like an assignment,
|
||||
// so the result size affects the final expression width.
|
||||
unsigned cast_width = base_->expr_width();
|
||||
if (cast_width < expr_width_)
|
||||
cast_width = expr_width_;
|
||||
|
||||
NetExpr*sub = base_->elaborate_expr(des, scope, cast_width, flags);
|
||||
|
||||
// Perform the cast. The extension method (zero/sign), if needed,
|
||||
// depends on the type of the base expression.
|
||||
|
|
@ -2590,7 +2617,7 @@ NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
// Find rounded up length that can fit the whole casted array of vectors
|
||||
int len = base->expr_width() + vector->packed_width() - 1;
|
||||
if(base->expr_width() > vector->packed_width()) {
|
||||
if(base->expr_width() > (unsigned)vector->packed_width()) {
|
||||
len /= vector->packed_width();
|
||||
} else {
|
||||
len /= base->expr_width();
|
||||
|
|
@ -2754,6 +2781,7 @@ NetExpr* PEConcat::elaborate_expr(Design*, NetScope*,
|
|||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
// fallthrough
|
||||
default:
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "I don't know how to elaborate(ivl_type_t)"
|
||||
|
|
@ -3141,6 +3169,25 @@ unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&)
|
|||
}
|
||||
}
|
||||
|
||||
// Look for the enumeration attributes.
|
||||
if (const netenum_t*netenum = net->enumeration()) {
|
||||
if (member_name == "num") {
|
||||
expr_type_ = IVL_VT_BOOL;
|
||||
expr_width_ = 32;
|
||||
min_width_ = 32;
|
||||
signed_flag_= true;
|
||||
return 32;
|
||||
}
|
||||
if ((member_name == "first") || (member_name == "last") ||
|
||||
(member_name == "next") || (member_name == "prev")) {
|
||||
expr_type_ = netenum->base_type();
|
||||
expr_width_ = netenum->packed_width();;
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = netenum->get_signed();
|
||||
return expr_width_;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3448,29 +3495,41 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
if (net == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Expecting idents with ntype to be signals." << endl;
|
||||
cerr << get_fileline() << ": error: Unable to bind variable `"
|
||||
<< path_ << "' in `" << scope_path(use_scope) << "'" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! ntype->type_compatible(net->net_type())) {
|
||||
cerr << get_fileline() << ": internal_error: "
|
||||
<< "net type doesn't match context type." << endl;
|
||||
if (const netdarray_t*array_type = dynamic_cast<const netdarray_t*> (ntype)) {
|
||||
if (array_type->type_compatible(net->net_type())) {
|
||||
NetESignal*tmp = new NetESignal(net);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "net type=";
|
||||
// Icarus allows a dynamic array to be initialised with a
|
||||
// single elementary value, so try that next.
|
||||
ntype = array_type->element_type();
|
||||
}
|
||||
|
||||
if (! ntype->type_compatible(net->net_type())) {
|
||||
cerr << get_fileline() << ": error: the type of the variable '"
|
||||
<< path_ << "' doesn't match the context type." << endl;
|
||||
|
||||
cerr << get_fileline() << ": : " << "variable type=";
|
||||
if (net->net_type())
|
||||
net->net_type()->debug_dump(cerr);
|
||||
else
|
||||
cerr << "<nil>";
|
||||
cerr << endl;
|
||||
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "context type=";
|
||||
cerr << get_fileline() << ": : " << "context type=";
|
||||
ivl_assert(*this, ntype);
|
||||
ntype->debug_dump(cerr);
|
||||
cerr << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
ivl_assert(*this, ntype->type_compatible(net->net_type()));
|
||||
|
||||
|
|
@ -5326,9 +5385,8 @@ NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*scope,
|
|||
// expression. Elaborate the expression as an element
|
||||
// type. The run-time will assign this value to each element.
|
||||
const netarray_t*array_type = dynamic_cast<const netarray_t*> (ntype);
|
||||
ivl_type_t elem_type = array_type->element_type();
|
||||
|
||||
init_val = init_->elaborate_expr(des, scope, elem_type, flags);
|
||||
init_val = init_->elaborate_expr(des, scope, array_type, flags);
|
||||
}
|
||||
|
||||
NetENew*tmp = new NetENew(ntype, size, init_val);
|
||||
|
|
@ -5579,6 +5637,10 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
|
|||
|
||||
NetExpr* PENumber::elaborate_expr(Design*des, NetScope*, ivl_type_t ntype, unsigned) const
|
||||
{
|
||||
// Icarus allows dynamic arrays to be initialised with a single value.
|
||||
if (const netdarray_t*array_type = dynamic_cast<const netdarray_t*> (ntype))
|
||||
ntype = array_type->element_type();
|
||||
|
||||
const netvector_t*use_type = dynamic_cast<const netvector_t*> (ntype);
|
||||
if (use_type == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
|
|
@ -5685,7 +5747,6 @@ unsigned PETernary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
} else if (tru_type == IVL_VT_LOGIC || fal_type == IVL_VT_LOGIC) {
|
||||
expr_type_ = IVL_VT_LOGIC;
|
||||
} else {
|
||||
ivl_assert(*this, tru_type == fal_type);
|
||||
expr_type_ = tru_type;
|
||||
}
|
||||
if (expr_type_ == IVL_VT_REAL) {
|
||||
|
|
|
|||
|
|
@ -1194,7 +1194,12 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
|||
if (!name_tail.index.empty())
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
ivl_assert(*this, use_sel == index_component_t::SEL_NONE || use_sel == index_component_t::SEL_BIT);
|
||||
if (use_sel != index_component_t::SEL_NONE && use_sel != index_component_t::SEL_BIT) {
|
||||
cerr << get_fileline() << ": sorry: Assignments to part selects of "
|
||||
"a struct member are not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! name_tail.index.empty()) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -59,7 +59,7 @@ void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
|
|||
{
|
||||
scope->time_unit(pscope->time_unit);
|
||||
scope->time_precision(pscope->time_precision);
|
||||
scope->time_from_timescale(pscope->time_from_timescale);
|
||||
scope->time_from_timescale(pscope->has_explicit_timescale());
|
||||
des->set_precision(pscope->time_precision);
|
||||
}
|
||||
|
||||
|
|
@ -167,8 +167,7 @@ static void collect_scope_specparams_(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
/*
|
||||
* Elaborate the enumeration into the given scope. If scope==0, then
|
||||
* the enumeration goes into $root instead of a scope.
|
||||
* Elaborate the enumeration into the given scope.
|
||||
*/
|
||||
static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
enum_type_t*enum_type)
|
||||
|
|
@ -193,10 +192,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
enum_type);
|
||||
|
||||
use_enum->set_line(enum_type->li);
|
||||
if (scope)
|
||||
scope->add_enumeration_set(enum_type, use_enum);
|
||||
else
|
||||
des->add_enumeration_set(enum_type, use_enum);
|
||||
scope->add_enumeration_set(enum_type, use_enum);
|
||||
|
||||
size_t name_idx = 0;
|
||||
// Find the enumeration width.
|
||||
|
|
@ -364,10 +360,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value);
|
||||
if (scope)
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
else
|
||||
rc_flag &= des->add_enumeration_name(use_enum, cur->name);
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
|
||||
if (! rc_flag) {
|
||||
cerr << use_enum->get_fileline()
|
||||
|
|
@ -397,15 +390,6 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
|||
}
|
||||
}
|
||||
|
||||
void elaborate_rootscope_enumerations(Design*des)
|
||||
{
|
||||
for (set<enum_type_t*>::const_iterator cur = pform_enum_sets.begin()
|
||||
; cur != pform_enum_sets.end() ; ++ cur) {
|
||||
enum_type_t*curp = *cur;
|
||||
elaborate_scope_enumeration(des, 0, curp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the pclass includes an implicit and explicit constructor, then
|
||||
* merge the implicit constructor into the explicit constructor as
|
||||
|
|
@ -509,7 +493,6 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
|||
|
||||
netclass_t*use_base_class = 0;
|
||||
if (base_class) {
|
||||
ivl_assert(*pclass, scope);
|
||||
use_base_class = scope->find_class(base_class->name);
|
||||
if (use_base_class == 0) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
|
|
@ -525,9 +508,10 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
|||
use_type->save_elaborated_type = use_class;
|
||||
|
||||
// Class scopes have no parent scope, because references are
|
||||
// not allowed to escape a class method.
|
||||
// not allowed to escape a class method. But they are allowed
|
||||
// to reference the compilation unit scope.
|
||||
NetScope*class_scope = new NetScope(0, hname_t(pclass->pscope_name()),
|
||||
NetScope::CLASS);
|
||||
NetScope::CLASS, scope->unit());
|
||||
class_scope->set_line(pclass);
|
||||
class_scope->set_class_def(use_class);
|
||||
use_class->set_class_scope(class_scope);
|
||||
|
|
@ -586,12 +570,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
|||
cur->second->elaborate_scope(des, method_scope);
|
||||
}
|
||||
|
||||
if (scope) {
|
||||
scope->add_class(use_class);
|
||||
|
||||
} else {
|
||||
des->add_class(use_class, pclass);
|
||||
}
|
||||
scope->add_class(use_class);
|
||||
}
|
||||
|
||||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
|
|
@ -603,18 +582,6 @@ static void elaborate_scope_classes(Design*des, NetScope*scope,
|
|||
}
|
||||
}
|
||||
|
||||
void elaborate_rootscope_classes(Design*des)
|
||||
{
|
||||
if (pform_classes.empty())
|
||||
return;
|
||||
|
||||
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
|
||||
; cur != pform_classes.end() ; ++ cur) {
|
||||
blend_class_constructors(cur->second);
|
||||
elaborate_scope_class(des, 0, cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
||||
const Module::replace_t&replacements)
|
||||
{
|
||||
|
|
@ -664,11 +631,6 @@ static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task)
|
|||
task_scope->is_auto(task->is_auto());
|
||||
task_scope->set_line(task);
|
||||
|
||||
if (scope==0) {
|
||||
set_scope_timescale(des, task_scope, task);
|
||||
des->add_root_task(task_scope, task);
|
||||
}
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << task->get_fileline() << ": elaborate_scope_task: "
|
||||
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
||||
|
|
@ -731,11 +693,6 @@ static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task)
|
|||
task_scope->is_auto(task->is_auto());
|
||||
task_scope->set_line(task);
|
||||
|
||||
if (scope==0) {
|
||||
set_scope_timescale(des, task_scope, task);
|
||||
des->add_root_task(task_scope, task);
|
||||
}
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << task->get_fileline() << ": elaborate_scope_func: "
|
||||
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
||||
|
|
@ -791,28 +748,6 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
|||
|
||||
}
|
||||
|
||||
void elaborate_rootscope_tasks(Design*des)
|
||||
{
|
||||
for (map<perm_string,PTaskFunc*>::iterator cur = pform_tasks.begin()
|
||||
; cur != pform_tasks.end() ; ++ cur) {
|
||||
|
||||
if (PTask*task = dynamic_cast<PTask*> (cur->second)) {
|
||||
elaborate_scope_task(des, 0, task);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PFunction*func = dynamic_cast<PFunction*>(cur->second)) {
|
||||
elaborate_scope_func(des, 0, func);
|
||||
continue;
|
||||
}
|
||||
|
||||
cerr << cur->second->get_fileline() << ": internal error: "
|
||||
<< "elaborate_rootscope_tasks does not understand "
|
||||
<< "this object," << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
class generate_schemes_work_item_t : public elaborator_work_item_t {
|
||||
public:
|
||||
generate_schemes_work_item_t(Design*des__, NetScope*scope, Module*mod)
|
||||
|
|
@ -1169,7 +1104,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
container->genvar_tmp_val = genvar;
|
||||
delete step;
|
||||
delete test_ex;
|
||||
test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
test_ex = elab_and_eval(des, container, loop_test, -1, true);
|
||||
test = dynamic_cast<NetEConst*>(test_ex);
|
||||
assert(test);
|
||||
}
|
||||
|
|
@ -1728,6 +1663,10 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
<< "." << endl;
|
||||
}
|
||||
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, sc);
|
||||
|
||||
// Run through the module instances, and make scopes out of
|
||||
// them. Also do parameter overrides that are done on the
|
||||
// instantiation line.
|
||||
|
|
@ -1754,7 +1693,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
// Create the new scope as a MODULE with my name. Note
|
||||
// that if this is a nested module, mark it thus so that
|
||||
// scope searches will continue into the parent scope.
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE,
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE, 0,
|
||||
bound_type_? true : false,
|
||||
mod->program_block,
|
||||
mod->is_interface);
|
||||
|
|
@ -1762,6 +1701,9 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
get_lineno(), mod->get_lineno());
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
|
||||
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
|
||||
my_scope->attribute(attrib_list[adx].key, attrib_list[adx].val);
|
||||
|
||||
instances[idx] = my_scope;
|
||||
|
||||
set_scope_timescale(des, my_scope, mod);
|
||||
|
|
@ -1820,6 +1762,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
mod->elaborate_scope(des, my_scope, replace);
|
||||
|
||||
}
|
||||
delete[]attrib_list;
|
||||
|
||||
/* Stash the instance array of scopes into the parent
|
||||
scope. Later elaboration passes will use this vector to
|
||||
|
|
|
|||
26
elab_sig.cc
26
elab_sig.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -1333,27 +1333,3 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
return sig;
|
||||
}
|
||||
|
||||
|
||||
void Design::root_elaborate_sig(void)
|
||||
{
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur) {
|
||||
|
||||
netclass_t*cur_class = cur->second;
|
||||
PClass*cur_pclass = class_to_pclass_[cur_class];
|
||||
|
||||
cur_class->elaborate_sig(this, cur_pclass);
|
||||
}
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << cur->second->get_fileline() << ": root_elaborate_sig: "
|
||||
<< "Elaborate_sig for root task/func " << scope_path(cur->first) << endl;
|
||||
}
|
||||
|
||||
cur->second->elaborate_sig(this, cur->first);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
elab_type.cc
13
elab_type.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2017 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
|
||||
|
|
@ -78,9 +78,8 @@ static void elaborate_array_ranges(Design*des, NetScope*scope,
|
|||
*/
|
||||
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
|
||||
{
|
||||
ivl_assert(*this, scope);
|
||||
Definitions*use_definitions = scope;
|
||||
if (use_definitions == 0)
|
||||
use_definitions = des;
|
||||
|
||||
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
||||
if (pos != cache_type_elaborate_.end() && pos->first == use_definitions)
|
||||
|
|
@ -147,13 +146,13 @@ ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*) const
|
|||
* available at the right time. At that time, the netenum_t* object is
|
||||
* stashed in the scope so that I can retrieve it here.
|
||||
*/
|
||||
ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
ivl_type_s* enum_type_t::elaborate_type_raw(Design*, NetScope*scope) const
|
||||
{
|
||||
ivl_assert(*this, scope);
|
||||
ivl_type_s*tmp = scope->enumeration_for_key(this);
|
||||
if (tmp) return tmp;
|
||||
|
||||
tmp = des->enumeration_for_key(this);
|
||||
if (tmp == 0 && scope->unit()) {
|
||||
tmp = scope->unit()->enumeration_for_key(this);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
|
|
|||
478
elaborate.cc
478
elaborate.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -2204,8 +2204,10 @@ void PGModule::elaborate(Design*des, NetScope*scope) const
|
|||
return;
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": internal error: Unknown module type: " <<
|
||||
type_ << endl;
|
||||
if (!ignore_missing_modules) {
|
||||
cerr << get_fileline() << ": internal error: Unknown module type: " <<
|
||||
type_ << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void PGModule::elaborate_scope(Design*des, NetScope*sc) const
|
||||
|
|
@ -2249,9 +2251,11 @@ void PGModule::elaborate_scope(Design*des, NetScope*sc) const
|
|||
|
||||
// Not a module or primitive that I know about or can find by
|
||||
// any means, so give up.
|
||||
cerr << get_fileline() << ": error: Unknown module type: " << type_ << endl;
|
||||
missing_modules[type_] += 1;
|
||||
des->errors += 1;
|
||||
if (!ignore_missing_modules) {
|
||||
cerr << get_fileline() << ": error: Unknown module type: " << type_ << endl;
|
||||
missing_modules[type_] += 1;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2351,19 +2355,7 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
|
|||
{
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
check_for_inconsistent_delays(scope);
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
|
|
@ -2914,11 +2906,12 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
|
|||
if (nscope == 0)
|
||||
nscope = scope;
|
||||
|
||||
// Handle the special case that the block contains only one
|
||||
// statement. There is no need to keep the block node. Also,
|
||||
// don't elide named blocks, because they might be referenced
|
||||
// elsewhere.
|
||||
if ((list_.size() == 1) && (pscope_name() == 0)) {
|
||||
// Handle the special case that the sequential block contains
|
||||
// only one statement. There is no need to keep the block node.
|
||||
// Also, don't elide named blocks, because they might be
|
||||
// referenced elsewhere.
|
||||
if ((type == NetBlock::SEQU) && (list_.size() == 1) &&
|
||||
(pscope_name() == 0)) {
|
||||
assert(list_[0]);
|
||||
NetProc*tmp = list_[0]->elaborate(des, nscope);
|
||||
return tmp;
|
||||
|
|
@ -4198,6 +4191,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
|||
|
||||
NetEvent*ev = new NetEvent(scope->local_symbol());
|
||||
ev->set_line(*this);
|
||||
ev->local_flag(true);
|
||||
unsigned expr_count = 0;
|
||||
|
||||
NetEvWait*wa = new NetEvWait(enet);
|
||||
|
|
@ -4208,14 +4202,18 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
|||
|
||||
if (expr_.count() == 0) {
|
||||
assert(enet);
|
||||
/* For synthesis we want just the inputs, but for the rest we
|
||||
* want inputs and outputs that may cause a value to change. */
|
||||
/* For synthesis or always_comb/latch we want just the inputs,
|
||||
* but for the rest we want inputs and outputs that may cause
|
||||
* a value to change. */
|
||||
extern bool synthesis; /* Synthesis flag from main.cc */
|
||||
bool rem_out = false;
|
||||
if (synthesis) {
|
||||
if (synthesis || search_funcs_) {
|
||||
rem_out = true;
|
||||
}
|
||||
NexusSet*nset = enet->nex_input(rem_out);
|
||||
// If this is an always_comb/latch then we need an implicit T0
|
||||
// trigger of the event expression.
|
||||
if (search_funcs_) wa->set_t0_trigger();
|
||||
NexusSet*nset = enet->nex_input(rem_out, search_funcs_);
|
||||
if (nset == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to elaborate:"
|
||||
<< endl;
|
||||
|
|
@ -4474,6 +4472,8 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
|
|||
/* Create an event wait and an otherwise unreferenced
|
||||
event variable to force a perpetual wait. */
|
||||
NetEvent*wait_event = new NetEvent(scope->local_symbol());
|
||||
wait_event->set_line(*this);
|
||||
wait_event->local_flag(true);
|
||||
scope->add_event(wait_event);
|
||||
|
||||
NetEvWait*wait = new NetEvWait(0);
|
||||
|
|
@ -4494,6 +4494,8 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
|
|||
eval_expr(expr);
|
||||
|
||||
NetEvent*wait_event = new NetEvent(scope->local_symbol());
|
||||
wait_event->set_line(*this);
|
||||
wait_event->local_flag(true);
|
||||
scope->add_event(wait_event);
|
||||
|
||||
NetEvWait*wait = new NetEvWait(0 /* noop */);
|
||||
|
|
@ -5364,7 +5366,10 @@ bool PProcess::elaborate(Design*des, NetScope*scope) const
|
|||
gets into its wait statement before non-combinational
|
||||
code is executed. */
|
||||
do {
|
||||
if (top->type() != IVL_PR_ALWAYS)
|
||||
if ((top->type() != IVL_PR_ALWAYS) &&
|
||||
(top->type() != IVL_PR_ALWAYS_COMB) &&
|
||||
(top->type() != IVL_PR_ALWAYS_FF) &&
|
||||
(top->type() != IVL_PR_ALWAYS_LATCH))
|
||||
break;
|
||||
|
||||
NetEvWait*st = dynamic_cast<NetEvWait*>(top->statement());
|
||||
|
|
@ -5411,19 +5416,7 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
|
|||
ndelays = delays.size();
|
||||
if (ndelays > 12) ndelays = 12;
|
||||
|
||||
/* Print a warning if we find default and `timescale based
|
||||
* delays in the design, since this is likely an error. */
|
||||
if (scope->time_from_timescale()) dly_used_timescale = true;
|
||||
else dly_used_no_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
dly_used_no_timescale && dly_used_timescale) {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
check_for_inconsistent_delays(scope);
|
||||
|
||||
/* Elaborate the delay values themselves. Remember to scale
|
||||
them for the timescale/precision of the scope. */
|
||||
|
|
@ -5691,6 +5684,10 @@ bool PPackage::elaborate(Design*des, NetScope*scope) const
|
|||
// Elaborate class definitions.
|
||||
elaborate_classes(des, scope, classes);
|
||||
|
||||
// Elaborate the variable initialization statements, making a
|
||||
// single initial process out of them.
|
||||
result_flag &= elaborate_var_inits_(des, scope);
|
||||
|
||||
return result_flag;
|
||||
}
|
||||
|
||||
|
|
@ -6123,14 +6120,17 @@ class later_defparams : public elaborator_work_item_t {
|
|||
|
||||
bool Design::check_proc_delay() const
|
||||
{
|
||||
bool result_flag = true;
|
||||
bool result = false;
|
||||
|
||||
for (const NetProcTop*pr = procs_ ; pr ; pr = pr->next_) {
|
||||
/* If this is an always block and we have no or zero delay then
|
||||
* a runtime infinite loop will happen. If we possible have some
|
||||
/* If this is an always process and we have no or zero delay then
|
||||
* a runtime infinite loop will happen. If we possibly have some
|
||||
* delay then print a warning that an infinite loop is possible.
|
||||
*/
|
||||
if (pr->type() == IVL_PR_ALWAYS) {
|
||||
if ((pr->type() == IVL_PR_ALWAYS) ||
|
||||
(pr->type() == IVL_PR_ALWAYS_COMB) ||
|
||||
(pr->type() == IVL_PR_ALWAYS_FF) ||
|
||||
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
|
||||
DelayType dly_type = pr->statement()->delay_type();
|
||||
|
||||
if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) {
|
||||
|
|
@ -6138,7 +6138,7 @@ bool Design::check_proc_delay() const
|
|||
<< " statement does not have any delay." << endl;
|
||||
cerr << pr->get_fileline() << ": : A runtime"
|
||||
<< " infinite loop will occur." << endl;
|
||||
result_flag = false;
|
||||
result = true;
|
||||
|
||||
} else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) {
|
||||
cerr << pr->get_fileline() << ": warning: always"
|
||||
|
|
@ -6146,6 +6146,38 @@ bool Design::check_proc_delay() const
|
|||
cerr << pr->get_fileline() << ": : A runtime"
|
||||
<< " infinite loop may be possible." << endl;
|
||||
}
|
||||
|
||||
// The always_comb/ff/latch processes also have special
|
||||
// delay rules that need to be checked.
|
||||
if ((pr->type() == IVL_PR_ALWAYS_COMB) ||
|
||||
(pr->type() == IVL_PR_ALWAYS_FF) ||
|
||||
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
|
||||
const NetEvWait *wait = dynamic_cast<const NetEvWait*> (pr->statement());
|
||||
if (! wait) {
|
||||
// The always_comb/latch processes have an event
|
||||
// control added automatically by the compiler.
|
||||
assert(pr->type() == IVL_PR_ALWAYS_FF);
|
||||
cerr << pr->get_fileline() << ": error: the "
|
||||
<< "first statement of an always_ff must "
|
||||
<< "be an event control." << endl;
|
||||
result = true;
|
||||
} else if (wait->statement()->delay_type(true) != NO_DELAY) {
|
||||
cerr << pr->get_fileline() << ": error: there "
|
||||
<< "must ";
|
||||
|
||||
if (pr->type() == IVL_PR_ALWAYS_FF) {
|
||||
cerr << "only be a single event control "
|
||||
<< "and no blocking delays in an "
|
||||
<< "always_ff process.";
|
||||
} else {
|
||||
cerr << "be no event controls or blocking "
|
||||
<< "delays in an always_comb/latch "
|
||||
<< "process.";
|
||||
}
|
||||
cerr << endl;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a final block it must not have a delay,
|
||||
|
|
@ -6155,37 +6187,287 @@ bool Design::check_proc_delay() const
|
|||
if (pr->type() == IVL_PR_FINAL) {
|
||||
DelayType dly_type = pr->statement()->delay_type();
|
||||
|
||||
if (dly_type != NO_DELAY && dly_type != ZERO_DELAY) {
|
||||
if (dly_type != NO_DELAY) {
|
||||
cerr << pr->get_fileline() << ": error: final"
|
||||
<< " statement contains a delay." << endl;
|
||||
result_flag = false;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result_flag;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Design::root_elaborate(void)
|
||||
static void print_nexus_name(const Nexus*nex)
|
||||
{
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur) {
|
||||
netclass_t*cur_class = cur->second;
|
||||
PClass*cur_pclass = class_to_pclass_[cur_class];
|
||||
cur_class->elaborate(this, cur_pclass);
|
||||
}
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << cur->second->get_fileline() << ": Design::root_elaborate: "
|
||||
<< "Elaborate for root task/func " << scope_path(cur->first) << endl;
|
||||
for (const Link*cur = nex->first_nlink(); cur; cur = cur->next_nlink()) {
|
||||
if (cur->get_dir() != Link::OUTPUT) continue;
|
||||
const NetPins*obj = cur->get_obj();
|
||||
// For a NetNet (signal) just use the name.
|
||||
if (const NetNet*net = dynamic_cast<const NetNet*>(obj)) {
|
||||
cerr << net->name();
|
||||
return;
|
||||
// For a NetPartSelect calculate the name.
|
||||
} else if (const NetPartSelect*ps = dynamic_cast<const NetPartSelect*>(obj)) {
|
||||
assert(ps->pin_count() >= 2);
|
||||
assert(ps->pin(1).get_dir() == Link::INPUT);
|
||||
assert(ps->pin(1).is_linked());
|
||||
print_nexus_name(ps->pin(1).nexus());
|
||||
cerr << "[]";
|
||||
return;
|
||||
// For a NetUReduce calculate the name.
|
||||
} else if (const NetUReduce*reduce = dynamic_cast<const NetUReduce*>(obj)) {
|
||||
assert(reduce->pin_count() == 2);
|
||||
assert(reduce->pin(1).get_dir() == Link::INPUT);
|
||||
assert(reduce->pin(1).is_linked());
|
||||
switch (reduce->type()) {
|
||||
case NetUReduce::AND:
|
||||
cerr << "&";
|
||||
break;
|
||||
case NetUReduce::OR:
|
||||
cerr << "|";
|
||||
break;
|
||||
case NetUReduce::XOR:
|
||||
cerr << "^";
|
||||
break;
|
||||
case NetUReduce::NAND:
|
||||
cerr << "~&";
|
||||
break;
|
||||
case NetUReduce::NOR:
|
||||
cerr << "~|";
|
||||
break;
|
||||
case NetUReduce::XNOR:
|
||||
cerr << "~^";
|
||||
break;
|
||||
case NetUReduce::NONE:
|
||||
assert(0);
|
||||
}
|
||||
print_nexus_name(reduce->pin(1).nexus());
|
||||
return;
|
||||
} else if (const NetLogic*logic = dynamic_cast<const NetLogic*>(obj)) {
|
||||
assert(logic->pin_count() >= 2);
|
||||
assert(logic->pin(1).get_dir() == Link::INPUT);
|
||||
assert(logic->pin(1).is_linked());
|
||||
switch (logic->type()) {
|
||||
case NetLogic::NOT:
|
||||
cerr << "~";
|
||||
break;
|
||||
default:
|
||||
// The other operators should never be used here,
|
||||
// so just return the nexus name.
|
||||
cerr << nex->name();
|
||||
return;
|
||||
}
|
||||
print_nexus_name(logic->pin(1).nexus());
|
||||
return;
|
||||
}
|
||||
// Use the following to find the type of anything that may be missing:
|
||||
// cerr << "(" << typeid(*obj).name() << ") ";
|
||||
}
|
||||
// Otherwise just use the nexus name so somthing is printed.
|
||||
cerr << nex->name();
|
||||
}
|
||||
|
||||
cur->second->elaborate(this, cur->first);
|
||||
static void print_event_probe_name(const NetEvProbe *prb)
|
||||
{
|
||||
assert(prb->pin_count() == 1);
|
||||
assert(prb->pin(0).get_dir() == Link::INPUT);
|
||||
assert(prb->pin(0).is_linked());
|
||||
print_nexus_name(prb->pin(0).nexus());
|
||||
}
|
||||
|
||||
static void check_event_probe_width(const LineInfo *info, const NetEvProbe *prb)
|
||||
{
|
||||
assert(prb->pin_count() == 1);
|
||||
assert(prb->pin(0).get_dir() == Link::INPUT);
|
||||
assert(prb->pin(0).is_linked());
|
||||
if (prb->edge() == NetEvProbe::ANYEDGE) return;
|
||||
if (prb->pin(0).nexus()->vector_width() > 1) {
|
||||
cerr << info->get_fileline() << " Warning: Synthesis wants "
|
||||
"the sensitivity list expressions for '";
|
||||
switch (prb->edge()) {
|
||||
case NetEvProbe::POSEDGE:
|
||||
cerr << "posedge ";
|
||||
break;
|
||||
case NetEvProbe::NEGEDGE:
|
||||
cerr << "negedge ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
print_nexus_name(prb->pin(0).nexus());
|
||||
cerr << "' to be a single bit." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void check_ff_sensitivity(const NetProc* statement)
|
||||
{
|
||||
const NetEvWait *evwt = dynamic_cast<const NetEvWait*> (statement);
|
||||
// We have already checked for and reported if the first statmemnt is
|
||||
// not a wait.
|
||||
if (! evwt) return;
|
||||
|
||||
for (unsigned cevt = 0; cevt < evwt->nevents(); cevt += 1) {
|
||||
const NetEvent *evt = evwt->event(cevt);
|
||||
for (unsigned cprb = 0; cprb < evt->nprobe(); cprb += 1) {
|
||||
const NetEvProbe *prb = evt->probe(cprb);
|
||||
check_event_probe_width(evwt, prb);
|
||||
if (prb->edge() == NetEvProbe::ANYEDGE) {
|
||||
cerr << evwt->get_fileline() << " Warning: Synthesis "
|
||||
"requires the sensitivity list of an "
|
||||
"always_ff process to only be edge "
|
||||
"sensitive. ";
|
||||
print_event_probe_name(prb);
|
||||
cerr << " is missing a pos/negedge." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if the always_* processes only contain synthesizable
|
||||
* constructs.
|
||||
*/
|
||||
bool Design::check_proc_synth() const
|
||||
{
|
||||
bool result = false;
|
||||
for (const NetProcTop*pr = procs_ ; pr ; pr = pr->next_) {
|
||||
if ((pr->type() == IVL_PR_ALWAYS_COMB) ||
|
||||
(pr->type() == IVL_PR_ALWAYS_FF) ||
|
||||
(pr->type() == IVL_PR_ALWAYS_LATCH)) {
|
||||
result |= pr->statement()->check_synth(pr->type(),
|
||||
pr->scope());
|
||||
if (pr->type() == IVL_PR_ALWAYS_FF) {
|
||||
check_ff_sensitivity(pr->statement());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether all design elements have an explicit timescale or all
|
||||
* design elements use the default timescale. If a mixture of explicit
|
||||
* and default timescales is found, a warning message is output. Note
|
||||
* that we only need to check the top level design elements - nested
|
||||
* design elements will always inherit the timescale from their parent
|
||||
* if they don't have any local timescale declarations.
|
||||
*
|
||||
* NOTE: Strictly speaking, this should be an error for SystemVerilog
|
||||
* (1800-2012 section 3.14.2).
|
||||
*/
|
||||
static void check_timescales(bool&some_explicit, bool&some_implicit,
|
||||
const PScope*scope)
|
||||
{
|
||||
if (scope->time_unit_is_default)
|
||||
some_implicit = true;
|
||||
else
|
||||
some_explicit = true;
|
||||
if (scope->time_prec_is_default)
|
||||
some_implicit = true;
|
||||
else
|
||||
some_explicit = true;
|
||||
}
|
||||
|
||||
static void check_timescales()
|
||||
{
|
||||
bool some_explicit = false;
|
||||
bool some_implicit = false;
|
||||
map<perm_string,Module*>::iterator mod;
|
||||
for (mod = pform_modules.begin(); mod != pform_modules.end(); ++mod) {
|
||||
const Module*mp = (*mod).second;
|
||||
check_timescales(some_explicit, some_implicit, mp);
|
||||
if (some_explicit && some_implicit)
|
||||
break;
|
||||
}
|
||||
map<perm_string,PPackage*>::iterator pkg;
|
||||
if (gn_system_verilog() && !(some_explicit && some_implicit)) {
|
||||
for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) {
|
||||
const PPackage*pp = (*pkg).second;
|
||||
check_timescales(some_explicit, some_implicit, pp);
|
||||
if (some_explicit && some_implicit)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gn_system_verilog() && !(some_explicit && some_implicit)) {
|
||||
for (unsigned idx = 0; idx < pform_units.size(); idx += 1) {
|
||||
const PPackage*pp = pform_units[idx];
|
||||
// We don't need a timescale if the compilation unit
|
||||
// contains no items outside a design element.
|
||||
if (pp->parameters.empty() &&
|
||||
pp->localparams.empty() &&
|
||||
pp->wires.empty() &&
|
||||
pp->tasks.empty() &&
|
||||
pp->funcs.empty() &&
|
||||
pp->classes.empty())
|
||||
continue;
|
||||
|
||||
check_timescales(some_explicit, some_implicit, pp);
|
||||
if (some_explicit && some_implicit)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(some_explicit && some_implicit))
|
||||
return;
|
||||
|
||||
if (gn_system_verilog()) {
|
||||
cerr << "warning: "
|
||||
<< "Some design elements have no explicit time unit and/or"
|
||||
<< endl;
|
||||
cerr << " : "
|
||||
<< "time precision. This may cause confusing timing results."
|
||||
<< endl;
|
||||
cerr << " : "
|
||||
<< "Affected design elements are:"
|
||||
<< endl;
|
||||
} else {
|
||||
cerr << "warning: "
|
||||
<< "Some modules have no timescale. This may cause"
|
||||
<< endl;
|
||||
cerr << " : "
|
||||
<< "confusing timing results. Affected modules are:"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
for (mod = pform_modules.begin(); mod != pform_modules.end(); ++mod) {
|
||||
Module*mp = (*mod).second;
|
||||
if (mp->has_explicit_timescale())
|
||||
continue;
|
||||
cerr << " : -- module " << (*mod).first
|
||||
<< " declared here: " << mp->get_fileline() << endl;
|
||||
}
|
||||
|
||||
if (!gn_system_verilog())
|
||||
return;
|
||||
|
||||
for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) {
|
||||
PPackage*pp = (*pkg).second;
|
||||
if (pp->has_explicit_timescale())
|
||||
continue;
|
||||
cerr << " : -- package " << (*pkg).first
|
||||
<< " declared here: " << pp->get_fileline() << endl;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0; idx < pform_units.size(); idx += 1) {
|
||||
PPackage*pp = pform_units[idx];
|
||||
if (pp->has_explicit_timescale())
|
||||
continue;
|
||||
|
||||
if (pp->parameters.empty() &&
|
||||
pp->localparams.empty() &&
|
||||
pp->wires.empty() &&
|
||||
pp->tasks.empty() &&
|
||||
pp->funcs.empty() &&
|
||||
pp->classes.empty())
|
||||
continue;
|
||||
|
||||
cerr << " : -- compilation unit";
|
||||
if (pform_units.size() > 1) {
|
||||
cerr << " from: " << pp->get_file();
|
||||
}
|
||||
cerr << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -6207,8 +6489,13 @@ struct root_elem {
|
|||
|
||||
Design* elaborate(list<perm_string>roots)
|
||||
{
|
||||
unsigned npackages = pform_packages.size();
|
||||
if (gn_system_verilog())
|
||||
npackages += pform_units.size();
|
||||
|
||||
vector<struct root_elem> root_elems(roots.size());
|
||||
vector<struct pack_elem> pack_elems(pform_packages.size());
|
||||
vector<struct pack_elem> pack_elems(npackages);
|
||||
map<LexicalScope*,NetScope*> unit_scopes;
|
||||
bool rc = true;
|
||||
unsigned i = 0;
|
||||
|
||||
|
|
@ -6216,23 +6503,36 @@ Design* elaborate(list<perm_string>roots)
|
|||
// module and elaborate what I find.
|
||||
Design*des = new Design;
|
||||
|
||||
// Elaborate enum sets in $root scope.
|
||||
elaborate_rootscope_enumerations(des);
|
||||
// Elaborate the compilation unit scopes. From here on, these are
|
||||
// treated as an additional set of packages.
|
||||
if (gn_system_verilog()) {
|
||||
for (i = 0; i < pform_units.size(); i += 1) {
|
||||
PPackage*unit = pform_units[i];
|
||||
NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true);
|
||||
scope->set_line(unit);
|
||||
set_scope_timescale(des, scope, unit);
|
||||
|
||||
// Elaborate tasks and functions in $root scope.
|
||||
elaborate_rootscope_tasks(des);
|
||||
elaborator_work_item_t*es = new elaborate_package_t(des, scope, unit);
|
||||
des->elaboration_work_list.push_back(es);
|
||||
|
||||
// Elaborate classes in $root scope.
|
||||
elaborate_rootscope_classes(des);
|
||||
pack_elems[i].pack = unit;
|
||||
pack_elems[i].scope = scope;
|
||||
|
||||
unit_scopes[unit] = scope;
|
||||
}
|
||||
}
|
||||
|
||||
// Elaborate the packages. Package elaboration is simpler
|
||||
// because there are fewer sub-scopes involved.
|
||||
i = 0;
|
||||
// because there are fewer sub-scopes involved. Note that
|
||||
// in SystemVerilog, packages are not allowed to refer to
|
||||
// the compilation unit scope, but the VHDL preprocessor
|
||||
// assumes they can.
|
||||
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
||||
; pac != pform_packages.end() ; ++ pac) {
|
||||
|
||||
ivl_assert(*pac->second, pac->first == pac->second->pscope_name());
|
||||
NetScope*scope = des->make_package_scope(pac->first);
|
||||
NetScope*unit_scope = unit_scopes[pac->second->parent_scope()];
|
||||
NetScope*scope = des->make_package_scope(pac->first, unit_scope, false);
|
||||
scope->set_line(pac->second);
|
||||
set_scope_timescale(des, scope, pac->second);
|
||||
|
||||
|
|
@ -6263,9 +6563,13 @@ Design* elaborate(list<perm_string>roots)
|
|||
// Get the module definition for this root instance.
|
||||
Module *rmod = (*mod).second;
|
||||
|
||||
// Get the compilation unit scope for this module.
|
||||
NetScope*unit_scope = unit_scopes[rmod->parent_scope()];
|
||||
|
||||
// Make the root scope. This makes a NetScope object and
|
||||
// pushes it into the list of root scopes in the Design.
|
||||
NetScope*scope = des->make_root_scope(*root, rmod->program_block,
|
||||
NetScope*scope = des->make_root_scope(*root, unit_scope,
|
||||
rmod->program_block,
|
||||
rmod->is_interface);
|
||||
|
||||
// Collect some basic properties of this scope from the
|
||||
|
|
@ -6335,6 +6639,10 @@ Design* elaborate(list<perm_string>roots)
|
|||
if (des->errors > 0)
|
||||
return des;
|
||||
|
||||
// Now we have the full design, check for timescale inconsistencies.
|
||||
if (warn_timescale)
|
||||
check_timescales();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>: elaborate: "
|
||||
<< "Start calling Package elaborate_sig methods." << endl;
|
||||
|
|
@ -6363,8 +6671,6 @@ Design* elaborate(list<perm_string>roots)
|
|||
<< "Start calling $root elaborate_sig methods." << endl;
|
||||
}
|
||||
|
||||
des->root_elaborate_sig();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>: elaborate: "
|
||||
<< "Start calling root module elaborate_sig methods." << endl;
|
||||
|
|
@ -6426,8 +6732,6 @@ Design* elaborate(list<perm_string>roots)
|
|||
rc &= pkg->elaborate(des, scope);
|
||||
}
|
||||
|
||||
des->root_elaborate();
|
||||
|
||||
for (i = 0; i < root_elems.size(); i++) {
|
||||
Module *rmod = root_elems[i].mod;
|
||||
NetScope *scope = root_elems[i].scope;
|
||||
|
|
@ -6442,10 +6746,11 @@ Design* elaborate(list<perm_string>roots)
|
|||
// Now that everything is fully elaborated verify that we do
|
||||
// not have an always block with no delay (an infinite loop),
|
||||
// or a final block with a delay.
|
||||
if (des->check_proc_delay() == false) {
|
||||
delete des;
|
||||
des = 0;
|
||||
}
|
||||
bool has_failure = des->check_proc_delay();
|
||||
|
||||
// Check to see if the always_comb/ff/latch processes only have
|
||||
// synthesizable constructs
|
||||
has_failure |= des->check_proc_synth();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: "
|
||||
|
|
@ -6453,5 +6758,10 @@ Design* elaborate(list<perm_string>roots)
|
|||
<< des->find_root_scopes().size() << " root scopes " << endl;
|
||||
}
|
||||
|
||||
if (has_failure) {
|
||||
delete des;
|
||||
des = 0;
|
||||
}
|
||||
|
||||
return des;
|
||||
}
|
||||
|
|
|
|||
20
emit.cc
20
emit.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -510,24 +510,12 @@ int Design::emit(struct target_t*tgt) const
|
|||
if (tgt->start_design(this) == false)
|
||||
return -2;
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
|
||||
; scope != root_tasks_.end() ; ++ scope) {
|
||||
scope->first->emit_scope(tgt);
|
||||
}
|
||||
|
||||
// enumerate package scopes
|
||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||
; scope != packages_.end() ; ++ scope) {
|
||||
scope->second->emit_scope(tgt);
|
||||
}
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
const NetScope*use_scope = cur->second->class_scope();
|
||||
cur->second->emit_scope(tgt);
|
||||
tgt->class_type(use_scope, cur->second);
|
||||
}
|
||||
|
||||
// enumerate root scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); ++ scope ) {
|
||||
|
|
@ -552,12 +540,6 @@ int Design::emit(struct target_t*tgt) const
|
|||
|
||||
// emit task and function definitions
|
||||
bool tasks_rc = true;
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
|
||||
; scope != root_tasks_.end() ; ++ scope)
|
||||
tasks_rc &= scope->first->emit_defs(tgt);
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur)
|
||||
tasks_rc &= cur->second->emit_defs(tgt);
|
||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||
; scope != packages_.end() ; ++ scope )
|
||||
tasks_rc &= scope->second->emit_defs(tgt);
|
||||
|
|
|
|||
390
eval_tree.cc
390
eval_tree.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2018 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
|
||||
|
|
@ -570,11 +570,11 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*r
|
|||
const verinum::V ne_res = ne_flag? verinum::V1 : verinum::V0;
|
||||
|
||||
verinum::V res = eq_res;
|
||||
unsigned top = lv.len();
|
||||
if (rv.len() < top)
|
||||
top = rv.len();
|
||||
|
||||
for (unsigned idx = 0 ; idx < top ; idx += 1) {
|
||||
// The two expressions should already be padded to the same size.
|
||||
ivl_assert(*this, lv.len() == rv.len());
|
||||
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) {
|
||||
|
||||
bool x_bit_present = false;
|
||||
|
||||
|
|
@ -611,60 +611,6 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*r
|
|||
}
|
||||
}
|
||||
|
||||
if (res != verinum::Vx) {
|
||||
verinum::V lpad = verinum::V0;
|
||||
verinum::V rpad = verinum::V0;
|
||||
|
||||
if (lv.has_sign() && lv.get(lv.len()-1) == verinum::V1)
|
||||
lpad = verinum::V1;
|
||||
if (rv.has_sign() && rv.get(rv.len()-1) == verinum::V1)
|
||||
rpad = verinum::V1;
|
||||
|
||||
for (unsigned idx = top ; idx < lv.len() ; idx += 1)
|
||||
switch (lv.get(idx)) {
|
||||
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
res = verinum::Vx;
|
||||
break;
|
||||
|
||||
case verinum::V0:
|
||||
if (res != verinum::Vx && rpad != verinum::V0)
|
||||
res = ne_res;
|
||||
break;
|
||||
|
||||
case verinum::V1:
|
||||
if (res != verinum::Vx && rpad != verinum::V1)
|
||||
res = ne_res;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned idx = top ; idx < rv.len() ; idx += 1)
|
||||
switch (rv.get(idx)) {
|
||||
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
res = verinum::Vx;
|
||||
break;
|
||||
|
||||
case verinum::V0:
|
||||
if (res != verinum::Vx && lpad != verinum::V0)
|
||||
res = ne_res;
|
||||
break;
|
||||
|
||||
case verinum::V1:
|
||||
if (res != verinum::Vx && lpad != verinum::V1)
|
||||
res = ne_res;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NetEConst*result = new NetEConst(verinum(res, 1));
|
||||
ivl_assert(*this, result);
|
||||
return result;
|
||||
|
|
@ -681,46 +627,15 @@ NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr
|
|||
|
||||
verinum::V res = verinum::V1;
|
||||
|
||||
// Find the smallest argument length.
|
||||
unsigned cnt = lv.len();
|
||||
if (cnt > rv.len()) cnt = rv.len();
|
||||
// The two expressions should already be padded to the same size.
|
||||
ivl_assert(*this, lv.len() == rv.len());
|
||||
|
||||
// Check the common bits.
|
||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1)
|
||||
if (lv.get(idx) != rv.get(idx)) {
|
||||
res = verinum::V0;
|
||||
break;
|
||||
}
|
||||
|
||||
bool is_signed = lv.has_sign() && rv.has_sign();
|
||||
|
||||
// If the left value is longer check it against the pad bit.
|
||||
if (res == verinum::V1) {
|
||||
verinum::V pad = verinum::V0;
|
||||
if (is_signed)
|
||||
pad = rv.get(rv.len()-1);
|
||||
|
||||
for (unsigned idx = cnt ; idx < lv.len() ; idx += 1)
|
||||
if (lv.get(idx) != pad) {
|
||||
res = verinum::V0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the right value is longer check it against the pad bit.
|
||||
if (res == verinum::V1) {
|
||||
verinum::V pad = verinum::V0;
|
||||
if (is_signed)
|
||||
pad = lv.get(lv.len()-1);
|
||||
|
||||
for (unsigned idx = cnt ; idx < rv.len() ; idx += 1) {
|
||||
if (rv.get(idx) != pad) {
|
||||
res = verinum::V0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ne_flag) {
|
||||
if (res == verinum::V0) res = verinum::V1;
|
||||
else res = verinum::V0;
|
||||
|
|
@ -731,6 +646,55 @@ NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr
|
|||
return result;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_weqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(le);
|
||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(re);
|
||||
if (lc == 0 || rc == 0) return 0;
|
||||
|
||||
const verinum&lv = lc->value();
|
||||
const verinum&rv = rc->value();
|
||||
|
||||
const verinum::V eq_res = ne_flag ? verinum::V0 : verinum::V1;
|
||||
const verinum::V ne_res = ne_flag ? verinum::V1 : verinum::V0;
|
||||
|
||||
verinum::V res = eq_res;
|
||||
|
||||
// The two expressions should already be padded to the same size.
|
||||
ivl_assert(*this, lv.len() == rv.len());
|
||||
|
||||
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) {
|
||||
// An X or Z in the R-value matches any L-value.
|
||||
switch (rv.get(idx)) {
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// An X or Z in the L-value that is not matches by an R-value X/Z returns undefined.
|
||||
switch (lv.get(idx)) {
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
res = verinum::Vx;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// A hard (0/1) mismatch gives a not-equal result.
|
||||
if (rv.get(idx) != lv.get(idx)) {
|
||||
res = ne_res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NetEConst*result = new NetEConst(verinum(res, 1));
|
||||
ivl_assert(*this, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
NetEConst*res = 0;
|
||||
|
|
@ -744,6 +708,10 @@ NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
|||
res = eval_eqeq_(false, l, r);
|
||||
break;
|
||||
|
||||
case 'w': // Wild equality (==?)
|
||||
res = eval_weqeq_(false, l, r);
|
||||
break;
|
||||
|
||||
case 'G': // >=
|
||||
res = eval_gteq_(l, r);
|
||||
break;
|
||||
|
|
@ -760,6 +728,10 @@ NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
|||
res = eval_eqeq_(true, l, r);
|
||||
break;
|
||||
|
||||
case 'W': // Wild not-equal (!=?)
|
||||
res = eval_weqeq_(true, l, r);
|
||||
break;
|
||||
|
||||
case '<': // Less than
|
||||
res = eval_less_(l, r);
|
||||
break;
|
||||
|
|
@ -1102,6 +1074,7 @@ NetEConst* NetEBShift::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
|||
break;
|
||||
case 'r':
|
||||
lv.has_sign(false);
|
||||
// fallthrough
|
||||
case 'R':
|
||||
val = cast_to_width(lv >> shift, wid);
|
||||
break;
|
||||
|
|
@ -1553,6 +1526,7 @@ NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const
|
|||
|
||||
case 'A':
|
||||
invert = true;
|
||||
// fallthrough
|
||||
case '&': {
|
||||
res = verinum::V1;
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
|
|
@ -1562,6 +1536,7 @@ NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const
|
|||
|
||||
case 'N':
|
||||
invert = true;
|
||||
// fallthrough
|
||||
case '|': {
|
||||
res = verinum::V0;
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
|
|
@ -1571,6 +1546,7 @@ NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const
|
|||
|
||||
case 'X':
|
||||
invert = true;
|
||||
// fallthrough
|
||||
case '^': {
|
||||
/* Reduction XOR. */
|
||||
unsigned ones = 0, unknown = 0;
|
||||
|
|
@ -1622,6 +1598,7 @@ NetExpr* NetECast::eval_arguments_(const NetExpr*ex) const
|
|||
res_val = cast_to_width(res_val, expr_width());
|
||||
res = new NetEConst(res_val);
|
||||
}
|
||||
// fallthrough
|
||||
case 'v':
|
||||
if (const NetECReal*val = dynamic_cast<const NetECReal*>(ex)) {
|
||||
verinum res_val(val->value().as_double(), false);
|
||||
|
|
@ -1936,15 +1913,111 @@ NetExpr* NetESFunc::evaluate_min_max_(ID id, const NetExpr*arg0_,
|
|||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_countbits_(const NetExpr* /*arg0*/,
|
||||
const NetExpr* /*arg1*/) const
|
||||
static void no_string_arg(const NetESFunc*info, unsigned arg_num)
|
||||
{
|
||||
return 0;
|
||||
cerr << info->get_fileline() << ": error: constant function "
|
||||
<< info->name() << "() does not support a string argument ("
|
||||
<< arg_num+1 << ")." << endl;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_countones_(const NetExpr* /*arg*/) const
|
||||
NetEConst* NetESFunc::evaluate_countbits_() const
|
||||
{
|
||||
return 0;
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(parms_[0]);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find which values need to be counted. */
|
||||
bool count_0 = false;
|
||||
bool count_1 = false;
|
||||
bool count_z = false;
|
||||
bool count_x = false;
|
||||
for (unsigned arg=1; arg < parms_.size(); ++arg) {
|
||||
const NetEConst*argi = dynamic_cast<const NetEConst*>(parms_[arg]);
|
||||
if (! argi) return 0;
|
||||
verinum check_for = argi->value();
|
||||
if (check_for.is_string()) {
|
||||
no_string_arg(this, arg);
|
||||
return 0;
|
||||
}
|
||||
switch (check_for[0]) {
|
||||
case verinum::V0:
|
||||
count_0 = true;
|
||||
break;
|
||||
case verinum::V1:
|
||||
count_1 = true;
|
||||
break;
|
||||
case verinum::Vz:
|
||||
count_z = true;
|
||||
break;
|
||||
case verinum::Vx:
|
||||
count_x = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search each bit of the vector looking for the values to
|
||||
* be counted. */
|
||||
int count = 0;
|
||||
for (unsigned bit=0; bit < value.len(); ++bit) {
|
||||
switch (value[bit]) {
|
||||
case verinum::V0:
|
||||
if (count_0) ++count;
|
||||
break;
|
||||
case verinum::V1:
|
||||
if (count_1) ++count;
|
||||
break;
|
||||
case verinum::Vz:
|
||||
if (count_z) ++count;
|
||||
break;
|
||||
case verinum::Vx:
|
||||
if (count_x) ++count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
verinum tmp (count, integer_width);
|
||||
tmp.has_sign(true);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_countones_(const NetExpr* arg) const
|
||||
{
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
int count = 0;
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (unsigned bit=0; bit < value.len(); ++bit) {
|
||||
if (value[bit] == verinum::V1) ++count;
|
||||
}
|
||||
|
||||
verinum tmp (count, integer_width);
|
||||
tmp.has_sign(true);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Get the total number of dimensions for the given expression. */
|
||||
|
|
@ -1967,19 +2040,92 @@ NetEConst* NetESFunc::evaluate_dimensions_(const NetExpr*arg) const
|
|||
return new NetEConst(verinum(verinum(res), integer_width));
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_isunknown_(const NetExpr* /*arg*/) const
|
||||
NetEConst* NetESFunc::evaluate_isunknown_(const NetExpr* arg) const
|
||||
{
|
||||
return 0;
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
unsigned is_unknown = 1;
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (value.is_defined()) is_unknown = 0;
|
||||
|
||||
verinum tmp (is_unknown, 1U);
|
||||
tmp.has_sign(false);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_onehot_(const NetExpr* /*arg*/) const
|
||||
static bool is_onehot(verinum&value, bool zero_is_okay)
|
||||
{
|
||||
return 0;
|
||||
bool found_a_one = false;
|
||||
|
||||
for (unsigned bit=0; bit < value.len(); ++bit) {
|
||||
if (value[bit] == verinum::V1) {
|
||||
if (found_a_one) return false;
|
||||
found_a_one = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no one bit was found return true if zero is okay. */
|
||||
if (zero_is_okay) found_a_one = true;
|
||||
return found_a_one;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_onehot0_(const NetExpr* /*arg*/) const
|
||||
NetEConst* NetESFunc::evaluate_onehot_(const NetExpr* arg) const
|
||||
{
|
||||
return 0;
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum tmp (is_onehot(value, false), 1U);
|
||||
tmp.has_sign(false);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_onehot0_(const NetExpr* arg) const
|
||||
{
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
if (tmpi) {
|
||||
verinum value = tmpi->value();
|
||||
|
||||
if (value.is_string()) {
|
||||
no_string_arg(this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum tmp (is_onehot(value, true), 1U);
|
||||
tmp.has_sign(false);
|
||||
res = new NetEConst(tmp);
|
||||
ivl_assert(*this, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Get the number of unpacked dimensions for the given expression. */
|
||||
|
|
@ -2151,7 +2297,7 @@ NetExpr* NetESFunc::evaluate_two_arg_(ID id, const NetExpr*arg0,
|
|||
{
|
||||
switch (id) {
|
||||
case CTBITS:
|
||||
return evaluate_countbits_(arg0, arg1);
|
||||
return evaluate_countbits_();
|
||||
/* The array functions are handled together. */
|
||||
case HIGH:
|
||||
case INCR:
|
||||
|
|
@ -2222,12 +2368,12 @@ NetESFunc::ID NetESFunc::built_in_id_() const
|
|||
built_in_func["$unpacked_dimensions" ] = UPDIMS;
|
||||
}
|
||||
|
||||
/* These are available in 1800-2009 and later. */
|
||||
/* This is available in 1800-2009 and later. */
|
||||
if (funcs_need_init && (generation_flag >= GN_VER2009)) {
|
||||
built_in_func["$countones" ] = CTONES;
|
||||
}
|
||||
|
||||
/* These are available in 1800-2012 and later. */
|
||||
/* This is available in 1800-2012 and later. */
|
||||
if (funcs_need_init && (generation_flag >= GN_VER2012)) {
|
||||
built_in_func["$countbits" ] = CTBITS;
|
||||
}
|
||||
|
|
@ -2254,7 +2400,7 @@ NetESFunc::ID NetESFunc::built_in_id_() const
|
|||
|
||||
NetExpr* NetESFunc::eval_tree()
|
||||
{
|
||||
/* Get the ID for this system function if it is can be used as a
|
||||
/* Get the ID for this system function if it can be used as a
|
||||
* constant function. */
|
||||
ID id = built_in_id_();
|
||||
if (id == NOT_BUILT_IN) return 0;
|
||||
|
|
@ -2262,8 +2408,9 @@ NetExpr* NetESFunc::eval_tree()
|
|||
switch (parms_.size()) {
|
||||
case 1:
|
||||
if (! takes_nargs_(id, 1)) {
|
||||
cerr << get_fileline() << ": error: " << name_
|
||||
<< "() does not support a single argument." << endl;
|
||||
cerr << get_fileline() << ": error: constant function "
|
||||
<< name_ << "() does not support a single argument."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
eval_expr(parms_[0]);
|
||||
|
|
@ -2271,8 +2418,9 @@ NetExpr* NetESFunc::eval_tree()
|
|||
|
||||
case 2:
|
||||
if (! takes_nargs_(id, 2)) {
|
||||
cerr << get_fileline() << ": error: " << name_
|
||||
<< "() does not support two arguments." << endl;
|
||||
cerr << get_fileline() << ": error: constant function "
|
||||
<< name_ << "() does not support two arguments."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
eval_expr(parms_[0]);
|
||||
|
|
@ -2282,15 +2430,21 @@ NetExpr* NetESFunc::eval_tree()
|
|||
default:
|
||||
/* Check to see if the function was called correctly. */
|
||||
if (! takes_nargs_(id, parms_.size())) {
|
||||
cerr << get_fileline() << ": error: " << name_
|
||||
<< "() does not support " << parms_.size()
|
||||
cerr << get_fileline() << ": error: constant function "
|
||||
<< name_ << "() does not support " << parms_.size()
|
||||
<< " arguments." << endl;
|
||||
return 0;
|
||||
}
|
||||
// HERE: Need to add support for a multi argument $countbits().
|
||||
cerr << get_fileline() << ": sorry: functions with "
|
||||
<< parms_.size() << " arguments are not supported: "
|
||||
<< name_ << "()." << endl;
|
||||
if (id == CTBITS) {
|
||||
for (unsigned bit = 0; bit < parms_.size(); ++bit) {
|
||||
eval_expr(parms_[bit]);
|
||||
}
|
||||
return evaluate_countbits_();
|
||||
} else {
|
||||
cerr << get_fileline() << ": sorry: constant functions with "
|
||||
<< parms_.size() << " arguments are not supported: "
|
||||
<< name_ << "()." << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2018 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
|
||||
|
|
@ -274,7 +274,18 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
|
||||
if (op_ == 'E' || op_ == 'N') {
|
||||
NetCaseCmp*gate = new NetCaseCmp(scope, scope->local_symbol(),
|
||||
width, op_=='E'?NetCaseCmp::EEQ:NetCaseCmp::NEQ);
|
||||
width, op_=='E' ? NetCaseCmp::EEQ : NetCaseCmp::NEQ);
|
||||
gate->set_line(*this);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
connect(gate->pin(2), rsig->pin(0));
|
||||
des->add_node(gate);
|
||||
return osig;
|
||||
}
|
||||
|
||||
if (op_ == 'w' || op_ == 'W') {
|
||||
NetCaseCmp*gate = new NetCaseCmp(scope, scope->local_symbol(),
|
||||
width, op_=='w' ? NetCaseCmp::WEQ : NetCaseCmp::WNE);
|
||||
gate->set_line(*this);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
|
|
@ -335,6 +346,7 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
// fallthrough
|
||||
case 'e': // ==
|
||||
connect(dev->pin_AEB(), osig->pin(0));
|
||||
break;
|
||||
|
|
@ -353,6 +365,7 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
// fallthrough
|
||||
case 'n': // !=
|
||||
connect(dev->pin_ANEB(), osig->pin(0));
|
||||
break;
|
||||
|
|
@ -1347,6 +1360,7 @@ static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (nset && (nset->size() > 0)) {
|
||||
NetEvent*ev = new NetEvent(scope->local_symbol());
|
||||
ev->set_line(*root);
|
||||
ev->local_flag(true);
|
||||
|
||||
NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
|
||||
ev, NetEvProbe::ANYEDGE,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.TH iverilog-vpi 1 "May 10th, 2015" "" "Version %M.%n%E"
|
||||
.TH iverilog-vpi 1 "Jan 29th, 2017" "" "Version %M.%n%E"
|
||||
.SH NAME
|
||||
iverilog-vpi - Compile front end for VPI modules
|
||||
|
||||
|
|
@ -26,6 +26,11 @@ becomes \fIfoo.vpi\fP.
|
|||
Include the named library in the link of the VPI module. This allows
|
||||
VPI modules to further reference external libraries.
|
||||
|
||||
.TP 8
|
||||
.B -L\fIdirectory\fP
|
||||
Add \fIdirectory\fP to the list of directories that will be searched
|
||||
for library files.
|
||||
|
||||
.TP 8
|
||||
.B -I\fIdirectory\fP
|
||||
Add \fIdirectory\fP to the list of directories that will be searched
|
||||
|
|
@ -115,7 +120,7 @@ iverilog(1), vvp(1),
|
|||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2015 Stephen Williams
|
||||
Copyright \(co 2002\-2017 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ CCSRC=
|
|||
CXSRC=
|
||||
OBJ=
|
||||
LIB=
|
||||
LIBDIR=
|
||||
OUT=
|
||||
INCOPT=
|
||||
DEFS=
|
||||
|
|
@ -81,6 +82,9 @@ do
|
|||
-l*) LIB="$LIB $parm"
|
||||
;;
|
||||
|
||||
-L*) LIBDIR="$LIBDIR $parm"
|
||||
;;
|
||||
|
||||
-I*) INCOPT="$INCOPT $parm"
|
||||
;;
|
||||
|
||||
|
|
@ -92,6 +96,11 @@ do
|
|||
exit;
|
||||
;;
|
||||
|
||||
--ccflags)
|
||||
echo "$CXXFLAGS"
|
||||
exit;
|
||||
;;
|
||||
|
||||
--ldflags)
|
||||
echo "$LDFLAGS"
|
||||
exit;
|
||||
|
|
@ -148,4 +157,4 @@ then
|
|||
fi
|
||||
|
||||
echo "Making $OUT from $OBJ..."
|
||||
exec $LD -o $OUT $LDFLAGS $OBJ $LIB $LDLIBS
|
||||
exec $LD -o $OUT $LDFLAGS $LIBDIR $OBJ $LIB $LDLIBS
|
||||
|
|
|
|||
1
ivl.def
1
ivl.def
|
|
@ -294,6 +294,7 @@ ivl_stmt_lval
|
|||
ivl_stmt_lvals
|
||||
ivl_stmt_lwidth
|
||||
ivl_stmt_name
|
||||
ivl_stmt_needs_t0_trigger
|
||||
ivl_stmt_nevent
|
||||
ivl_stmt_opcode
|
||||
ivl_stmt_parm
|
||||
|
|
|
|||
17
ivl_target.h
17
ivl_target.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_ivl_target_H
|
||||
#define IVL_ivl_target_H
|
||||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -306,8 +306,10 @@ typedef enum ivl_lpm_type_e {
|
|||
IVL_LPM_CONCAT = 16,
|
||||
IVL_LPM_CONCATZ = 36, /* Transparent concat */
|
||||
IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */
|
||||
IVL_LPM_CMP_EQX= 37, /* Wildcard EQ (==?) */
|
||||
IVL_LPM_CMP_EQX= 37, /* Wildcard EQ (casex) */
|
||||
IVL_LPM_CMP_EQZ= 38, /* casez EQ */
|
||||
IVL_LPM_CMP_WEQ= 41,
|
||||
IVL_LPM_CMP_WNE= 42,
|
||||
IVL_LPM_CMP_EQ = 10,
|
||||
IVL_LPM_CMP_GE = 1,
|
||||
IVL_LPM_CMP_GT = 2,
|
||||
|
|
@ -353,9 +355,12 @@ typedef enum ivl_path_edge_e {
|
|||
/* Processes are initial, always, or final blocks with a statement. This is
|
||||
the type of the ivl_process_t object. */
|
||||
typedef enum ivl_process_type_e ENUM_UNSIGNED_INT {
|
||||
IVL_PR_INITIAL = 0,
|
||||
IVL_PR_ALWAYS = 1,
|
||||
IVL_PR_FINAL = 2
|
||||
IVL_PR_INITIAL = 0,
|
||||
IVL_PR_ALWAYS = 1,
|
||||
IVL_PR_ALWAYS_COMB = 3,
|
||||
IVL_PR_ALWAYS_FF = 4,
|
||||
IVL_PR_ALWAYS_LATCH = 5,
|
||||
IVL_PR_FINAL = 2
|
||||
} ivl_process_type_t;
|
||||
|
||||
/* These are the sorts of reasons a scope may come to be. These types
|
||||
|
|
@ -2100,6 +2105,7 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
|
|||
* handle disable statements.
|
||||
*
|
||||
* ivl_stmt_events
|
||||
* ivl_stmt_needs_t0_trigger
|
||||
* ivl_stmt_nevent
|
||||
* Statements that have event arguments (TRIGGER and WAIT) make
|
||||
* those event objects available through these methods.
|
||||
|
|
@ -2227,6 +2233,7 @@ extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net);
|
|||
/* IVL_ST_DELAY */
|
||||
extern uint64_t ivl_stmt_delay_val(ivl_statement_t net);
|
||||
/* IVL_ST_WAIT IVL_ST_TRIGGER */
|
||||
extern unsigned ivl_stmt_needs_t0_trigger(ivl_statement_t net);
|
||||
extern unsigned ivl_stmt_nevent(ivl_statement_t net);
|
||||
extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx);
|
||||
/* IVL_ST_CONTRIB */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_ivl_target_priv_H
|
||||
#define IVL_ivl_target_priv_H
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2017 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
|
||||
|
|
@ -52,7 +52,6 @@ struct ivl_design_s {
|
|||
|
||||
// Keep arrays of root scopes.
|
||||
std::map<const NetScope*,ivl_scope_t> classes;
|
||||
std::map<const NetScope*,ivl_scope_t> root_tasks;
|
||||
std::vector<ivl_scope_t> packages;
|
||||
std::vector<ivl_scope_t> roots;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_globals_H
|
||||
#define IVL_globals_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -53,6 +53,9 @@ extern char dep_mode;
|
|||
|
||||
extern int verbose_flag;
|
||||
|
||||
extern int warn_redef;
|
||||
extern int warn_redef_all;
|
||||
|
||||
/* This is the entry to the lexer. */
|
||||
extern int yylex(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
%option prefix="yy"
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -858,6 +858,25 @@ void define_macro(const char* name, const char* value, int keyword, int argc)
|
|||
{
|
||||
int idx;
|
||||
struct define_t* def;
|
||||
struct define_t* prev;
|
||||
|
||||
/* Verilog has a very nasty system of macros jumping from
|
||||
* file to file, resulting in a global macro scope. Here
|
||||
* we optionally warn about any redefinitions.
|
||||
*
|
||||
* If istack is empty, we are processing a configuration
|
||||
* or precompiled macro file, so don't want to check for
|
||||
* redefinitions - when a precompiled macro file is used,
|
||||
* it will contain copies of any predefined macros.
|
||||
*/
|
||||
if (warn_redef && istack) {
|
||||
prev = def_lookup(name);
|
||||
if (prev && (warn_redef_all || (strcmp(prev->value, value) != 0))) {
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "warning: redefinition of macro %s from value '%s' to '%s'\n",
|
||||
name, prev->value, value);
|
||||
}
|
||||
}
|
||||
|
||||
def = malloc(sizeof(struct define_t));
|
||||
def->name = strdup(name);
|
||||
|
|
@ -2100,7 +2119,7 @@ void destroy_lexor(void)
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
22
ivlpp/main.c
22
ivlpp/main.c
|
|
@ -1,5 +1,5 @@
|
|||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1999-2015 Stephen Williams (steve@icarus.com)";
|
||||
"Copyright (c) 1999-2017 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
|
||||
|
|
@ -98,6 +98,10 @@ int line_direct_flag = 0;
|
|||
unsigned error_count = 0;
|
||||
FILE *depend_file = NULL;
|
||||
|
||||
/* Should we warn about macro redefinitions? */
|
||||
int warn_redef = 0;
|
||||
int warn_redef_all = 0;
|
||||
|
||||
static int flist_read_flags(const char*path)
|
||||
{
|
||||
char line_buf[2048];
|
||||
|
|
@ -282,7 +286,7 @@ int main(int argc, char*argv[])
|
|||
include_dir[0] = 0; /* 0 is reserved for the current files path. */
|
||||
include_dir[1] = strdup(".");
|
||||
|
||||
while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:vV")) != EOF) switch (opt) {
|
||||
while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:vVW:")) != EOF) switch (opt) {
|
||||
|
||||
case 'F':
|
||||
flist_read_flags(optarg);
|
||||
|
|
@ -336,6 +340,15 @@ int main(int argc, char*argv[])
|
|||
break;
|
||||
}
|
||||
|
||||
case 'W':
|
||||
if (strcmp(optarg, "redef-all") == 0) {
|
||||
warn_redef_all = 1;
|
||||
warn_redef = 1;
|
||||
} else if (strcmp(optarg, "redef-chg") == 0) {
|
||||
warn_redef = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
fprintf(stderr, "Icarus Verilog Preprocessor version "
|
||||
VERSION " (" VERSION_TAG ")\n\n");
|
||||
|
|
@ -366,7 +379,10 @@ int main(int argc, char*argv[])
|
|||
" -p<fil> - Write precompiled defines to <fil>\n"
|
||||
" -P<fil> - Read precompiled defines from <fil>\n"
|
||||
" -v - Verbose\n"
|
||||
" -V - Print version information and quit\n",
|
||||
" -V - Print version information and quit\n"
|
||||
" -W<cat> - Enable extra ivlpp warning category:\n"
|
||||
" o redef-all - all macro redefinitions\n"
|
||||
" o redef-chg - macro definition changes\n",
|
||||
argv[0]);
|
||||
return flag_errors;
|
||||
}
|
||||
|
|
|
|||
48
lexor.lex
48
lexor.lex
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -72,6 +72,7 @@ static const char* set_file_name(char*text)
|
|||
void reset_lexor();
|
||||
static void line_directive();
|
||||
static void line_directive2();
|
||||
static void reset_all();
|
||||
|
||||
verinum*make_unsized_binary(const char*txt);
|
||||
verinum*make_undef_highz_dec(const char*txt);
|
||||
|
|
@ -187,6 +188,8 @@ TU [munpf]
|
|||
"!=" { return K_NE; }
|
||||
"===" { return K_CEQ; }
|
||||
"!==" { return K_CNE; }
|
||||
"==?" { return K_WEQ; }
|
||||
"!=?" { return K_WNE; }
|
||||
"||" { return K_LOR; }
|
||||
"&&" { return K_LAND; }
|
||||
"&&&" { return K_TAND; }
|
||||
|
|
@ -310,15 +313,6 @@ TU [munpf]
|
|||
BEGIN(UDPTABLE);
|
||||
break;
|
||||
|
||||
/* Translate these to checks if we already have or are
|
||||
* outside the declaration region. */
|
||||
case K_timeunit:
|
||||
if (have_timeunit_decl) rc = K_timeunit_check;
|
||||
break;
|
||||
case K_timeprecision:
|
||||
if (have_timeprec_decl) rc = K_timeprecision_check;
|
||||
break;
|
||||
|
||||
default:
|
||||
yylval.text = 0;
|
||||
break;
|
||||
|
|
@ -428,6 +422,12 @@ TU [munpf]
|
|||
|
||||
if (strcmp(yytext,"$attribute") == 0)
|
||||
return KK_attribute;
|
||||
|
||||
if (gn_system_verilog() && strcmp(yytext,"$unit") == 0) {
|
||||
yylval.package = pform_units.back();
|
||||
return PACKAGE_IDENTIFIER;
|
||||
}
|
||||
|
||||
yylval.text = strdupnew(yytext);
|
||||
return SYSTEM_IDENTIFIER; }
|
||||
|
||||
|
|
@ -566,11 +566,7 @@ TU [munpf]
|
|||
"definition." << endl;
|
||||
error_count += 1;
|
||||
} else {
|
||||
pform_set_default_nettype(NetNet::WIRE, yylloc.text,
|
||||
yylloc.first_line);
|
||||
in_celldefine = false;
|
||||
uc_drive = UCD_NONE;
|
||||
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
|
||||
reset_all();
|
||||
} }
|
||||
|
||||
/* Notice and handle the `unconnected_drive directive. */
|
||||
|
|
@ -1597,6 +1593,18 @@ static void line_directive2()
|
|||
yylloc.first_line = lineno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset all compiler directives. This will be called when a `resetall
|
||||
* directive is encountered or when a new compilation unit is started.
|
||||
*/
|
||||
static void reset_all()
|
||||
{
|
||||
pform_set_default_nettype(NetNet::WIRE, yylloc.text, yylloc.first_line);
|
||||
in_celldefine = false;
|
||||
uc_drive = UCD_NONE;
|
||||
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
|
||||
}
|
||||
|
||||
extern FILE*vl_input;
|
||||
void reset_lexor()
|
||||
{
|
||||
|
|
@ -1605,6 +1613,14 @@ void reset_lexor()
|
|||
|
||||
/* Announce the first file name. */
|
||||
yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
|
||||
|
||||
if (separate_compilation) {
|
||||
reset_all();
|
||||
if (!keyword_mask_stack.empty()) {
|
||||
lexor_keyword_mask = keyword_mask_stack.back();
|
||||
keyword_mask_stack.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1614,7 +1630,7 @@ void destroy_lexor()
|
|||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ static unsigned string_pool_count = 0;
|
|||
StringHeap::StringHeap()
|
||||
{
|
||||
cell_base_ = 0;
|
||||
cell_ptr_ = HEAPCELL;
|
||||
cell_count_ = 0;
|
||||
cell_size_ = 0;
|
||||
cell_ptr_ = 0;
|
||||
}
|
||||
|
||||
StringHeap::~StringHeap()
|
||||
|
|
@ -45,20 +45,24 @@ StringHeap::~StringHeap()
|
|||
const char* StringHeap::add(const char*text)
|
||||
{
|
||||
unsigned len = strlen(text);
|
||||
assert((len+1) <= HEAPCELL);
|
||||
|
||||
unsigned rem = HEAPCELL - cell_ptr_;
|
||||
unsigned rem = cell_size_ - cell_ptr_;
|
||||
if (rem < (len+1)) {
|
||||
cell_base_ = (char*)malloc(HEAPCELL);
|
||||
// release any unused memory
|
||||
if (rem > 0) {
|
||||
cell_base_ = (char*)realloc(cell_base_, cell_ptr_);
|
||||
assert(cell_base_ != 0);
|
||||
}
|
||||
// start new cell
|
||||
cell_size_ = (len+1) > DEFAULT_CELL_SIZE ? len+1 : DEFAULT_CELL_SIZE;
|
||||
cell_base_ = (char*)malloc(cell_size_);
|
||||
cell_ptr_ = 0;
|
||||
assert(cell_base_ != 0);
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
string_pool_count += 1;
|
||||
string_pool = (char **) realloc(string_pool,
|
||||
string_pool_count*sizeof(char **));
|
||||
string_pool[string_pool_count-1] = cell_base_;
|
||||
#endif
|
||||
cell_ptr_ = 0;
|
||||
cell_count_ += 1;
|
||||
assert(cell_base_ != 0);
|
||||
}
|
||||
|
||||
char*res = cell_base_ + cell_ptr_;
|
||||
|
|
@ -66,7 +70,7 @@ const char* StringHeap::add(const char*text)
|
|||
cell_ptr_ += len;
|
||||
cell_base_[cell_ptr_++] = 0;
|
||||
|
||||
assert(cell_ptr_ <= HEAPCELL);
|
||||
assert(cell_ptr_ <= cell_size_);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,11 +78,11 @@ class StringHeap {
|
|||
perm_string make(const char*);
|
||||
|
||||
private:
|
||||
enum { HEAPCELL = 0x10000 };
|
||||
static const unsigned DEFAULT_CELL_SIZE = 0x10000;
|
||||
|
||||
char*cell_base_;
|
||||
unsigned cell_size_;
|
||||
unsigned cell_ptr_;
|
||||
unsigned cell_count_;
|
||||
|
||||
private: // not implemented
|
||||
StringHeap(const StringHeap&);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ LDRELOCFLAGS = @LDRELOCFLAGS@
|
|||
|
||||
LDTARGETFLAGS = @LDTARGETFLAGS@
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const @PICFLAG@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
|
||||
A = a_close.o a_compare_handles.o a_configure.o a_fetch_argc.o \
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2014 Michael Ruff (mruff at chiaro.com)
|
||||
* Copyright (c) 2002-2018 Michael Ruff (mruff at chiaro.com)
|
||||
* Michael Runyan (mrunyan at chiaro.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -42,8 +42,9 @@ typedef struct t_pli_data {
|
|||
int paramvc; /* parameter number for misctf */
|
||||
} s_pli_data, *p_pli_data;
|
||||
|
||||
static PLI_INT32 compiletf(char *);
|
||||
static PLI_INT32 calltf(char *);
|
||||
static PLI_INT32 compiletf(ICARUS_VPI_CONST PLI_BYTE8 *);
|
||||
static PLI_INT32 calltf(ICARUS_VPI_CONST PLI_BYTE8 *);
|
||||
static PLI_INT32 sizetf(ICARUS_VPI_CONST PLI_BYTE8 *);
|
||||
static PLI_INT32 callback(p_cb_data);
|
||||
|
||||
/*
|
||||
|
|
@ -150,7 +151,7 @@ void veriusertfs_register_table(p_tfcell vtable)
|
|||
tf_data.tfname = tf->tfname;
|
||||
tf_data.compiletf = compiletf;
|
||||
tf_data.calltf = calltf;
|
||||
tf_data.sizetf = (PLI_INT32 (*)(PLI_BYTE8 *))tf->sizetf;
|
||||
tf_data.sizetf = sizetf;
|
||||
tf_data.user_data = (char *)data;
|
||||
|
||||
if (pli_trace) {
|
||||
|
|
@ -180,7 +181,7 @@ void veriusertfs_register_table(p_tfcell vtable)
|
|||
* This function calls the veriusertfs checktf and sets up all the
|
||||
* callbacks misctf requires.
|
||||
*/
|
||||
static PLI_INT32 compiletf(char *data)
|
||||
static PLI_INT32 compiletf(ICARUS_VPI_CONST PLI_BYTE8*data)
|
||||
{
|
||||
p_pli_data pli;
|
||||
p_tfcell tf;
|
||||
|
|
@ -260,7 +261,7 @@ static PLI_INT32 compiletf(char *data)
|
|||
/*
|
||||
* This function is the wrapper for the veriusertfs calltf routine.
|
||||
*/
|
||||
static PLI_INT32 calltf(char *data)
|
||||
static PLI_INT32 calltf(ICARUS_VPI_CONST PLI_BYTE8*data)
|
||||
{
|
||||
int rc = 0;
|
||||
p_pli_data pli;
|
||||
|
|
@ -283,6 +284,32 @@ static PLI_INT32 calltf(char *data)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is the wrapper for the veriusertfs sizetf routine.
|
||||
*/
|
||||
static PLI_INT32 sizetf(ICARUS_VPI_CONST PLI_BYTE8*data)
|
||||
{
|
||||
int rc = 32;
|
||||
p_pli_data pli;
|
||||
p_tfcell tf;
|
||||
|
||||
/* cast back from opaque */
|
||||
pli = (p_pli_data)data;
|
||||
tf = pli->tf;
|
||||
|
||||
/* execute sizetf */
|
||||
if (tf->sizetf) {
|
||||
if (pli_trace) {
|
||||
fprintf(pli_trace, "Call %s->sizetf(%d, %d)\n",
|
||||
tf->tfname, tf->data, reason_sizetf);
|
||||
}
|
||||
|
||||
rc = tf->sizetf(tf->data, reason_sizetf);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is the wrapper for all the misctf callbacks
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -82,36 +82,10 @@ bool load_module(const char*type)
|
|||
fflush(depend_file);
|
||||
}
|
||||
|
||||
if (ivlpp_string) {
|
||||
char*cmdline = (char*)malloc(strlen(ivlpp_string) +
|
||||
strlen(path) + 4);
|
||||
strcpy(cmdline, ivlpp_string);
|
||||
strcat(cmdline, " \"");
|
||||
strcat(cmdline, path);
|
||||
strcat(cmdline, "\"");
|
||||
if (verbose_flag)
|
||||
cerr << "Loading library file " << path << "." << endl;
|
||||
|
||||
if (verbose_flag)
|
||||
cerr << "Executing: " << cmdline << endl<< flush;
|
||||
|
||||
FILE*file = popen(cmdline, "r");
|
||||
|
||||
if (verbose_flag)
|
||||
cerr << "...parsing output from preprocessor..." << endl << flush;
|
||||
|
||||
pform_parse(path, file);
|
||||
pclose(file);
|
||||
free(cmdline);
|
||||
|
||||
} else {
|
||||
if (verbose_flag)
|
||||
cerr << "Loading library file "
|
||||
<< path << "." << endl;
|
||||
|
||||
FILE*file = fopen(path, "r");
|
||||
assert(file);
|
||||
pform_parse(path, file);
|
||||
fclose(file);
|
||||
}
|
||||
pform_parse(path);
|
||||
|
||||
if (verbose_flag)
|
||||
cerr << "... Load module complete." << endl << flush;
|
||||
|
|
@ -119,7 +93,6 @@ bool load_module(const char*type)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
102
main.cc
102
main.cc
|
|
@ -1,5 +1,5 @@
|
|||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)";
|
||||
"Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)";
|
||||
|
||||
/*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -140,6 +140,8 @@ void add_vpi_module(const char*name)
|
|||
map<perm_string,unsigned> missing_modules;
|
||||
map<perm_string,bool> library_file_map;
|
||||
|
||||
vector<perm_string> source_files;
|
||||
|
||||
list<const char*> library_suff;
|
||||
|
||||
list<perm_string> roots;
|
||||
|
|
@ -164,6 +166,11 @@ bool warn_sens_entire_arr = false;
|
|||
bool warn_anachronisms = false;
|
||||
bool warn_floating_nets = false;
|
||||
|
||||
/*
|
||||
* Ignore errors about missing modules
|
||||
*/
|
||||
bool ignore_missing_modules = false;
|
||||
|
||||
/*
|
||||
* Debug message class flags.
|
||||
*/
|
||||
|
|
@ -174,6 +181,11 @@ bool debug_emit = false;
|
|||
bool debug_synth2 = false;
|
||||
bool debug_optimizer = false;
|
||||
|
||||
/*
|
||||
* Compilation control flags.
|
||||
*/
|
||||
bool separate_compilation = false;
|
||||
|
||||
/*
|
||||
* Optimization control flags.
|
||||
*/
|
||||
|
|
@ -570,6 +582,9 @@ static bool set_default_timescale(const char*ts_string)
|
|||
*
|
||||
* warnings:<string>
|
||||
* Warning flag letters.
|
||||
*
|
||||
* ignore_missing_modules:<bool>
|
||||
* true to ignore errors about missing modules
|
||||
*/
|
||||
bool had_timescale = false;
|
||||
static void read_iconfig_file(const char*ipath)
|
||||
|
|
@ -720,6 +735,10 @@ static void read_iconfig_file(const char*ipath)
|
|||
break;
|
||||
}
|
||||
|
||||
} else if (strcmp(buf, "ignore_missing_modules") == 0) {
|
||||
if (strcmp(cp, "true") == 0)
|
||||
ignore_missing_modules = true;
|
||||
|
||||
} else if (strcmp(buf, "-y") == 0) {
|
||||
build_library_index(cp, CASE_SENSITIVE);
|
||||
|
||||
|
|
@ -765,6 +784,38 @@ static void read_iconfig_file(const char*ipath)
|
|||
fclose(ifile);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function reads a list of source file names. Each name starts
|
||||
* with the first non-space character, and ends with the last non-space
|
||||
* character. Spaces in the middle are OK.
|
||||
*/
|
||||
static void read_sources_file(const char*path)
|
||||
{
|
||||
char line_buf[2048];
|
||||
|
||||
FILE*fd = fopen(path, "r");
|
||||
if (fd == 0) {
|
||||
cerr << "ERROR: Unable to read source file list: " << path << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(line_buf, sizeof line_buf, fd) != 0) {
|
||||
char*cp = line_buf + strspn(line_buf, " \t\r\b\f");
|
||||
char*tail = cp + strlen(cp);
|
||||
while (tail > cp) {
|
||||
if (! isspace((int)tail[-1]))
|
||||
break;
|
||||
tail -= 1;
|
||||
tail[0] = 0;
|
||||
}
|
||||
|
||||
if (cp < tail)
|
||||
source_files.push_back(filename_strings.make(cp));
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
extern Design* elaborate(list <perm_string> root);
|
||||
|
||||
#if defined(HAVE_TIMES)
|
||||
|
|
@ -851,12 +902,14 @@ int main(int argc, char*argv[])
|
|||
min_typ_max_flag = TYP;
|
||||
min_typ_max_warn = 10;
|
||||
|
||||
while ((opt = getopt(argc, argv, "C:f:hN:P:p:Vv")) != EOF) switch (opt) {
|
||||
while ((opt = getopt(argc, argv, "C:F:f:hN:P:p:Vv")) != EOF) switch (opt) {
|
||||
|
||||
case 'C':
|
||||
read_iconfig_file(optarg);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
read_sources_file(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
parm_to_flagmap(optarg);
|
||||
break;
|
||||
|
|
@ -909,6 +962,7 @@ int main(int argc, char*argv[])
|
|||
"usage: ivl <options> <file>\n"
|
||||
"options:\n"
|
||||
"\t-C <name> Config file from driver.\n"
|
||||
"\t-F <file> List of source files from driver.\n"
|
||||
"\t-h Print usage information, and exit.\n"
|
||||
"\t-N <file> Dump the elaborated netlist to <file>.\n"
|
||||
"\t-P <file> Write the parsed input to <file>.\n"
|
||||
|
|
@ -924,11 +978,19 @@ int main(int argc, char*argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
int arg = optind;
|
||||
while (arg < argc) {
|
||||
perm_string path = filename_strings.make(argv[arg++]);
|
||||
source_files.push_back(path);
|
||||
}
|
||||
|
||||
if (source_files.empty()) {
|
||||
cerr << "No input files." << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
separate_compilation = source_files.size() > 1;
|
||||
|
||||
if( depfile_name ) {
|
||||
depend_file = fopen(depfile_name, "a");
|
||||
if(! depend_file) {
|
||||
|
|
@ -940,16 +1002,22 @@ int main(int argc, char*argv[])
|
|||
switch (generation_flag) {
|
||||
case GN_VER2012:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1800_2012;
|
||||
// fallthrough
|
||||
case GN_VER2009:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1800_2009;
|
||||
// fallthrough
|
||||
case GN_VER2005_SV:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1800_2005;
|
||||
// fallthrough
|
||||
case GN_VER2005:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2005;
|
||||
// fallthrough
|
||||
case GN_VER2001:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
|
||||
// fallthrough
|
||||
case GN_VER2001_NOCONFIG:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_2001;
|
||||
// fallthrough
|
||||
case GN_VER1995:
|
||||
lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
|
||||
}
|
||||
|
|
@ -1023,8 +1091,10 @@ int main(int argc, char*argv[])
|
|||
if (flag_tmp) disable_concatz_generation = strcmp(flag_tmp,"true")==0;
|
||||
|
||||
/* Parse the input. Make the pform. */
|
||||
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
|
||||
int rc = pform_parse(argv[optind]);
|
||||
int rc = 0;
|
||||
for (unsigned idx = 0; idx < source_files.size(); idx += 1) {
|
||||
rc += pform_parse(source_files[idx]);
|
||||
}
|
||||
|
||||
if (pf_path) {
|
||||
ofstream out (pf_path);
|
||||
|
|
@ -1038,22 +1108,16 @@ int main(int argc, char*argv[])
|
|||
; cur != disciplines.end() ; ++ cur ) {
|
||||
pform_dump(out, (*cur).second);
|
||||
}
|
||||
out << "PFORM DUMP $ROOT TASKS/FUNCTIONS:" << endl;
|
||||
for (map<perm_string,PTaskFunc*>::iterator cur = pform_tasks.begin()
|
||||
; cur != pform_tasks.end() ; ++ cur) {
|
||||
pform_dump(out, cur->second);
|
||||
}
|
||||
out << "PFORM DUMP $ROOT CLASSES:" << endl;
|
||||
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
|
||||
; cur != pform_classes.end() ; ++ cur) {
|
||||
pform_dump(out, cur->second);
|
||||
out << "PFORM DUMP COMPILATION UNITS:" << endl;
|
||||
for (vector<PPackage*>::iterator pac = pform_units.begin()
|
||||
; pac != pform_units.end() ; ++ pac) {
|
||||
pform_dump(out, *pac);
|
||||
}
|
||||
out << "PFORM DUMP PACKAGES:" << endl;
|
||||
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
|
||||
; pac != pform_packages.end() ; ++ pac) {
|
||||
pform_dump(out, pac->second);
|
||||
}
|
||||
|
||||
out << "PFORM DUMP MODULES:" << endl;
|
||||
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
|
||||
; mod != pform_modules.end() ; ++ mod ) {
|
||||
|
|
@ -1171,12 +1235,6 @@ int main(int argc, char*argv[])
|
|||
(*idx).second = 0;
|
||||
}
|
||||
|
||||
for(map<perm_string,data_type_t*>::iterator it = pform_typedefs.begin()
|
||||
; it != pform_typedefs.end() ; ++it) {
|
||||
delete (*it).second;
|
||||
(*it).second = 0;
|
||||
}
|
||||
|
||||
if (verbose_flag) {
|
||||
if (times_flag) {
|
||||
times(cycles+2);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
These are instructions for building Icarus Verilog binaries for
|
||||
Windows using mingw cross compiler tools on Linux.
|
||||
|
||||
To start with, you need the mingw64-cross-* packages for your linux
|
||||
distribution, which gives you the x86_64-w64-mingw32-* commands
|
||||
installed on your system. Installing the cross environment is outside
|
||||
the scope of this writeup.
|
||||
|
||||
First, configure with this command:
|
||||
|
||||
$ ./configure --host=x86_64-w64-mingw32
|
||||
|
||||
This generates the Makefiles needed to cross compile everything with
|
||||
the mingw32 compiler. The configure script will generate the command
|
||||
name paths, so long as commands line x86_64-w64-mingw32-gcc
|
||||
et. al. are in your path.
|
||||
|
||||
Next, compile with the command:
|
||||
|
||||
$ make HOSTCC=cc HOSTCFLAGS=-O
|
||||
|
||||
The configure generated the cross compiler flags, but there are a few
|
||||
bits that need to be compiled with the native compiler. (version.exe
|
||||
for example is used by the build process but is not installed.) The
|
||||
MOSTCC= flag on the make command line makes sure the Makefile knows
|
||||
about the native tool.
|
||||
207
net_design.cc
207
net_design.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -101,11 +101,11 @@ uint64_t Design::scale_to_precision(uint64_t val,
|
|||
return val;
|
||||
}
|
||||
|
||||
NetScope* Design::make_root_scope(perm_string root, bool program_block,
|
||||
bool is_interface)
|
||||
NetScope* Design::make_root_scope(perm_string root, NetScope*unit_scope,
|
||||
bool program_block, bool is_interface)
|
||||
{
|
||||
NetScope *root_scope_;
|
||||
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE,
|
||||
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE, unit_scope,
|
||||
false, program_block, is_interface);
|
||||
/* This relies on the fact that the basename return value is
|
||||
permallocated. */
|
||||
|
|
@ -125,31 +125,18 @@ list<NetScope*> Design::find_root_scopes() const
|
|||
return root_scopes_;
|
||||
}
|
||||
|
||||
NetScope* Design::make_package_scope(perm_string name)
|
||||
NetScope* Design::make_package_scope(perm_string name, NetScope*unit_scope,
|
||||
bool is_unit)
|
||||
{
|
||||
NetScope*scope;
|
||||
|
||||
scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, false, false);
|
||||
scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, unit_scope,
|
||||
false, false, false, is_unit);
|
||||
scope->set_module_name(scope->basename());
|
||||
packages_[name] = scope;
|
||||
return scope;
|
||||
}
|
||||
|
||||
void Design::add_class(netclass_t*cl, PClass*pclass)
|
||||
{
|
||||
Definitions::add_class(cl);
|
||||
class_to_pclass_[cl] = pclass;
|
||||
}
|
||||
|
||||
netclass_t* Design::find_class(perm_string name) const
|
||||
{
|
||||
map<perm_string,netclass_t*>::const_iterator cur = classes_.find(name);
|
||||
if (cur != classes_.end())
|
||||
return cur->second;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetScope* Design::find_package(perm_string name) const
|
||||
{
|
||||
map<perm_string,NetScope*>::const_iterator cur = packages_.find(name);
|
||||
|
|
@ -170,17 +157,6 @@ list<NetScope*> Design::find_package_scopes() const
|
|||
return res;
|
||||
}
|
||||
|
||||
list<NetScope*> Design::find_roottask_scopes() const
|
||||
{
|
||||
list<NetScope*>res;
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
res.push_back (cur->first);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a scope in the design, given its rooted
|
||||
* hierarchical name. Each component of the key is used to scan one
|
||||
|
|
@ -211,25 +187,6 @@ NetScope* Design::find_scope(const std::list<hname_t>&path) const
|
|||
}
|
||||
}
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator root = root_tasks_.begin()
|
||||
; root != root_tasks_.end() ; ++ root) {
|
||||
|
||||
NetScope*cur = root->first;
|
||||
if (path.front() != cur->fullname())
|
||||
continue;
|
||||
|
||||
std::list<hname_t> tmp = path;
|
||||
tmp.pop_front();
|
||||
|
||||
while (cur) {
|
||||
if (tmp.empty()) return cur;
|
||||
|
||||
cur = cur->child( tmp.front() );
|
||||
|
||||
tmp.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -253,6 +210,49 @@ NetScope* Design::find_scope(const hname_t&path) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool is_design_unit(NetScope*scope)
|
||||
{
|
||||
return (scope->type() == NetScope::MODULE && !scope->nested_module())
|
||||
|| (scope->type() == NetScope::PACKAGE);
|
||||
}
|
||||
|
||||
static bool is_subroutine(NetScope::TYPE type)
|
||||
{
|
||||
return type == NetScope::TASK || type == NetScope::FUNC;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a scope within another scope, given its relative
|
||||
* hierarchical name. Each component of the key is used to scan one
|
||||
* more step down the tree until the name runs out or the search
|
||||
* fails.
|
||||
*/
|
||||
NetScope* Design::find_scope_(NetScope*scope, const std::list<hname_t>&path,
|
||||
NetScope::TYPE type) const
|
||||
{
|
||||
std::list<hname_t> tmp = path;
|
||||
|
||||
do {
|
||||
hname_t key = tmp.front();
|
||||
/* If we are looking for a module or we are not
|
||||
* looking at the last path component check for
|
||||
* a name match (second line). */
|
||||
if (scope->type() == NetScope::MODULE
|
||||
&& (type == NetScope::MODULE || tmp.size() > 1)
|
||||
&& scope->module_name()==key.peek_name()) {
|
||||
|
||||
/* Up references may match module name */
|
||||
|
||||
} else {
|
||||
scope = scope->child( key );
|
||||
if (scope == 0) break;
|
||||
}
|
||||
tmp.pop_front();
|
||||
} while (! tmp.empty());
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a relative lookup of a scope by name. The starting point is
|
||||
* the scope parameter within which I start looking for the scope. If
|
||||
|
|
@ -266,36 +266,62 @@ NetScope* Design::find_scope(NetScope*scope, const std::list<hname_t>&path,
|
|||
if (path.empty())
|
||||
return scope;
|
||||
|
||||
for ( ; scope ; scope = scope->parent()) {
|
||||
// Record the compilation unit scope for use later.
|
||||
NetScope*unit_scope = scope->unit();
|
||||
|
||||
std::list<hname_t> tmp = path;
|
||||
// First search upwards through the hierarchy.
|
||||
while (scope) {
|
||||
NetScope*found_scope = find_scope_(scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
|
||||
NetScope*cur = scope;
|
||||
do {
|
||||
hname_t key = tmp.front();
|
||||
/* If we are looking for a module or we are not
|
||||
* looking at the last path component check for
|
||||
* a name match (second line). */
|
||||
if (cur->type() == NetScope::MODULE
|
||||
&& (type == NetScope::MODULE || tmp.size() > 1)
|
||||
&& cur->module_name()==key.peek_name()) {
|
||||
// Avoid searching the unit scope twice.
|
||||
if (scope == unit_scope)
|
||||
unit_scope = 0;
|
||||
|
||||
/* Up references may match module name */
|
||||
// Special case - see IEEE 1800-2012 section 23.8.1.
|
||||
if (unit_scope && is_design_unit(scope) && is_subroutine(type)) {
|
||||
found_scope = find_scope_(unit_scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
|
||||
} else {
|
||||
cur = cur->child( key );
|
||||
if (cur == 0) break;
|
||||
}
|
||||
tmp.pop_front();
|
||||
} while (! tmp.empty());
|
||||
unit_scope = 0;
|
||||
}
|
||||
|
||||
if (cur) return cur;
|
||||
scope = scope->parent();
|
||||
}
|
||||
|
||||
// If we haven't already done so, search the compilation unit scope.
|
||||
if (unit_scope) {
|
||||
NetScope*found_scope = find_scope_(unit_scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
}
|
||||
|
||||
// Last chance. Look for the name starting at the root.
|
||||
return find_scope(path);
|
||||
}
|
||||
|
||||
/*
|
||||
* This method locates a scope within another scope, given its relative
|
||||
* hierarchical name. Each component of the key is used to scan one
|
||||
* more step down the tree until the name runs out or the search
|
||||
* fails.
|
||||
*/
|
||||
NetScope* Design::find_scope_(NetScope*scope, const hname_t&path,
|
||||
NetScope::TYPE type) const
|
||||
{
|
||||
/* If we are looking for a module or we are not
|
||||
* looking at the last path component check for
|
||||
* a name match (second line). */
|
||||
if ((scope->type() == NetScope::MODULE) && (type == NetScope::MODULE)
|
||||
&& (scope->module_name() == path.peek_name())) {
|
||||
/* Up references may match module name */
|
||||
return scope;
|
||||
}
|
||||
return scope->child( path );
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a relative lookup of a scope by name. The starting point is
|
||||
* the scope parameter within which I start looking for the scope. If
|
||||
|
|
@ -307,24 +333,36 @@ NetScope* Design::find_scope(NetScope*scope, const hname_t&path,
|
|||
{
|
||||
assert(scope);
|
||||
|
||||
for ( ; scope ; scope = scope->parent()) {
|
||||
// Record the compilation unit scope for use later.
|
||||
NetScope*unit_scope = scope->unit();
|
||||
|
||||
NetScope*cur = scope;
|
||||
// First search upwards through the hierarchy.
|
||||
while (scope) {
|
||||
NetScope*found_scope = find_scope_(scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
|
||||
/* If we are looking for a module or we are not
|
||||
* looking at the last path component check for
|
||||
* a name match (second line). */
|
||||
if (cur->type() == NetScope::MODULE
|
||||
&& (type == NetScope::MODULE)
|
||||
&& cur->module_name()==path.peek_name()) {
|
||||
// Avoid searching the unit scope twice.
|
||||
if (scope == unit_scope)
|
||||
unit_scope = 0;
|
||||
|
||||
/* Up references may match module name */
|
||||
// Special case - see IEEE 1800-2012 section 23.8.1.
|
||||
if (unit_scope && is_design_unit(scope) && is_subroutine(type)) {
|
||||
found_scope = find_scope_(unit_scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
|
||||
} else {
|
||||
cur = cur->child( path );
|
||||
unit_scope = 0;
|
||||
}
|
||||
|
||||
if (cur) return cur;
|
||||
scope = scope->parent();
|
||||
}
|
||||
|
||||
// If we haven't already done so, search the compilation unit scope.
|
||||
if (unit_scope) {
|
||||
NetScope*found_scope = find_scope_(unit_scope, path, type);
|
||||
if (found_scope)
|
||||
return found_scope;
|
||||
}
|
||||
|
||||
// Last chance. Look for the name starting at the root.
|
||||
|
|
@ -867,11 +905,6 @@ NetScope* Design::find_task(NetScope*scope, const pform_name_t&name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Design::add_root_task(NetScope*tscope, PTaskFunc*tf)
|
||||
{
|
||||
root_tasks_[tscope] = tf;
|
||||
}
|
||||
|
||||
void Design::add_node(NetNode*net)
|
||||
{
|
||||
assert(net->design_ == 0);
|
||||
|
|
|
|||
10
net_event.cc
10
net_event.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
NetEvent::NetEvent(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
local_flag_ = false;
|
||||
scope_ = 0;
|
||||
snext_ = 0;
|
||||
probes_ = 0;
|
||||
|
|
@ -345,7 +346,7 @@ void NetEvProbe::find_similar_probes(list<NetEvProbe*>&plist)
|
|||
}
|
||||
|
||||
NetEvWait::NetEvWait(NetProc*pr)
|
||||
: statement_(pr)
|
||||
: statement_(pr), has_t0_trigger_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -442,3 +443,8 @@ NetProc* NetEvWait::statement()
|
|||
{
|
||||
return statement_;
|
||||
}
|
||||
|
||||
const NetProc* NetEvWait::statement() const
|
||||
{
|
||||
return statement_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2018 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
|
||||
|
|
@ -23,6 +23,10 @@
|
|||
# include <typeinfo>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#define unique_ptr auto_ptr
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
|
|
@ -1018,7 +1022,7 @@ NetExpr* NetESignal::evaluate_function(const LineInfo&loc,
|
|||
NetExpr* NetETernary::evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&context_map) const
|
||||
{
|
||||
auto_ptr<NetExpr> cval (cond_->evaluate_function(loc, context_map));
|
||||
unique_ptr<NetExpr> cval (cond_->evaluate_function(loc, context_map));
|
||||
|
||||
switch (const_logical(cval.get())) {
|
||||
|
||||
|
|
|
|||
343
net_nex_input.cc
343
net_nex_input.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2017 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
|
||||
|
|
@ -27,29 +27,29 @@
|
|||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
NexusSet* NetExpr::nex_input(bool)
|
||||
NexusSet* NetExpr::nex_input(bool, bool) const
|
||||
{
|
||||
cerr << get_fileline()
|
||||
<< ": internal error: nex_input not implemented: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetProc::nex_input(bool)
|
||||
NexusSet* NetProc::nex_input(bool, bool) const
|
||||
{
|
||||
cerr << get_fileline()
|
||||
<< ": internal error: NetProc::nex_input not implemented"
|
||||
<< endl;
|
||||
return 0;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEArrayPattern::nex_input(bool rem_out)
|
||||
NexusSet* NetEArrayPattern::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||
if (items_[idx]==0) continue;
|
||||
|
||||
NexusSet*tmp = items_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = items_[idx]->nex_input(rem_out, search_funcs);
|
||||
if (tmp == 0) continue;
|
||||
|
||||
result->add(*tmp);
|
||||
|
|
@ -58,32 +58,32 @@ NexusSet* NetEArrayPattern::nex_input(bool rem_out)
|
|||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEBinary::nex_input(bool rem_out)
|
||||
NexusSet* NetEBinary::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = left_->nex_input(rem_out);
|
||||
NexusSet*tmp = right_->nex_input(rem_out);
|
||||
NexusSet*result = left_->nex_input(rem_out, search_funcs);
|
||||
NexusSet*tmp = right_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEConcat::nex_input(bool rem_out)
|
||||
NexusSet* NetEConcat::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
if (parms_[0] == NULL) return NULL;
|
||||
NexusSet*result = parms_[0]->nex_input(rem_out);
|
||||
if (parms_[0] == NULL) return new NexusSet;
|
||||
NexusSet*result = parms_[0]->nex_input(rem_out, search_funcs);
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx] == NULL) {
|
||||
delete result;
|
||||
return NULL;
|
||||
return new NexusSet;
|
||||
}
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEAccess::nex_input(bool)
|
||||
NexusSet* NetEAccess::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
|
@ -91,59 +91,55 @@ NexusSet* NetEAccess::nex_input(bool)
|
|||
/*
|
||||
* A constant has not inputs, so always return an empty set.
|
||||
*/
|
||||
NexusSet* NetEConst::nex_input(bool)
|
||||
NexusSet* NetEConst::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetECReal::nex_input(bool)
|
||||
NexusSet* NetECReal::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEEvent::nex_input(bool)
|
||||
NexusSet* NetEEvent::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetELast::nex_input(bool)
|
||||
NexusSet* NetELast::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetENetenum::nex_input(bool)
|
||||
NexusSet* NetENetenum::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetENew::nex_input(bool)
|
||||
NexusSet* NetENew::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetENull::nex_input(bool)
|
||||
NexusSet* NetENull::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEProperty::nex_input(bool)
|
||||
NexusSet* NetEProperty::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEScope::nex_input(bool)
|
||||
NexusSet* NetEScope::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetESelect::nex_input(bool rem_out)
|
||||
NexusSet* NetESelect::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = base_? base_->nex_input(rem_out) : new NexusSet();
|
||||
NexusSet*tmp = expr_->nex_input(rem_out);
|
||||
if (tmp == NULL) {
|
||||
delete result;
|
||||
return NULL;
|
||||
}
|
||||
NexusSet*result = base_? base_->nex_input(rem_out, search_funcs) : new NexusSet();
|
||||
NexusSet*tmp = expr_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
/* See the comment for NetESignal below. */
|
||||
|
|
@ -157,30 +153,29 @@ NexusSet* NetESelect::nex_input(bool rem_out)
|
|||
/*
|
||||
* The $fread, etc. system functions can have NULL arguments.
|
||||
*/
|
||||
NexusSet* NetESFunc::nex_input(bool rem_out)
|
||||
NexusSet* NetESFunc::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
if (parms_.empty())
|
||||
return new NexusSet;
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
NexusSet*result;
|
||||
if (parms_[0]) result = parms_[0]->nex_input(rem_out);
|
||||
else result = new NexusSet;
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_.empty()) return result;
|
||||
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx]) {
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEShallowCopy::nex_input(bool)
|
||||
NexusSet* NetEShallowCopy::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetESignal::nex_input(bool rem_out)
|
||||
NexusSet* NetESignal::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
/*
|
||||
* This is not what I would expect for the various selects (bit,
|
||||
|
|
@ -194,7 +189,7 @@ NexusSet* NetESignal::nex_input(bool rem_out)
|
|||
/* If we have an array index add it to the sensitivity list. */
|
||||
if (word_) {
|
||||
NexusSet*tmp;
|
||||
tmp = word_->nex_input(rem_out);
|
||||
tmp = word_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
if (warn_sens_entire_arr) {
|
||||
|
|
@ -209,27 +204,44 @@ NexusSet* NetESignal::nex_input(bool rem_out)
|
|||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetETernary::nex_input(bool rem_out)
|
||||
NexusSet* NetETernary::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*tmp;
|
||||
NexusSet*result = cond_->nex_input(rem_out);
|
||||
NexusSet*result = cond_->nex_input(rem_out, search_funcs);
|
||||
|
||||
tmp = true_val_->nex_input(rem_out);
|
||||
tmp = true_val_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
tmp = false_val_->nex_input(rem_out);
|
||||
tmp = false_val_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEUFunc::nex_input(bool rem_out)
|
||||
NexusSet* NetEUFunc::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (search_funcs) {
|
||||
NetFuncDef*func = func_->func_def();
|
||||
NexusSet*tmp = func->proc()->nex_input(rem_out, search_funcs);
|
||||
// Remove the function inputs
|
||||
NexusSet*in = new NexusSet;
|
||||
for (unsigned idx = 0 ; idx < func->port_count() ; idx += 1) {
|
||||
NetNet*net = func->port(idx);
|
||||
assert(net->pin_count() == 1);
|
||||
in->add(net->pin(0).nexus(), 0, net->vector_width());
|
||||
}
|
||||
tmp->rem(*in);
|
||||
delete in;
|
||||
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
|
@ -237,21 +249,28 @@ NexusSet* NetEUFunc::nex_input(bool rem_out)
|
|||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEUnary::nex_input(bool rem_out)
|
||||
NexusSet* NetEUnary::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
return expr_->nex_input(rem_out);
|
||||
return expr_->nex_input(rem_out, search_funcs);
|
||||
}
|
||||
|
||||
NexusSet* NetAssign_::nex_input(bool rem_out)
|
||||
NexusSet* NetAlloc::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetAssign_::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
assert(! nest_);
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (word_) {
|
||||
NexusSet*tmp = word_->nex_input(rem_out);
|
||||
NexusSet*tmp = word_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
if (base_) {
|
||||
NexusSet*tmp = base_->nex_input(rem_out);
|
||||
NexusSet*tmp = base_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
|
@ -259,15 +278,21 @@ NexusSet* NetAssign_::nex_input(bool rem_out)
|
|||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetAssignBase::nex_input(bool rem_out)
|
||||
NexusSet* NetAssignBase::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = rval_->nex_input(rem_out);
|
||||
NexusSet*result = new NexusSet;
|
||||
// For the deassign and release statements there is no R-value.
|
||||
if (rval_) {
|
||||
NexusSet*tmp = rval_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
/* It is possible that the lval_ can have nex_input values. In
|
||||
particular, index expressions are statement inputs as well,
|
||||
so should be addressed here. */
|
||||
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
|
||||
NexusSet*tmp = cur->nex_input(rem_out);
|
||||
NexusSet*tmp = cur->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
|
@ -292,16 +317,15 @@ NexusSet* NetAssignBase::nex_input(bool rem_out)
|
|||
* In this example, "t" should not be in the input set because it is
|
||||
* used by the sequence as a temporary value.
|
||||
*/
|
||||
NexusSet* NetBlock::nex_input(bool rem_out)
|
||||
NexusSet* NetBlock::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
if (last_ == 0)
|
||||
return new NexusSet;
|
||||
if (last_ == 0) return new NexusSet;
|
||||
|
||||
if (type_ != SEQU) {
|
||||
if (! search_funcs && (type_ != SEQU)) {
|
||||
cerr << get_fileline() << ": internal error: Sorry, "
|
||||
<< "I don't know how to synthesize fork/join blocks."
|
||||
<< endl;
|
||||
return 0;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NetProc*cur = last_->next_;
|
||||
|
|
@ -312,10 +336,10 @@ NexusSet* NetBlock::nex_input(bool rem_out)
|
|||
|
||||
do {
|
||||
/* Get the inputs for the current statement. */
|
||||
NexusSet*tmp = cur->nex_input(rem_out);
|
||||
NexusSet*tmp = cur->nex_input(rem_out, search_funcs);
|
||||
|
||||
/* Add the current input set to the accumulated input set. */
|
||||
if (tmp != 0) result->add(*tmp);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
/* Add the current outputs to the accumulated output set if
|
||||
|
|
@ -339,11 +363,9 @@ NexusSet* NetBlock::nex_input(bool rem_out)
|
|||
* the inputs to all the guards, and the inputs to all the guarded
|
||||
* statements.
|
||||
*/
|
||||
NexusSet* NetCase::nex_input(bool rem_out)
|
||||
NexusSet* NetCase::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = expr_->nex_input(rem_out);
|
||||
if (result == 0)
|
||||
return 0;
|
||||
NexusSet*result = expr_->nex_input(rem_out, search_funcs);
|
||||
|
||||
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||
|
||||
|
|
@ -351,8 +373,7 @@ NexusSet* NetCase::nex_input(bool rem_out)
|
|||
if (items_[idx].statement == 0)
|
||||
continue;
|
||||
|
||||
NexusSet*tmp = items_[idx].statement->nex_input(rem_out);
|
||||
assert(tmp);
|
||||
NexusSet*tmp = items_[idx].statement->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
|
||||
|
|
@ -360,8 +381,7 @@ NexusSet* NetCase::nex_input(bool rem_out)
|
|||
case is special and is identified by a null
|
||||
guard. The default guard obviously has no input. */
|
||||
if (items_[idx].guard) {
|
||||
tmp = items_[idx].guard->nex_input(rem_out);
|
||||
assert(tmp);
|
||||
tmp = items_[idx].guard->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
|
@ -370,24 +390,18 @@ NexusSet* NetCase::nex_input(bool rem_out)
|
|||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetCAssign::nex_input(bool)
|
||||
NexusSet* NetCondit::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
cerr << get_fileline() << ": internal warning: NetCAssign::nex_input()"
|
||||
<< " not implemented." << endl;
|
||||
return new NexusSet;
|
||||
}
|
||||
NexusSet*result = expr_->nex_input(rem_out, search_funcs);
|
||||
|
||||
NexusSet* NetCondit::nex_input(bool rem_out)
|
||||
{
|
||||
NexusSet*result = expr_->nex_input(rem_out);
|
||||
if (if_ != 0) {
|
||||
NexusSet*tmp = if_->nex_input(rem_out);
|
||||
NexusSet*tmp = if_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (else_ != 0) {
|
||||
NexusSet*tmp = else_->nex_input(rem_out);
|
||||
NexusSet*tmp = else_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
|
@ -395,51 +409,85 @@ NexusSet* NetCondit::nex_input(bool rem_out)
|
|||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetDoWhile::nex_input(bool rem_out)
|
||||
NexusSet* NetDisable::nex_input(bool, bool) const
|
||||
{
|
||||
NexusSet*result = proc_->nex_input(rem_out);
|
||||
NexusSet*tmp = cond_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetEvWait::nex_input(bool rem_out)
|
||||
{
|
||||
NexusSet*result;
|
||||
if (statement_)
|
||||
result = statement_->nex_input(rem_out);
|
||||
else
|
||||
result = new NexusSet;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetForce::nex_input(bool)
|
||||
{
|
||||
cerr << get_fileline() << ": internal warning: NetForce::nex_input()"
|
||||
<< " not implemented." << endl;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetForLoop::nex_input(bool rem_out)
|
||||
NexusSet* NetDoWhile::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = init_expr_->nex_input(rem_out);
|
||||
NexusSet*result = cond_->nex_input(rem_out, search_funcs);
|
||||
|
||||
NexusSet*tmp = condition_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
if (proc_) {
|
||||
NexusSet*tmp = proc_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
tmp = statement_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
return result;
|
||||
}
|
||||
|
||||
tmp = step_statement_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
NexusSet* NetEvTrig::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetEvWait::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetForever::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetForLoop::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (init_expr_) {
|
||||
NexusSet*tmp = init_expr_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (condition_) {
|
||||
NexusSet*tmp = condition_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (step_statement_) {
|
||||
NexusSet*tmp = step_statement_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if (gn_shared_loop_index_flag) {
|
||||
tmp = new NexusSet();
|
||||
NexusSet*tmp = new NexusSet();
|
||||
for (unsigned idx = 0 ; idx < index_->pin_count() ; idx += 1)
|
||||
tmp->add(index_->pin(idx).nexus(), 0, index_->vector_width());
|
||||
|
||||
|
|
@ -450,10 +498,9 @@ NexusSet* NetForLoop::nex_input(bool rem_out)
|
|||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetForever::nex_input(bool rem_out)
|
||||
NexusSet* NetFree::nex_input(bool, bool) const
|
||||
{
|
||||
NexusSet*result = statement_->nex_input(rem_out);
|
||||
return result;
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -465,36 +512,44 @@ NexusSet* NetForever::nex_input(bool rem_out)
|
|||
* include the input set of the <expr> because it does not affect the
|
||||
* result. The statement can be omitted.
|
||||
*/
|
||||
NexusSet* NetPDelay::nex_input(bool rem_out)
|
||||
NexusSet* NetPDelay::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
if (statement_ == 0) return 0;
|
||||
NexusSet*result = statement_->nex_input(rem_out);
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NexusSet* NetRepeat::nex_input(bool rem_out)
|
||||
NexusSet* NetRepeat::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = statement_->nex_input(rem_out);
|
||||
NexusSet*tmp = expr_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
NexusSet*result = expr_->nex_input(rem_out, search_funcs);
|
||||
|
||||
if (statement_) {
|
||||
NexusSet*tmp = statement_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* The $display, etc. system tasks can have NULL arguments.
|
||||
*/
|
||||
NexusSet* NetSTask::nex_input(bool rem_out)
|
||||
NexusSet* NetSTask::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
if (parms_.empty())
|
||||
return new NexusSet;
|
||||
NexusSet*result = new NexusSet;
|
||||
|
||||
NexusSet*result;
|
||||
if (parms_[0]) result = parms_[0]->nex_input(rem_out);
|
||||
else result = new NexusSet;
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_.empty()) return result;
|
||||
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx]) {
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out);
|
||||
NexusSet*tmp = parms_[idx]->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
|
@ -508,16 +563,20 @@ NexusSet* NetSTask::nex_input(bool rem_out)
|
|||
* parameters to consider, because the compiler already removed them
|
||||
* and converted them to blocking assignments.
|
||||
*/
|
||||
NexusSet* NetUTask::nex_input(bool)
|
||||
NexusSet* NetUTask::nex_input(bool, bool) const
|
||||
{
|
||||
return new NexusSet;
|
||||
}
|
||||
|
||||
NexusSet* NetWhile::nex_input(bool rem_out)
|
||||
NexusSet* NetWhile::nex_input(bool rem_out, bool search_funcs) const
|
||||
{
|
||||
NexusSet*result = proc_->nex_input(rem_out);
|
||||
NexusSet*tmp = cond_->nex_input(rem_out);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
NexusSet*result = cond_->nex_input(rem_out, search_funcs);
|
||||
|
||||
if (proc_) {
|
||||
NexusSet*tmp = proc_->nex_input(rem_out, search_funcs);
|
||||
result->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2017 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
|
||||
|
|
@ -36,8 +36,13 @@ void NetProc::nex_output(NexusSet&)
|
|||
<< endl;
|
||||
}
|
||||
|
||||
void NetAlloc::nex_output(NexusSet&)
|
||||
{
|
||||
}
|
||||
|
||||
void NetAssign_::nex_output(NexusSet&out)
|
||||
{
|
||||
assert(! nest_);
|
||||
assert(sig_);
|
||||
unsigned use_word = 0;
|
||||
unsigned use_base = 0;
|
||||
|
|
@ -89,8 +94,7 @@ void NetAssignBase::nex_output(NexusSet&out)
|
|||
|
||||
void NetBlock::nex_output(NexusSet&out)
|
||||
{
|
||||
if (last_ == 0)
|
||||
return;
|
||||
if (last_ == 0) return;
|
||||
|
||||
NetProc*cur = last_;
|
||||
do {
|
||||
|
|
@ -104,10 +108,8 @@ void NetCase::nex_output(NexusSet&out)
|
|||
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||
|
||||
// Empty statements clearly have no output.
|
||||
if (items_[idx].statement == 0)
|
||||
continue;
|
||||
if (items_[idx].statement == 0) continue;
|
||||
|
||||
assert(items_[idx].statement);
|
||||
items_[idx].statement->nex_output(out);
|
||||
}
|
||||
|
||||
|
|
@ -115,22 +117,31 @@ void NetCase::nex_output(NexusSet&out)
|
|||
|
||||
void NetCondit::nex_output(NexusSet&out)
|
||||
{
|
||||
if (if_ != 0)
|
||||
if_->nex_output(out);
|
||||
if (else_ != 0)
|
||||
else_->nex_output(out);
|
||||
if (if_) if_->nex_output(out);
|
||||
if (else_) else_->nex_output(out);
|
||||
}
|
||||
|
||||
void NetDisable::nex_output(NexusSet&)
|
||||
{
|
||||
}
|
||||
|
||||
void NetDoWhile::nex_output(NexusSet&out)
|
||||
{
|
||||
if (proc_ != 0)
|
||||
proc_->nex_output(out);
|
||||
if (proc_) proc_->nex_output(out);
|
||||
}
|
||||
|
||||
void NetEvTrig::nex_output(NexusSet&)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEvWait::nex_output(NexusSet&out)
|
||||
{
|
||||
assert(statement_);
|
||||
statement_->nex_output(out);
|
||||
if (statement_) statement_->nex_output(out);
|
||||
}
|
||||
|
||||
void NetForever::nex_output(NexusSet&out)
|
||||
{
|
||||
if (statement_) statement_->nex_output(out);
|
||||
}
|
||||
|
||||
void NetForLoop::nex_output(NexusSet&out)
|
||||
|
|
@ -138,11 +149,20 @@ void NetForLoop::nex_output(NexusSet&out)
|
|||
if (statement_) statement_->nex_output(out);
|
||||
}
|
||||
|
||||
void NetFree::nex_output(NexusSet&)
|
||||
{
|
||||
}
|
||||
|
||||
void NetPDelay::nex_output(NexusSet&out)
|
||||
{
|
||||
if (statement_) statement_->nex_output(out);
|
||||
}
|
||||
|
||||
void NetRepeat::nex_output(NexusSet&out)
|
||||
{
|
||||
if (statement_) statement_->nex_output(out);
|
||||
}
|
||||
|
||||
/*
|
||||
* For the purposes of synthesis, system task calls have no output at
|
||||
* all. This is OK because most system tasks are not synthesizable in
|
||||
|
|
@ -163,6 +183,5 @@ void NetUTask::nex_output(NexusSet&)
|
|||
|
||||
void NetWhile::nex_output(NexusSet&out)
|
||||
{
|
||||
if (proc_ != 0)
|
||||
proc_->nex_output(out);
|
||||
if (proc_) proc_->nex_output(out);
|
||||
}
|
||||
|
|
|
|||
63
net_scope.cc
63
net_scope.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -112,10 +112,10 @@ void Definitions::add_class(netclass_t*net_class)
|
|||
* in question.
|
||||
*/
|
||||
|
||||
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest,
|
||||
bool program, bool interface)
|
||||
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, NetScope*in_unit,
|
||||
bool nest, bool program, bool interface, bool compilation_unit)
|
||||
: type_(t), name_(n), nested_module_(nest), program_block_(program),
|
||||
is_interface_(interface), up_(up)
|
||||
is_interface_(interface), is_unit_(compilation_unit), unit_(in_unit), up_(up)
|
||||
{
|
||||
events_ = 0;
|
||||
lcounter_ = 0;
|
||||
|
|
@ -124,6 +124,9 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest,
|
|||
calls_stask_ = false;
|
||||
in_final_ = false;
|
||||
|
||||
if (compilation_unit)
|
||||
unit_ = this;
|
||||
|
||||
if (up) {
|
||||
assert(t!=CLASS);
|
||||
need_const_func_ = up->need_const_func_;
|
||||
|
|
@ -133,6 +136,8 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest,
|
|||
time_from_timescale_ = up->time_from_timescale();
|
||||
// Need to check for duplicate names?
|
||||
up_->children_[name_] = this;
|
||||
if (unit_ == 0)
|
||||
unit_ = up_->unit_;
|
||||
} else {
|
||||
need_const_func_ = false;
|
||||
is_const_func_ = false;
|
||||
|
|
@ -210,6 +215,8 @@ const netenum_t*NetScope::find_enumeration_for_name(perm_string name)
|
|||
NetEConstEnum*tmp = cur_scope->enum_names_[name];
|
||||
if (tmp) break;
|
||||
cur_scope = cur_scope->parent();
|
||||
if (cur_scope == 0)
|
||||
cur_scope = unit_;
|
||||
}
|
||||
|
||||
assert(cur_scope);
|
||||
|
|
@ -304,16 +311,16 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix)
|
|||
*/
|
||||
bool NetScope::replace_parameter(perm_string key, PExpr*val, NetScope*scope)
|
||||
{
|
||||
bool flag = false;
|
||||
if (parameters.find(key) == parameters.end())
|
||||
return false;
|
||||
|
||||
if (parameters.find(key) != parameters.end()) {
|
||||
param_expr_t&ref = parameters[key];
|
||||
ref.val_expr = val;
|
||||
ref.val_scope = scope;
|
||||
flag = true;
|
||||
}
|
||||
param_expr_t&ref = parameters[key];
|
||||
if (ref.local_flag)
|
||||
return false;
|
||||
|
||||
return flag;
|
||||
ref.val_expr = val;
|
||||
ref.val_scope = scope;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetScope::make_parameter_unannotatable(perm_string key)
|
||||
|
|
@ -364,12 +371,7 @@ const NetExpr* NetScope::get_parameter(Design*des,
|
|||
msb = 0;
|
||||
lsb = 0;
|
||||
const NetExpr*tmp = enumeration_expr(key);
|
||||
if (tmp) return tmp;
|
||||
|
||||
tmp = des->enumeration_expr(key);
|
||||
if (tmp) return tmp;
|
||||
|
||||
return 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetScope::param_ref_t NetScope::find_parameter(perm_string key)
|
||||
|
|
@ -386,11 +388,6 @@ NetScope::param_ref_t NetScope::find_parameter(perm_string key)
|
|||
return idx;
|
||||
}
|
||||
|
||||
NetScope::TYPE NetScope::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
void NetScope::print_type(ostream&stream) const
|
||||
{
|
||||
switch (type_) {
|
||||
|
|
@ -657,15 +654,11 @@ netclass_t*NetScope::find_class(perm_string name)
|
|||
if (type_==CLASS && name_==hname_t(name))
|
||||
return class_def_;
|
||||
|
||||
// Look for the class that directly within this scope.
|
||||
// Look for the class directly within this scope.
|
||||
map<perm_string,netclass_t*>::const_iterator cur = classes_.find(name);
|
||||
if (cur != classes_.end())
|
||||
return cur->second;
|
||||
|
||||
// If this is a module scope, then look no further.
|
||||
if (type_==MODULE)
|
||||
return 0;
|
||||
|
||||
if (up_==0 && type_==CLASS) {
|
||||
assert(class_def_);
|
||||
|
||||
|
|
@ -673,12 +666,16 @@ netclass_t*NetScope::find_class(perm_string name)
|
|||
return def_parent->find_class(name);
|
||||
}
|
||||
|
||||
// If there is no further to look, ...
|
||||
if (up_ == 0)
|
||||
return 0;
|
||||
|
||||
// Try looking up for the class.
|
||||
return up_->find_class(name);
|
||||
if (up_!=0 && type_!=MODULE)
|
||||
return up_->find_class(name);
|
||||
|
||||
// Try the compilation unit.
|
||||
if (unit_ != 0)
|
||||
return unit_->find_class(name);
|
||||
|
||||
// Nowhere left to try...
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2017 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
|
||||
|
|
@ -165,7 +165,8 @@ bool netclass_t::test_for_missing_initializers() const
|
|||
NetScope*netclass_t::method_from_name(perm_string name) const
|
||||
{
|
||||
NetScope*task = class_scope_->child( hname_t(name) );
|
||||
if (task == 0) return 0;
|
||||
if ((task == 0) && super_)
|
||||
task = super_->method_from_name(name);
|
||||
return task;
|
||||
|
||||
}
|
||||
|
|
|
|||
679
netlist.cc
679
netlist.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
# include <typeinfo>
|
||||
# include <cstdlib>
|
||||
# include <climits>
|
||||
# include <cstring>
|
||||
# include "compiler.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
|
@ -2768,7 +2769,7 @@ static DelayType delay_type_from_expr(const NetExpr*expr)
|
|||
* The looping structures can use the same basic code so put it here
|
||||
* instead of duplicating it for each one (repeat and while).
|
||||
*/
|
||||
static DelayType get_loop_delay_type(const NetExpr*expr, const NetProc*proc)
|
||||
static DelayType get_loop_delay_type(const NetExpr*expr, const NetProc*proc, bool print_delay)
|
||||
{
|
||||
DelayType result;
|
||||
|
||||
|
|
@ -2779,12 +2780,20 @@ static DelayType get_loop_delay_type(const NetExpr*expr, const NetProc*proc)
|
|||
break;
|
||||
/* We have a constant true expression so the body always runs. */
|
||||
case DEFINITE_DELAY:
|
||||
result = proc->delay_type();
|
||||
if (proc) {
|
||||
result = proc->delay_type(print_delay);
|
||||
} else {
|
||||
result = NO_DELAY;
|
||||
}
|
||||
break;
|
||||
/* We don't know if the body will run so reduce a DEFINITE_DELAY
|
||||
* to a POSSIBLE_DELAY. All other stay the same. */
|
||||
case POSSIBLE_DELAY:
|
||||
result = combine_delays(NO_DELAY, proc->delay_type());
|
||||
if (proc) {
|
||||
result = combine_delays(NO_DELAY, proc->delay_type(print_delay));
|
||||
} else {
|
||||
result = NO_DELAY;
|
||||
}
|
||||
break;
|
||||
/* This should never happen since delay_type_from_expr() only
|
||||
* returns three different values. */
|
||||
|
|
@ -2797,25 +2806,40 @@ static DelayType get_loop_delay_type(const NetExpr*expr, const NetProc*proc)
|
|||
}
|
||||
|
||||
/* The default object does not have any delay. */
|
||||
DelayType NetProc::delay_type() const
|
||||
DelayType NetProc::delay_type(bool /* print_delay */ ) const
|
||||
{
|
||||
return NO_DELAY;
|
||||
}
|
||||
|
||||
DelayType NetBlock::delay_type() const
|
||||
DelayType NetBlock::delay_type(bool print_delay) const
|
||||
{
|
||||
DelayType result = NO_DELAY;
|
||||
// A join_none has no delay.
|
||||
if (type() == PARA_JOIN_NONE) return NO_DELAY;
|
||||
|
||||
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||
DelayType dt = cur->delay_type();
|
||||
if (dt > result) result = dt;
|
||||
if (dt == DEFINITE_DELAY) break;
|
||||
DelayType result;
|
||||
// A join_any has the minimum delay.
|
||||
if (type() == PARA_JOIN_ANY) {
|
||||
result = DEFINITE_DELAY;
|
||||
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||
DelayType dt = cur->delay_type(print_delay);
|
||||
if (dt < result) result = dt;
|
||||
if ((dt == NO_DELAY) && !print_delay) break;
|
||||
}
|
||||
|
||||
// A begin or join has the maximum delay.
|
||||
} else {
|
||||
result = NO_DELAY;
|
||||
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||
DelayType dt = cur->delay_type(print_delay);
|
||||
if (dt > result) result = dt;
|
||||
if ((dt == DEFINITE_DELAY) && !print_delay) break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DelayType NetCase::delay_type() const
|
||||
DelayType NetCase::delay_type(bool print_delay) const
|
||||
{
|
||||
DelayType result = NO_DELAY;
|
||||
bool def_stmt = false;
|
||||
|
|
@ -2823,7 +2847,7 @@ DelayType NetCase::delay_type() const
|
|||
|
||||
for (unsigned idx = 0; idx < nstmts; idx += 1) {
|
||||
if (!expr(idx)) def_stmt = true;
|
||||
DelayType dt = stat(idx) ? stat(idx)->delay_type() : NO_DELAY;
|
||||
DelayType dt = stat(idx) ? stat(idx)->delay_type(print_delay) : NO_DELAY;
|
||||
if (idx == 0) {
|
||||
result = dt;
|
||||
} else {
|
||||
|
|
@ -2831,6 +2855,7 @@ DelayType NetCase::delay_type() const
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: If all the cases are covered (e.g. an enum) then this is not true.
|
||||
/* If we don't have a default statement we don't know for sure
|
||||
* that we have a delay. */
|
||||
if (!def_stmt) result = combine_delays(NO_DELAY, result);
|
||||
|
|
@ -2838,74 +2863,636 @@ DelayType NetCase::delay_type() const
|
|||
return result;
|
||||
}
|
||||
|
||||
DelayType NetCondit::delay_type() const
|
||||
DelayType NetCondit::delay_type(bool print_delay) const
|
||||
{
|
||||
DelayType if_type = if_ ? if_->delay_type() : NO_DELAY;
|
||||
DelayType el_type = else_? else_->delay_type() : NO_DELAY;
|
||||
DelayType if_type = if_ ? if_->delay_type(print_delay) : NO_DELAY;
|
||||
DelayType el_type = else_? else_->delay_type(print_delay) : NO_DELAY;
|
||||
return combine_delays(if_type, el_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* A do/while will execute the body at least once.
|
||||
*/
|
||||
DelayType NetDoWhile::delay_type() const
|
||||
DelayType NetDoWhile::delay_type(bool print_delay) const
|
||||
{
|
||||
ivl_assert(*this, proc_);
|
||||
return proc_->delay_type();
|
||||
if (proc_) return proc_->delay_type(print_delay);
|
||||
|
||||
return ZERO_DELAY;
|
||||
}
|
||||
|
||||
DelayType NetEvWait::delay_type() const
|
||||
DelayType NetEvWait::delay_type(bool print_delay) const
|
||||
{
|
||||
if (print_delay) {
|
||||
cerr << get_fileline() << ": error: an event control is not allowed "
|
||||
"in an always_comb, always_ff or always_latch process."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return DEFINITE_DELAY;
|
||||
}
|
||||
|
||||
DelayType NetForever::delay_type() const
|
||||
DelayType NetForever::delay_type(bool print_delay) const
|
||||
{
|
||||
ivl_assert(*this, statement_);
|
||||
return statement_->delay_type();
|
||||
if (statement_) return statement_->delay_type(print_delay);
|
||||
|
||||
return ZERO_DELAY;
|
||||
}
|
||||
|
||||
DelayType NetForLoop::delay_type() const
|
||||
DelayType NetForLoop::delay_type(bool print_delay) const
|
||||
{
|
||||
ivl_assert(*this, statement_);
|
||||
return get_loop_delay_type(condition_, statement_);
|
||||
return get_loop_delay_type(condition_, statement_, print_delay);
|
||||
}
|
||||
|
||||
DelayType NetPDelay::delay_type() const
|
||||
DelayType NetPDelay::delay_type(bool print_delay) const
|
||||
{
|
||||
if (print_delay) {
|
||||
cerr << get_fileline() << ": error: a blocking delay is not allowed "
|
||||
"in an always_comb, always_ff or always_latch process."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (expr_) {
|
||||
return delay_type_from_expr(expr_);
|
||||
} else {
|
||||
if (delay() > 0) {
|
||||
return DEFINITE_DELAY;
|
||||
if (statement_) {
|
||||
return combine_delays(delay_type_from_expr(expr_),
|
||||
statement_->delay_type(print_delay));
|
||||
} else {
|
||||
if (statement_) {
|
||||
return statement_->delay_type();
|
||||
} else {
|
||||
return NO_DELAY;
|
||||
}
|
||||
return delay_type_from_expr(expr_);
|
||||
}
|
||||
}
|
||||
|
||||
if (delay() > 0) return DEFINITE_DELAY;
|
||||
|
||||
if (statement_) {
|
||||
return combine_delays(ZERO_DELAY,
|
||||
statement_->delay_type(print_delay));
|
||||
} else {
|
||||
return ZERO_DELAY;
|
||||
}
|
||||
}
|
||||
|
||||
DelayType NetRepeat::delay_type(bool print_delay) const
|
||||
{
|
||||
return get_loop_delay_type(expr_, statement_, print_delay);
|
||||
}
|
||||
|
||||
DelayType NetTaskDef::delay_type(bool print_delay) const
|
||||
{
|
||||
if (proc_) {
|
||||
return proc_->delay_type(print_delay);
|
||||
} else {
|
||||
return NO_DELAY;
|
||||
}
|
||||
}
|
||||
|
||||
DelayType NetUTask::delay_type(bool print_delay) const
|
||||
{
|
||||
return task()->task_def()->delay_type(print_delay);
|
||||
}
|
||||
|
||||
static bool do_expr_event_match(const NetExpr*expr, const NetEvWait*evwt)
|
||||
{
|
||||
// The event wait should only have a single event.
|
||||
if (evwt->nevents() != 1) return false;
|
||||
// The event should have a single probe.
|
||||
const NetEvent *evt = evwt->event(0);
|
||||
if (evt->nprobe() != 1) return false;
|
||||
// The probe should be for any edge.
|
||||
const NetEvProbe *prb = evt->probe(0);
|
||||
if (prb->edge() != NetEvProbe::ANYEDGE) return false;
|
||||
// Create a NexusSet from the event probe signals.
|
||||
NexusSet *ns_evwt = new NexusSet;
|
||||
for (unsigned idx =0; idx < prb->pin_count(); idx += 1) {
|
||||
if (! prb->pin(idx).is_linked()) {
|
||||
delete ns_evwt;
|
||||
return false;
|
||||
}
|
||||
// Casting away const is safe since this nexus set is only being read.
|
||||
ns_evwt->add(const_cast<Nexus*> (prb->pin(idx).nexus()),
|
||||
0, prb->pin(idx).nexus()->vector_width());
|
||||
}
|
||||
// Get the NexusSet for the expression.
|
||||
NexusSet *ns_expr = expr->nex_input();
|
||||
// Make sure the event and expression NexusSets match exactly.
|
||||
if (ns_evwt->size() != ns_expr->size()) {
|
||||
delete ns_evwt;
|
||||
delete ns_expr;
|
||||
return false;
|
||||
}
|
||||
ns_expr->rem(*ns_evwt);
|
||||
delete ns_evwt;
|
||||
if (ns_expr->size() != 0) {
|
||||
delete ns_expr;
|
||||
return false;
|
||||
}
|
||||
delete ns_expr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool while_is_wait(const NetExpr*expr, const NetProc*stmt)
|
||||
{
|
||||
if (const NetEvWait*evwt = dynamic_cast<const NetEvWait*>(stmt)) {
|
||||
if (evwt->statement()) return false;
|
||||
const NetEBComp*cond = dynamic_cast<const NetEBComp*>(expr);
|
||||
if (! cond) return false;
|
||||
if (cond->op() != 'N') return false;
|
||||
const NetEConst*cval = dynamic_cast<const NetEConst*>(cond->right());
|
||||
if (! cval) return false;
|
||||
const verinum val = cval->value();
|
||||
if (val.len() != 1) return false;
|
||||
if (val.get(0) != verinum::V1) return false;
|
||||
if (! do_expr_event_match(cond->left(), evwt)) return false;
|
||||
if (evwt->get_lineno() != cond->get_lineno()) return false;
|
||||
if (evwt->get_file() != cond->get_file()) return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DelayType NetWhile::delay_type(bool print_delay) const
|
||||
{
|
||||
// If the wait was a constant value the compiler already removed it
|
||||
// so we know we can only have a possible delay.
|
||||
if (while_is_wait(cond_, proc_)) {
|
||||
if (print_delay) {
|
||||
cerr << get_fileline() << ": error: a wait statement is "
|
||||
"not allowed in an "
|
||||
"always_comb, always_ff or always_latch process."
|
||||
<< endl;
|
||||
}
|
||||
return POSSIBLE_DELAY;
|
||||
}
|
||||
return get_loop_delay_type(cond_, proc_, print_delay);
|
||||
}
|
||||
|
||||
/*
|
||||
* These are the check_synth() functions. They are used to print
|
||||
* a warning if the item is not synthesizable.
|
||||
*/
|
||||
static const char * get_process_type_as_string(ivl_process_type_t pr_type)
|
||||
{
|
||||
switch (pr_type) {
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
return "in an always_comb process.";
|
||||
break;
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
return "in an always_ff process.";
|
||||
break;
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
return "in an always_latch process.";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_synth_warning(const NetProc *net_proc, const char *name,
|
||||
ivl_process_type_t pr_type)
|
||||
{
|
||||
cerr << net_proc->get_fileline() << ": warning: " << name
|
||||
<< " statement cannot be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
|
||||
static void check_if_logic_l_value(const NetAssignBase *base,
|
||||
ivl_process_type_t pr_type)
|
||||
{
|
||||
if (base->l_val_count() != 1) return;
|
||||
|
||||
const NetAssign_*lval = base->l_val(0);
|
||||
if (! lval) return;
|
||||
|
||||
NetNet*sig = lval->sig();
|
||||
if (! sig) return;
|
||||
|
||||
if ((sig->data_type() != IVL_VT_BOOL) &&
|
||||
(sig->data_type() != IVL_VT_LOGIC)) {
|
||||
cerr << base->get_fileline() << ": warning: Assinging to a "
|
||||
"non-integral variable ("<< sig->name()
|
||||
<< ") cannot be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* By default elements can be synthesized or ignored. */
|
||||
bool NetProc::check_synth(ivl_process_type_t /* pr_type */,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: User function calls still need to be checked (NetEUFunc).
|
||||
// : Non-constant system functions need a warning (NetESFunc).
|
||||
// : Constant functions should already be elaborated.
|
||||
|
||||
/* By default assign elements can be synthesized. */
|
||||
bool NetAssignBase::check_synth(ivl_process_type_t /* pr_type */,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetAssign::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
check_if_logic_l_value(this, pr_type);
|
||||
|
||||
// FIXME: Check that ff/latch only use this for internal signals.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetAssignNB::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
bool result = false;
|
||||
if (pr_type == IVL_PR_ALWAYS_COMB) {
|
||||
cerr << get_fileline() << ": warning: A non-blocking assignment "
|
||||
"should not be used in an always_comb process." << endl;
|
||||
}
|
||||
|
||||
if (event_) {
|
||||
cerr << get_fileline() << ": error: A non-blocking assignment "
|
||||
"cannot be synthesized with an event control "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
result = true;
|
||||
}
|
||||
|
||||
check_if_logic_l_value(this, pr_type);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetBlock::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
bool result = false;
|
||||
// Only a begin/end can be synthesized.
|
||||
if (type() != SEQU) {
|
||||
cerr << get_fileline() << ": error: A fork/";
|
||||
switch (type()) {
|
||||
case PARA:
|
||||
cerr << "join";
|
||||
break;
|
||||
case PARA_JOIN_ANY:
|
||||
cerr << "join_any";
|
||||
break;
|
||||
case PARA_JOIN_NONE:
|
||||
cerr << "join_none";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
cerr << " statement cannot be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
result = true;
|
||||
}
|
||||
|
||||
const NetScope*save_scope = scope;
|
||||
if (subscope()) scope = subscope();
|
||||
if (scope != save_scope) {
|
||||
result |= scope->check_synth(pr_type, scope);
|
||||
}
|
||||
for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) {
|
||||
result |= cur->check_synth(pr_type, scope);
|
||||
}
|
||||
scope = save_scope;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetCase::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
bool result = false;
|
||||
for (unsigned idx = 0; idx < nitems(); idx += 1) {
|
||||
if (stat(idx)) result |= stat(idx)->check_synth(pr_type, scope);
|
||||
}
|
||||
// FIXME: Check for ff/latch/comb structures.
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetCAssign::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
print_synth_warning(this, "A procedural assign", pr_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetCondit::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
bool result = false;
|
||||
if (if_) result |= if_->check_synth(pr_type, scope);
|
||||
if (else_) result |= else_->check_synth(pr_type, scope);
|
||||
// FIXME: Check for ff/latch/comb structures.
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetDeassign::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
print_synth_warning(this, "A procedural deassign", pr_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetDisable::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
while (scope) {
|
||||
if (scope != target_) scope = scope->parent();
|
||||
else break;
|
||||
}
|
||||
|
||||
|
||||
if (! scope) {
|
||||
cerr << get_fileline() << ": warning: A disable statement can "
|
||||
"only be synthesized when disabling an enclosing block "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetDoWhile::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
bool result = false;
|
||||
print_synth_warning(this, "A do/while", pr_type);
|
||||
if (proc_) result |= proc_->check_synth(pr_type, scope);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetEvTrig::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
print_synth_warning(this, "An event trigger", pr_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The delay check above has already marked this as an error.
|
||||
bool NetEvWait::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
bool result = false;
|
||||
if (statement_) result |= statement_->check_synth(pr_type, scope);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetForce::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
print_synth_warning(this, "A force", pr_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetForever::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
bool result = false;
|
||||
print_synth_warning(this, "A forever", pr_type);
|
||||
if (statement_) result |= statement_->check_synth(pr_type, scope);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* A bunch of private routines to verify that a for loop has the correct
|
||||
* structure for synthesis.
|
||||
*/
|
||||
static void print_for_idx_warning(const NetProc*proc, const char*check,
|
||||
ivl_process_type_t pr_type, NetNet*idx)
|
||||
{
|
||||
cerr << proc->get_fileline() << ": warning: A for statement must use "
|
||||
"the index (" << idx->name() << ") in the " << check
|
||||
<< " expression to be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
|
||||
static void check_for_const_synth(const NetExpr*expr, const NetProc*proc,
|
||||
const char*str, ivl_process_type_t pr_type)
|
||||
{
|
||||
if (! dynamic_cast<const NetEConst*>(expr)) {
|
||||
cerr << proc-> get_fileline() << ": warning: A for "
|
||||
"statement must " << str
|
||||
<< " value to be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void check_for_bin_synth(const NetExpr*left,const NetExpr*right,
|
||||
const char*str, const char*check,
|
||||
const NetProc*proc,
|
||||
ivl_process_type_t pr_type, NetNet*index)
|
||||
{
|
||||
const NetESignal*lsig = dynamic_cast<const NetESignal*>(left);
|
||||
const NetESignal*rsig = dynamic_cast<const NetESignal*>(right);
|
||||
|
||||
if (lsig && (lsig->sig() == index)) {
|
||||
check_for_const_synth(right, proc, str, pr_type);
|
||||
} else if (rsig && (rsig->sig() == index)) {
|
||||
check_for_const_synth(left, proc, str, pr_type);
|
||||
} else {
|
||||
print_for_idx_warning(proc, check, pr_type, index);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_for_step_warning(const NetProc*proc,
|
||||
ivl_process_type_t pr_type)
|
||||
{
|
||||
cerr << proc->get_fileline() << ": warning: A for statement step must "
|
||||
"be a simple assignment statement to be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
|
||||
static void print_for_step_warning(const NetProc*proc,
|
||||
ivl_process_type_t pr_type, NetNet*idx)
|
||||
{
|
||||
cerr << proc->get_fileline() << ": warning: A for statement step must "
|
||||
"be an assignment to the index variable ("
|
||||
<< idx->name() << ") to be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
|
||||
static void check_for_bstep_synth(const NetExpr*expr, const NetProc*proc,
|
||||
ivl_process_type_t pr_type, NetNet*index)
|
||||
{
|
||||
if (const NetECast*tmp = dynamic_cast<const NetECast*>(expr)) {
|
||||
expr = tmp->expr();
|
||||
}
|
||||
|
||||
if (const NetEBAdd*tmp = dynamic_cast<const NetEBAdd*>(expr)) {
|
||||
check_for_bin_synth(tmp->left(), tmp->right(),
|
||||
"change by a constant", "step", proc, pr_type,
|
||||
index);
|
||||
} else {
|
||||
cerr << proc->get_fileline() << ": warning: A for statement "
|
||||
"step must be a simple binary +/- "
|
||||
"to be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void check_for_step_synth(const NetAssign*assign, const NetProc*proc,
|
||||
ivl_process_type_t pr_type, NetNet*index)
|
||||
{
|
||||
if (assign->l_val_count() != 1) {
|
||||
print_for_step_warning(proc, pr_type);
|
||||
} else if (assign->l_val(0)->sig() != index) {
|
||||
print_for_step_warning(proc, pr_type, index);
|
||||
} else {
|
||||
switch (assign->assign_operator()) {
|
||||
case '+':
|
||||
case '-':
|
||||
check_for_const_synth(assign->rval(), proc,
|
||||
"have a constant step", pr_type);
|
||||
break;
|
||||
case 0:
|
||||
check_for_bstep_synth(assign->rval(), proc, pr_type, index);
|
||||
break;
|
||||
default:
|
||||
cerr << proc->get_fileline() << ": warning: A for statement "
|
||||
"step does not support operator '"
|
||||
<< assign->assign_operator()
|
||||
<< "' it must be +/- to be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DelayType NetRepeat::delay_type() const
|
||||
bool NetForLoop::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
ivl_assert(*this, statement_);
|
||||
return get_loop_delay_type(expr_, statement_);
|
||||
bool result = false;
|
||||
|
||||
// FIXME: What about an enum (NetEConstEnum)?
|
||||
if (! dynamic_cast<const NetEConst*>(init_expr_)) {
|
||||
cerr << get_fileline() << ": warning: A for statement must "
|
||||
"have a constant initial value to be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
|
||||
// FIXME: Do the following also need to be supported in the condition?
|
||||
// It would seem like they are hard to use to find the bounds.
|
||||
// From NetEBinary
|
||||
// What about NetEBits sig & constant, etc.
|
||||
// From NetEUnary
|
||||
// What about NetEUBits ! sig or ! (sig == constat)
|
||||
// What about NetEUReduce &signal
|
||||
if (const NetESignal*tmp = dynamic_cast<const NetESignal*>(condition_)) {
|
||||
if (tmp->sig() != index_) {
|
||||
print_for_idx_warning(this, "condition", pr_type, index_);
|
||||
}
|
||||
} else if (const NetEBComp*cmp = dynamic_cast<const NetEBComp*>(condition_)) {
|
||||
check_for_bin_synth(cmp->left(), cmp->right(),
|
||||
"compare against a constant", "condition",
|
||||
this, pr_type, index_);
|
||||
} else {
|
||||
print_for_idx_warning(this, "condition", pr_type, index_);
|
||||
}
|
||||
|
||||
if (const NetAssign*tmp = dynamic_cast<const NetAssign*>(step_statement_)) {
|
||||
check_for_step_synth(tmp, this, pr_type, index_);
|
||||
} else {
|
||||
print_for_step_warning(this, pr_type);
|
||||
}
|
||||
|
||||
if (statement_) result |= statement_->check_synth(pr_type, scope);
|
||||
return result;
|
||||
}
|
||||
|
||||
DelayType NetTaskDef::delay_type() const
|
||||
// The delay check above has already marked this as an error.
|
||||
bool NetPDelay::check_synth(ivl_process_type_t /* pr_type */,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
return proc_->delay_type();
|
||||
return false;
|
||||
}
|
||||
|
||||
DelayType NetUTask::delay_type() const
|
||||
bool NetRelease::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */ ) const
|
||||
{
|
||||
return task()->task_def()->delay_type();
|
||||
print_synth_warning(this, "A release", pr_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
DelayType NetWhile::delay_type() const
|
||||
bool NetRepeat::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
ivl_assert(*this, proc_);
|
||||
return get_loop_delay_type(cond_, proc_);
|
||||
bool result = false;
|
||||
print_synth_warning(this, "A repeat", pr_type);
|
||||
if (statement_) result |= statement_->check_synth(pr_type, scope);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetScope::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */) const
|
||||
{
|
||||
bool result = false;
|
||||
// Skip local events/signals
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
|
||||
if (cur->local_flag()) continue;
|
||||
cerr << cur->get_fileline() << ": warning: An event ("
|
||||
<< cur->name() << ") cannot be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
for (signals_map_iter_t cur = signals_map_.begin();
|
||||
cur != signals_map_.end() ; ++ cur) {
|
||||
const NetNet*sig = cur->second;
|
||||
if ((sig->data_type() != IVL_VT_BOOL) &&
|
||||
(sig->data_type() != IVL_VT_LOGIC)) {
|
||||
cerr << sig->get_fileline() << ": warning: A non-integral "
|
||||
"variable (" << sig->name() << ") cannot be "
|
||||
"synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetSTask::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */) const
|
||||
{
|
||||
if (strcmp(name(), "$ivl_darray_method$delete") == 0) {
|
||||
cerr << get_fileline() << ": warning: Dynamic array "
|
||||
"delete method cannot be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
} else {
|
||||
cerr << get_fileline() << ": warning: System task ("
|
||||
<< name() << ") cannot be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetTaskDef::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */) const
|
||||
{
|
||||
bool result = false;
|
||||
const NetScope *tscope = this->scope();
|
||||
result |= tscope->check_synth(pr_type, tscope);
|
||||
if (! tscope->is_auto()) {
|
||||
cerr << tscope->get_def_file() << ":"
|
||||
<< tscope->get_def_lineno()
|
||||
<< ": warning: user task (" << tscope->basename()
|
||||
<< ") must be automatic to be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
}
|
||||
if (proc_) result |= proc_->check_synth(pr_type, tscope);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetUTask::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
return task()->task_def()->check_synth(pr_type, scope);
|
||||
}
|
||||
|
||||
bool NetWhile::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* scope) const
|
||||
{
|
||||
bool result = false;
|
||||
// A wait is already maked as an error in the delay check above.
|
||||
if (! while_is_wait(cond_, proc_)) {
|
||||
print_synth_warning(this, "A while", pr_type);
|
||||
if (proc_) result |= proc_->check_synth(pr_type, scope);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
216
netlist.h
216
netlist.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_netlist_H
|
||||
#define IVL_netlist_H
|
||||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -927,10 +927,13 @@ class NetScope : public Definitions, public Attrib {
|
|||
public:
|
||||
enum TYPE { MODULE, CLASS, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE };
|
||||
|
||||
/* Create a new scope, and attach it to the given parent. The
|
||||
name is expected to have been permallocated. */
|
||||
NetScope(NetScope*up, const hname_t&name, TYPE t, bool nest=false,
|
||||
bool program=false, bool interface=false);
|
||||
/* Create a new scope associated with a given compilation unit,
|
||||
and attach it to the given parent. If no compilation unit is
|
||||
specified, the parent's compilation unit is used. The name
|
||||
is expected to have been permallocated. */
|
||||
NetScope(NetScope*up, const hname_t&name, TYPE t, NetScope*in_unit=0,
|
||||
bool nest=false, bool program=false, bool interface=false,
|
||||
bool compilation_unit=false);
|
||||
~NetScope();
|
||||
|
||||
/* Rename the scope using the name generated by inserting as
|
||||
|
|
@ -1002,10 +1005,12 @@ class NetScope : public Definitions, public Attrib {
|
|||
|
||||
netclass_t* find_class(perm_string name);
|
||||
|
||||
/* The parent and child() methods allow users of NetScope
|
||||
objects to locate nearby scopes. */
|
||||
/* The unit(), parent(), and child() methods allow users of
|
||||
NetScope objects to locate nearby scopes. */
|
||||
NetScope* unit() { return unit_; }
|
||||
NetScope* parent() { return up_; }
|
||||
NetScope* child(const hname_t&name);
|
||||
const NetScope* unit() const { return unit_; }
|
||||
const NetScope* parent() const { return up_; }
|
||||
const NetScope* child(const hname_t&name) const;
|
||||
|
||||
|
|
@ -1023,7 +1028,8 @@ class NetScope : public Definitions, public Attrib {
|
|||
// Program blocks and interfaces have elaboration constraints.
|
||||
inline bool program_block() const { return program_block_; }
|
||||
inline bool is_interface() const { return is_interface_; }
|
||||
TYPE type() const;
|
||||
inline bool is_unit() const { return is_unit_; }
|
||||
inline TYPE type() const { return type_; }
|
||||
void print_type(ostream&) const;
|
||||
|
||||
// This provides a link to the variable initialisation process
|
||||
|
|
@ -1152,6 +1158,9 @@ class NetScope : public Definitions, public Attrib {
|
|||
perm_string local_symbol();
|
||||
|
||||
void dump(ostream&) const;
|
||||
// Check to see if the scope has items that are not allowed
|
||||
// in an always_comb/ff/latch process.
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
void emit_scope(struct target_t*tgt) const;
|
||||
bool emit_defs(struct target_t*tgt) const;
|
||||
|
||||
|
|
@ -1249,6 +1258,8 @@ class NetScope : public Definitions, public Attrib {
|
|||
bool program_block_;
|
||||
// True if the scope is an interface
|
||||
bool is_interface_;
|
||||
// True if the scope is a compilation unit
|
||||
bool is_unit_;
|
||||
|
||||
perm_string file_;
|
||||
perm_string def_file_;
|
||||
|
|
@ -1279,6 +1290,7 @@ class NetScope : public Definitions, public Attrib {
|
|||
const PFunction*func_pform_;
|
||||
unsigned elab_stage_;
|
||||
|
||||
NetScope*unit_;
|
||||
NetScope*up_;
|
||||
map<hname_t,NetScope*> children_;
|
||||
|
||||
|
|
@ -2036,7 +2048,7 @@ class NetExpr : public LineInfo {
|
|||
// Get the Nexus that are the input to this
|
||||
// expression. Normally this descends down to the reference to
|
||||
// a signal that reads from its input.
|
||||
virtual NexusSet* nex_input(bool rem_out = true) =0;
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const =0;
|
||||
|
||||
// Return a version of myself that is structural. This is used
|
||||
// for converting expressions to gates. The arguments are:
|
||||
|
|
@ -2079,7 +2091,7 @@ class NetEArrayPattern : public NetExpr {
|
|||
void dump(ostream&) const;
|
||||
|
||||
NetEArrayPattern* dup_expr() const;
|
||||
NexusSet* nex_input(bool rem_out =true);
|
||||
NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
private:
|
||||
std::vector<NetExpr*> items_;
|
||||
|
|
@ -2112,7 +2124,7 @@ class NetEConst : public NetExpr {
|
|||
|
||||
virtual NetEConst* dup_expr() const;
|
||||
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
|
@ -2184,7 +2196,7 @@ class NetECReal : public NetExpr {
|
|||
|
||||
virtual NetECReal* dup_expr() const;
|
||||
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
|
@ -2356,6 +2368,8 @@ class NetCaseCmp : public NetNode {
|
|||
enum kind_t {
|
||||
EEQ, // ===
|
||||
NEQ, // !==
|
||||
WEQ, // ==?
|
||||
WNE, // !=?
|
||||
XEQ, // casex guard tests
|
||||
ZEQ // casez guard tests
|
||||
};
|
||||
|
|
@ -2626,7 +2640,7 @@ class NetProc : public virtual LineInfo {
|
|||
// Find the nexa that are input by the statement. This is used
|
||||
// for example by @* to find the inputs to the process for the
|
||||
// sensitivity list.
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
// Find the nexa that are set by the statement. Add the output
|
||||
// values to the set passed as a parameter.
|
||||
|
|
@ -2704,7 +2718,9 @@ class NetProc : public virtual LineInfo {
|
|||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
// Recursively checks to see if there is delay in this element.
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
// Check to see if the item is synthesizable.
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
protected:
|
||||
bool synth_async_block_substatement_(Design*des, NetScope*scope,
|
||||
|
|
@ -2732,6 +2748,8 @@ class NetAlloc : public NetProc {
|
|||
|
||||
const NetScope* scope() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
|
|
@ -2839,7 +2857,7 @@ class NetAssign_ {
|
|||
// being outputs. For example foo[idx] = ... is the l-value
|
||||
// (NetAssign_ object) with a foo l-value and the input
|
||||
// expression idx.
|
||||
NexusSet* nex_input(bool rem_out = true);
|
||||
NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
// Figuring out nex_output to process ultimately comes down to
|
||||
// this method.
|
||||
|
|
@ -2887,7 +2905,7 @@ class NetAssignBase : public NetProc {
|
|||
void set_delay(NetExpr*);
|
||||
const NetExpr* get_delay() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&o);
|
||||
|
||||
|
||||
|
|
@ -2902,6 +2920,7 @@ class NetAssignBase : public NetProc {
|
|||
// This dumps all the lval structures.
|
||||
void dump_lval(ostream&) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetAssign_*lval_;
|
||||
|
|
@ -2923,6 +2942,7 @@ class NetAssign : public NetAssignBase {
|
|||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -2945,6 +2965,7 @@ class NetAssignNB : public NetAssignBase {
|
|||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
unsigned nevents() const;
|
||||
const NetEvent*event(unsigned) const;
|
||||
|
|
@ -3002,12 +3023,13 @@ class NetBlock : public NetProc {
|
|||
// for sequential blocks.
|
||||
void emit_recurse(struct target_t*) const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const Type type_;
|
||||
|
|
@ -3045,7 +3067,7 @@ class NetCase : public NetProc {
|
|||
inline const NetExpr*expr(unsigned idx) const { return items_[idx].guard;}
|
||||
inline const NetProc*stat(unsigned idx) const { return items_[idx].statement; }
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&out);
|
||||
|
||||
bool synth_async(Design*des, NetScope*scope,
|
||||
|
|
@ -3054,7 +3076,8 @@ class NetCase : public NetProc {
|
|||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -3091,9 +3114,9 @@ class NetCAssign : public NetAssignBase {
|
|||
explicit NetCAssign(NetAssign_*lv, NetExpr*rv);
|
||||
~NetCAssign();
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private: // not implemented
|
||||
NetCAssign(const NetCAssign&);
|
||||
|
|
@ -3124,7 +3147,7 @@ class NetCondit : public NetProc {
|
|||
bool emit_recurse_if(struct target_t*) const;
|
||||
bool emit_recurse_else(struct target_t*) const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&o);
|
||||
|
||||
bool is_asynchronous();
|
||||
|
|
@ -3144,7 +3167,8 @@ class NetCondit : public NetProc {
|
|||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -3190,6 +3214,7 @@ class NetDeassign : public NetAssignBase {
|
|||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private: // not implemented
|
||||
NetDeassign(const NetDeassign&);
|
||||
|
|
@ -3213,8 +3238,11 @@ class NetDisable : public NetProc {
|
|||
|
||||
const NetScope*target() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -3241,11 +3269,12 @@ class NetDoWhile : public NetProc {
|
|||
|
||||
void emit_proc_recurse(struct target_t*) const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -3302,6 +3331,9 @@ class NetEvent : public LineInfo {
|
|||
|
||||
perm_string name() const;
|
||||
|
||||
bool local_flag() const { return local_flag_; }
|
||||
void local_flag(bool f) { local_flag_ = f; }
|
||||
|
||||
// Get information about probes connected to me.
|
||||
unsigned nprobe() const;
|
||||
NetEvProbe* probe(unsigned);
|
||||
|
|
@ -3333,6 +3365,7 @@ class NetEvent : public LineInfo {
|
|||
|
||||
private:
|
||||
perm_string name_;
|
||||
bool local_flag_;
|
||||
|
||||
// The NetScope class uses these to list the events.
|
||||
NetScope*scope_;
|
||||
|
|
@ -3370,8 +3403,11 @@ class NetEvTrig : public NetProc {
|
|||
|
||||
const NetEvent*event() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetEvent*event_;
|
||||
|
|
@ -3387,12 +3423,15 @@ class NetEvWait : public NetProc {
|
|||
|
||||
void add_event(NetEvent*tgt);
|
||||
void replace_event(NetEvent*orig, NetEvent*repl);
|
||||
inline void set_t0_trigger() { has_t0_trigger_ = true; };
|
||||
|
||||
inline unsigned nevents() const { return events_.size(); }
|
||||
inline const NetEvent*event(unsigned idx) const { return events_[idx]; }
|
||||
inline NetEvent*event(unsigned idx) { return events_[idx]; }
|
||||
inline bool has_t0_trigger() const { return has_t0_trigger_; };
|
||||
|
||||
NetProc*statement();
|
||||
const NetProc*statement() const;
|
||||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
bool emit_recurse(struct target_t*) const;
|
||||
|
|
@ -3406,7 +3445,7 @@ class NetEvWait : public NetProc {
|
|||
// process? This method checks.
|
||||
virtual bool is_synchronous();
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&out);
|
||||
|
||||
virtual bool synth_async(Design*des, NetScope*scope,
|
||||
|
|
@ -3425,12 +3464,14 @@ class NetEvWait : public NetProc {
|
|||
virtual void dump(ostream&, unsigned ind) const;
|
||||
// This will ignore any statement.
|
||||
virtual void dump_inline(ostream&) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc*statement_;
|
||||
// Events that I might wait for.
|
||||
std::vector<NetEvent*>events_;
|
||||
bool has_t0_trigger_;
|
||||
};
|
||||
|
||||
ostream& operator << (ostream&out, const NetEvWait&obj);
|
||||
|
|
@ -3473,10 +3514,9 @@ class NetForce : public NetAssignBase {
|
|||
explicit NetForce(NetAssign_*l, NetExpr*r);
|
||||
~NetForce();
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -3491,10 +3531,12 @@ class NetForever : public NetProc {
|
|||
|
||||
void emit_recurse(struct target_t*) const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -3513,11 +3555,12 @@ class NetForLoop : public NetProc {
|
|||
|
||||
void emit_recurse(struct target_t*) const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -3550,6 +3593,8 @@ class NetFree : public NetProc {
|
|||
|
||||
const NetScope* scope() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
|
|
@ -3613,12 +3658,13 @@ class NetPDelay : public NetProc {
|
|||
uint64_t delay() const;
|
||||
const NetExpr*expr() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
bool emit_proc_recurse(struct target_t*) const;
|
||||
|
||||
|
|
@ -3640,10 +3686,12 @@ class NetRepeat : public NetProc {
|
|||
const NetExpr*expr() const;
|
||||
void emit_recurse(struct target_t*) const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -3666,6 +3714,7 @@ class NetRelease : public NetAssignBase {
|
|||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
@ -3691,10 +3740,11 @@ class NetSTask : public NetProc {
|
|||
|
||||
const NetExpr* parm(unsigned idx) const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
|
|
@ -3724,7 +3774,8 @@ class NetTaskDef : public NetBaseDef {
|
|||
~NetTaskDef();
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
DelayType delay_type() const;
|
||||
DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private: // not implemented
|
||||
NetTaskDef(const NetTaskDef&);
|
||||
|
|
@ -3750,7 +3801,7 @@ class NetELast : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetELast*dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
private:
|
||||
NetNet*sig_;
|
||||
|
|
@ -3779,7 +3830,7 @@ class NetEUFunc : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetEUFunc*dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual NetExpr* eval_tree();
|
||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
|
@ -3815,7 +3866,7 @@ class NetEAccess : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetEAccess*dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
private:
|
||||
NetBranch*branch_;
|
||||
|
|
@ -3837,11 +3888,12 @@ class NetUTask : public NetProc {
|
|||
|
||||
const NetScope* task() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetScope*task_;
|
||||
|
|
@ -3862,16 +3914,17 @@ class NetWhile : public NetProc {
|
|||
|
||||
void emit_proc_recurse(struct target_t*) const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void nex_output(NexusSet&);
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual DelayType delay_type() const;
|
||||
virtual DelayType delay_type(bool print_delay=false) const;
|
||||
virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
|
||||
virtual bool evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
private:
|
||||
NetExpr* cond_;
|
||||
NetExpr*cond_;
|
||||
NetProc*proc_;
|
||||
};
|
||||
|
||||
|
|
@ -4005,7 +4058,7 @@ class NetEBinary : public NetExpr {
|
|||
virtual NetExpr* eval_tree();
|
||||
virtual NetExpr* evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
|
@ -4128,6 +4181,7 @@ class NetEBComp : public NetEBinary {
|
|||
NetEConst*eval_gt_(const NetExpr*le, const NetExpr*re) const;
|
||||
NetEConst*eval_gteq_(const NetExpr*le, const NetExpr*re) const;
|
||||
NetEConst*eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const;
|
||||
NetEConst*eval_weqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -4258,7 +4312,7 @@ class NetEConcat : public NetExpr {
|
|||
NetExpr* parm(unsigned idx) const { return parms_[idx]; }
|
||||
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual bool has_width() const;
|
||||
virtual NetEConcat* dup_expr() const;
|
||||
virtual NetEConst* eval_tree();
|
||||
|
|
@ -4306,7 +4360,7 @@ class NetESelect : public NetExpr {
|
|||
// sub-expression.
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual bool has_width() const;
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetEConst* eval_tree();
|
||||
|
|
@ -4335,7 +4389,7 @@ class NetEEvent : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetEEvent* dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual void dump(ostream&os) const;
|
||||
|
||||
|
|
@ -4358,7 +4412,7 @@ class NetENetenum : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetENetenum* dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual void dump(ostream&os) const;
|
||||
|
||||
|
|
@ -4382,7 +4436,7 @@ class NetENew : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetENew* dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual void dump(ostream&os) const;
|
||||
|
||||
|
|
@ -4404,7 +4458,7 @@ class NetENull : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetENull* dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual void dump(ostream&os) const;
|
||||
};
|
||||
|
|
@ -4430,7 +4484,7 @@ class NetEProperty : public NetExpr {
|
|||
ivl_variable_type_t expr_type() const;
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetEProperty* dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual void dump(ostream&os) const;
|
||||
|
||||
|
|
@ -4455,7 +4509,7 @@ class NetEScope : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetEScope* dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual void dump(ostream&os) const;
|
||||
|
||||
|
|
@ -4489,7 +4543,7 @@ class NetESFunc : public NetExpr {
|
|||
map<perm_string,LocalVar>&ctx) const;
|
||||
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual const netenum_t* enumeration() const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
|
|
@ -4551,7 +4605,7 @@ class NetESFunc : public NetExpr {
|
|||
/* Added in SystemVerilog 2009 and later. */
|
||||
CTONES = 0x00020024, /* $countones takes one argument. */
|
||||
/* Added in SystemVerilog 2012 and later. */
|
||||
CTBITS = 0xfffe0025, /* $countbits takes one or more arguments. */
|
||||
CTBITS = 0xfffc0025, /* $countbits takes two or more arguments. */
|
||||
/* Added as Icarus extensions to Verilog-A. */
|
||||
ABS = 0x00020026, /* $abs takes one argument. */
|
||||
MAX = 0x00040027, /* $max takes two argument. */
|
||||
|
|
@ -4561,7 +4615,7 @@ class NetESFunc : public NetExpr {
|
|||
|
||||
bool takes_nargs_(ID func, unsigned nargs) {
|
||||
if (nargs > 15) nargs = 15;
|
||||
return func & (1 << (nargs + 16));
|
||||
return func & (1U << (nargs + 16));
|
||||
}
|
||||
|
||||
const char* name_;
|
||||
|
|
@ -4603,8 +4657,7 @@ class NetESFunc : public NetExpr {
|
|||
NetEConst* evaluate_array_funcs_(ID id,
|
||||
const NetExpr*arg0,
|
||||
const NetExpr*arg1) const;
|
||||
NetEConst* evaluate_countbits_(const NetExpr*arg0,
|
||||
const NetExpr*arg1) const;
|
||||
NetEConst* evaluate_countbits_(void) const;
|
||||
|
||||
public:
|
||||
bool is_built_in() const { return built_in_id_() != NOT_BUILT_IN; };
|
||||
|
|
@ -4624,7 +4677,7 @@ class NetEShallowCopy : public NetExpr {
|
|||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetEShallowCopy* dup_expr() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
|
||||
virtual void dump(ostream&os) const;
|
||||
|
||||
|
|
@ -4656,7 +4709,7 @@ class NetETernary : public NetExpr {
|
|||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||
map<perm_string,LocalVar>&ctx) const;
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||
|
|
@ -4711,7 +4764,7 @@ class NetEUnary : public NetExpr {
|
|||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||
|
||||
virtual ivl_variable_type_t expr_type() const;
|
||||
virtual NexusSet* nex_input(bool rem_out = true);
|
||||
virtual NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
|
|
@ -4787,7 +4840,7 @@ class NetESignal : public NetExpr {
|
|||
|
||||
virtual NetESignal* dup_expr() const;
|
||||
NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
|
||||
NexusSet* nex_input(bool rem_out = true);
|
||||
NexusSet* nex_input(bool rem_out = true, bool search_funcs = false) const;
|
||||
const netenum_t*enumeration() const;
|
||||
|
||||
virtual NetExpr*evaluate_function(const LineInfo&loc,
|
||||
|
|
@ -4835,7 +4888,7 @@ struct elaborator_work_item_t {
|
|||
* This class contains an entire design. It includes processes and a
|
||||
* netlist, and can be passed around from function to function.
|
||||
*/
|
||||
class Design : public Definitions {
|
||||
class Design {
|
||||
|
||||
public:
|
||||
Design();
|
||||
|
|
@ -4857,12 +4910,13 @@ class Design : public Definitions {
|
|||
|
||||
const char* get_flag(const string&key) const;
|
||||
|
||||
NetScope* make_root_scope(perm_string name, bool program_block,
|
||||
bool is_interface);
|
||||
NetScope* make_root_scope(perm_string name, NetScope*unit_scope,
|
||||
bool program_block, bool is_interface);
|
||||
NetScope* find_root_scope();
|
||||
std::list<NetScope*> find_root_scopes() const;
|
||||
|
||||
NetScope* make_package_scope(perm_string name);
|
||||
NetScope* make_package_scope(perm_string name, NetScope*unit_scope,
|
||||
bool is_unit);
|
||||
std::list<NetScope*> find_package_scopes() const;
|
||||
|
||||
/* Attempt to set the precision to the specified value. If the
|
||||
|
|
@ -4912,11 +4966,6 @@ class Design : public Definitions {
|
|||
// Look for defparams that never matched, and print warnings.
|
||||
void residual_defparams();
|
||||
|
||||
// Do elaborate_sig for objects in $root scope.
|
||||
void root_elaborate_sig(void);
|
||||
|
||||
void root_elaborate(void);
|
||||
|
||||
/* This method locates a signal, starting at a given
|
||||
scope. The name parameter may be partially hierarchical, so
|
||||
this method, unlike the NetScope::find_signal method,
|
||||
|
|
@ -4929,12 +4978,6 @@ class Design : public Definitions {
|
|||
|
||||
// Tasks
|
||||
NetScope* find_task(NetScope*scope, const pform_name_t&name);
|
||||
void add_root_task(NetScope*tscope, PTaskFunc*tf);
|
||||
std::list<NetScope*> find_roottask_scopes(void) const;
|
||||
|
||||
// Find a class in the $root scope.
|
||||
void add_class(netclass_t*cl, PClass*pclass);
|
||||
netclass_t* find_class(perm_string name) const;
|
||||
|
||||
// NODES
|
||||
void add_node(NetNode*);
|
||||
|
|
@ -4948,6 +4991,7 @@ class Design : public Definitions {
|
|||
void add_process(NetAnalogTop*);
|
||||
void delete_process(NetProcTop*);
|
||||
bool check_proc_delay() const;
|
||||
bool check_proc_synth() const;
|
||||
|
||||
NetNet* find_discipline_reference(ivl_discipline_t dis, NetScope*scope);
|
||||
|
||||
|
|
@ -4962,6 +5006,12 @@ class Design : public Definitions {
|
|||
unsigned errors;
|
||||
|
||||
private:
|
||||
NetScope* find_scope_(NetScope*, const hname_t&name,
|
||||
NetScope::TYPE type = NetScope::MODULE) const;
|
||||
|
||||
NetScope* find_scope_(NetScope*, const std::list<hname_t>&path,
|
||||
NetScope::TYPE type = NetScope::MODULE) const;
|
||||
|
||||
// Keep a tree of scopes. The NetScope class handles the wide
|
||||
// tree and per-hop searches for me.
|
||||
list<NetScope*>root_scopes_;
|
||||
|
|
@ -4970,12 +5020,6 @@ class Design : public Definitions {
|
|||
// packages do not nest.
|
||||
std::map<perm_string,NetScope*>packages_;
|
||||
|
||||
// Tasks in the $root scope
|
||||
std::map<NetScope*,PTaskFunc*>root_tasks_;
|
||||
|
||||
// Need this for elaboration of $root scope pclass objects.
|
||||
std::map<netclass_t*,PClass*> class_to_pclass_;
|
||||
|
||||
// List the nodes in the design.
|
||||
NetNode*nodes_;
|
||||
// These are in support of the node functor iterator.
|
||||
|
|
|
|||
39
netmisc.cc
39
netmisc.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -1260,6 +1260,8 @@ const char *human_readable_op(const char op, bool unary)
|
|||
if (unary) type = "~|"; // NOR
|
||||
else type = "!=="; // Case inequality
|
||||
break;
|
||||
case 'w': type = "==?"; break; // Wild equality
|
||||
case 'W': type = "!=?"; break; // Wild inequality
|
||||
|
||||
case 'l': type = "<<(<)"; break; // Left shifts
|
||||
case 'r': type = ">>"; break; // Logical right shift
|
||||
|
|
@ -1665,3 +1667,38 @@ NetScope* find_method_containing_scope(const LineInfo&, NetScope*scope)
|
|||
|
||||
return scope;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print a warning if we find a mixture of default and explicit timescale
|
||||
* based delays in the design, since this is likely an error.
|
||||
*/
|
||||
void check_for_inconsistent_delays(NetScope*scope)
|
||||
{
|
||||
static bool used_implicit_timescale = false;
|
||||
static bool used_explicit_timescale = false;
|
||||
static bool display_ts_dly_warning = true;
|
||||
|
||||
if (scope->time_from_timescale())
|
||||
used_explicit_timescale = true;
|
||||
else
|
||||
used_implicit_timescale = true;
|
||||
|
||||
if (display_ts_dly_warning &&
|
||||
used_explicit_timescale &&
|
||||
used_implicit_timescale) {
|
||||
if (gn_system_verilog()) {
|
||||
cerr << "warning: Found both default and explicit "
|
||||
"timescale based delays. Use" << endl;
|
||||
cerr << " : -Wtimescale to find the design "
|
||||
"element(s) with no explicit" << endl;
|
||||
cerr << " : timescale." << endl;
|
||||
} else {
|
||||
cerr << "warning: Found both default and "
|
||||
"`timescale based delays. Use" << endl;
|
||||
cerr << " : -Wtimescale to find the "
|
||||
"module(s) with no `timescale." << endl;
|
||||
}
|
||||
display_ts_dly_warning = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
netmisc.h
12
netmisc.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_netmisc_H
|
||||
#define IVL_netmisc_H
|
||||
/*
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -378,10 +378,6 @@ const char *human_readable_op(const char op, bool unary = false);
|
|||
enum const_bool { C_NON, C_0, C_1, C_X };
|
||||
const_bool const_logical(const NetExpr*expr);
|
||||
|
||||
extern bool dly_used_no_timescale;
|
||||
extern bool dly_used_timescale;
|
||||
extern bool display_ts_dly_warning;
|
||||
|
||||
/*
|
||||
* When scaling a real value to a time we need to do some standard
|
||||
* processing.
|
||||
|
|
@ -409,4 +405,10 @@ extern void assign_unpacked_with_bufz(Design*des, NetScope*scope,
|
|||
|
||||
extern NetPartSelect* detect_partselect_lval(Link&pin);
|
||||
|
||||
/*
|
||||
* Print a warning if we find a mixture of default and explicit timescale
|
||||
* based delays in the design, since this is likely an error.
|
||||
*/
|
||||
extern void check_for_inconsistent_delays(NetScope*scope);
|
||||
|
||||
#endif /* IVL_netmisc_H */
|
||||
|
|
|
|||
257
parse.y
257
parse.y
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -35,9 +35,6 @@ class PSpecPath;
|
|||
|
||||
extern void lex_end_table();
|
||||
|
||||
bool have_timeunit_decl = false;
|
||||
bool have_timeprec_decl = false;
|
||||
|
||||
static list<pform_range_t>* param_active_range = 0;
|
||||
static bool param_active_signed = false;
|
||||
static ivl_variable_type_t param_active_type = IVL_VT_LOGIC;
|
||||
|
|
@ -468,7 +465,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%token <number> BASED_NUMBER DEC_NUMBER UNBASED_NUMBER
|
||||
%token <realtime> REALTIME
|
||||
%token K_PLUS_EQ K_MINUS_EQ K_INCR K_DECR
|
||||
%token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_LP K_LS K_RS K_RSS K_SG
|
||||
%token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_WEQ K_WNE K_LP K_LS K_RS K_RSS K_SG
|
||||
/* K_CONTRIBUTE is <+, the contribution assign. */
|
||||
%token K_CONTRIBUTE
|
||||
%token K_PO_POS K_PO_NEG K_POW
|
||||
|
|
@ -532,8 +529,6 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%token K_tagged K_this K_throughout K_timeprecision K_timeunit K_type
|
||||
%token K_typedef K_union K_unique K_var K_virtual K_void K_wait_order
|
||||
%token K_wildcard K_with K_within
|
||||
/* Fake tokens that are passed once we have an initial token. */
|
||||
%token K_timeprecision_check K_timeunit_check
|
||||
|
||||
/* The new tokens from 1800-2009. */
|
||||
%token K_accept_on K_checker K_endchecker K_eventually K_global K_implies
|
||||
|
|
@ -598,7 +593,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
|
||||
%type <tf_ports> function_item function_item_list function_item_list_opt
|
||||
%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 <tf_ports> tf_port_declaration tf_port_item tf_port_item_list tf_port_list tf_port_list_opt
|
||||
|
||||
%type <named_pexpr> modport_simple_port port_name parameter_value_byname
|
||||
%type <named_pexprs> port_name_list parameter_value_byname_list
|
||||
|
|
@ -627,6 +622,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%type <decl_assignments> list_of_variable_decl_assignments
|
||||
|
||||
%type <data_type> data_type data_type_or_implicit data_type_or_implicit_or_void
|
||||
%type <data_type> simple_type_or_string
|
||||
%type <class_type> class_identifier
|
||||
%type <struct_member> struct_union_member
|
||||
%type <struct_members> struct_union_member_list
|
||||
|
|
@ -655,6 +651,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%type <statement> statement statement_item statement_or_null
|
||||
%type <statement> compressed_statement
|
||||
%type <statement> loop_statement for_step jump_statement
|
||||
%type <statement> procedural_assertion_statement
|
||||
%type <statement_list> statement_or_null_list statement_or_null_list_opt
|
||||
|
||||
%type <statement> analog_statement
|
||||
|
|
@ -682,7 +679,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%left '|'
|
||||
%left '^' K_NXOR K_NOR
|
||||
%left '&' K_NAND
|
||||
%left K_EQ K_NE K_CEQ K_CNE
|
||||
%left K_EQ K_NE K_CEQ K_CNE K_WEQ K_WNE
|
||||
%left K_GE K_LE '<' '>'
|
||||
%left K_LS K_RS K_RSS
|
||||
%left '+' '-'
|
||||
|
|
@ -691,7 +688,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%left UNARY_PREC
|
||||
|
||||
|
||||
/* to resolve dangling else ambiguity. */
|
||||
/* to resolve dangling else ambiguity. */
|
||||
%nonassoc less_than_K_else
|
||||
%nonassoc K_else
|
||||
|
||||
|
|
@ -699,12 +696,22 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%nonassoc '('
|
||||
%nonassoc K_exclude
|
||||
|
||||
/* to resolve timeunits declaration/redeclaration ambiguity */
|
||||
%nonassoc no_timeunits_declaration
|
||||
%nonassoc one_timeunits_declaration
|
||||
%nonassoc K_timeunit K_timeprecision
|
||||
|
||||
%%
|
||||
|
||||
|
||||
/* IEEE1800-2005: A.1.2 */
|
||||
/* source_text ::= [ timeunits_declaration ] { description } */
|
||||
source_text : description_list | ;
|
||||
source_text
|
||||
: timeunits_declaration_opt
|
||||
{ pform_set_scope_timescale(yyloc); }
|
||||
description_list
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
assertion_item /* IEEE1800-2012: A.6.10 */
|
||||
: concurrent_assertion_item
|
||||
|
|
@ -1136,11 +1143,7 @@ data_type_or_implicit_or_void
|
|||
}
|
||||
;
|
||||
|
||||
/* NOTE 1: We pull the "timeunits_declaration" into the description
|
||||
here in order to be a little more flexible with where timeunits
|
||||
statements may go. This may be a bad idea, but it is legacy now. */
|
||||
|
||||
/* NOTE 2: The "module" rule of the description combines the
|
||||
/* NOTE: The "module" rule of the description combines the
|
||||
module_declaration, program_declaration, and interface_declaration
|
||||
rules from the standard description. */
|
||||
|
||||
|
|
@ -1725,17 +1728,18 @@ open_range_list /* IEEE1800-2005 A.2.11 */
|
|||
|
||||
package_declaration /* IEEE1800-2005 A.1.2 */
|
||||
: K_package lifetime_opt IDENTIFIER ';'
|
||||
{ pform_start_package_declaration(@1, $3, $2);
|
||||
}
|
||||
{ pform_start_package_declaration(@1, $3, $2); }
|
||||
timeunits_declaration_opt
|
||||
{ pform_set_scope_timescale(@1); }
|
||||
package_item_list_opt
|
||||
K_endpackage endlabel_opt
|
||||
{ pform_end_package_declaration(@1);
|
||||
// If an end label is present make sure it match the package name.
|
||||
if ($8) {
|
||||
if (strcmp($3,$8) != 0) {
|
||||
yyerror(@8, "error: End label doesn't match package name");
|
||||
if ($10) {
|
||||
if (strcmp($3,$10) != 0) {
|
||||
yyerror(@10, "error: End label doesn't match package name");
|
||||
}
|
||||
delete[]$8;
|
||||
delete[]$10;
|
||||
}
|
||||
delete[]$3;
|
||||
}
|
||||
|
|
@ -1815,6 +1819,21 @@ property_expr /* IEEE1800-2012 A.2.10 */
|
|||
: expression
|
||||
;
|
||||
|
||||
procedural_assertion_statement /* IEEE1800-2012 A.6.10 */
|
||||
: K_assert '(' expression ')' statement %prec less_than_K_else
|
||||
{ yyerror(@1, "sorry: Simple immediate assertion statements not implemented.");
|
||||
$$ = 0;
|
||||
}
|
||||
| K_assert '(' expression ')' K_else statement
|
||||
{ yyerror(@1, "sorry: Simple immediate assertion statements not implemented.");
|
||||
$$ = 0;
|
||||
}
|
||||
| K_assert '(' expression ')' statement K_else statement
|
||||
{ yyerror(@1, "sorry: Simple immediate assertion statements not implemented.");
|
||||
$$ = 0;
|
||||
}
|
||||
;
|
||||
|
||||
/* The property_qualifier rule is as literally described in the LRM,
|
||||
but the use is usually as { property_qualifier }, which is
|
||||
implemented by the property_qualifier_opt rule below. */
|
||||
|
|
@ -1865,6 +1884,60 @@ signing /* IEEE1800-2005: A.2.2.1 */
|
|||
| K_unsigned { $$ = false; }
|
||||
;
|
||||
|
||||
simple_type_or_string /* IEEE1800-2005: A.2.2.1 */
|
||||
: integer_vector_type
|
||||
{ ivl_variable_type_t use_vtype = $1;
|
||||
bool reg_flag = false;
|
||||
if (use_vtype == IVL_VT_NO_TYPE) {
|
||||
use_vtype = IVL_VT_LOGIC;
|
||||
reg_flag = true;
|
||||
}
|
||||
vector_type_t*tmp = new vector_type_t(use_vtype, false, 0);
|
||||
tmp->reg_flag = reg_flag;
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| non_integer_type
|
||||
{ real_type_t*tmp = new real_type_t($1);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| atom2_type
|
||||
{ atom2_type_t*tmp = new atom2_type_t($1, true);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_integer
|
||||
{ list<pform_range_t>*pd = make_range_from_width(integer_width);
|
||||
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, true, pd);
|
||||
tmp->reg_flag = true;
|
||||
tmp->integer_flag = true;
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_time
|
||||
{ list<pform_range_t>*pd = make_range_from_width(64);
|
||||
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, pd);
|
||||
tmp->reg_flag = !gn_system_verilog();
|
||||
$$ = tmp;
|
||||
}
|
||||
| TYPE_IDENTIFIER
|
||||
{ $$ = $1.type;
|
||||
delete[]$1.text;
|
||||
}
|
||||
| PACKAGE_IDENTIFIER K_SCOPE_RES
|
||||
{ lex_in_package_scope($1); }
|
||||
TYPE_IDENTIFIER
|
||||
{ lex_in_package_scope(0);
|
||||
$$ = $4.type;
|
||||
delete[]$4.text;
|
||||
}
|
||||
| K_string
|
||||
{ string_type_t*tmp = new string_type_t;
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
statement /* IEEE1800-2005: A.6.4 */
|
||||
: attribute_list_opt statement_item
|
||||
{ pform_bind_attributes($2->attributes, $1);
|
||||
|
|
@ -2028,7 +2101,10 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
|||
|
||||
| K_task lifetime_opt IDENTIFIER error K_endtask
|
||||
{
|
||||
assert(current_task == 0);
|
||||
if (current_task) {
|
||||
pform_pop_scope();
|
||||
current_task = 0;
|
||||
}
|
||||
}
|
||||
endlabel_opt
|
||||
{ // Last step: check any closing name. This is done late so
|
||||
|
|
@ -2112,10 +2188,16 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
|||
|
||||
: port_direction_opt data_type_or_implicit IDENTIFIER dimensions_opt tf_port_item_expr_opt
|
||||
{ vector<pform_tf_port_t>*tmp;
|
||||
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
|
||||
NetNet::PortType use_port_type = $1;
|
||||
if ((use_port_type == NetNet::PIMPLICIT) && (gn_system_verilog() || ($2 == 0)))
|
||||
use_port_type = port_declaration_context.port_type;
|
||||
perm_string name = lex_strings.make($3);
|
||||
list<perm_string>* ilist = list_from_identifier($3);
|
||||
|
||||
if (use_port_type == NetNet::PIMPLICIT) {
|
||||
yyerror(@1, "error: missing task/function port direction.");
|
||||
use_port_type = NetNet::PINPUT; // for error recovery
|
||||
}
|
||||
if (($2 == 0) && ($1==NetNet::PIMPLICIT)) {
|
||||
// Detect special case this is an undecorated
|
||||
// identifier and we need to get the declaration from
|
||||
|
|
@ -2127,7 +2209,6 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
|||
port_declaration_context.data_type,
|
||||
ilist);
|
||||
|
||||
|
||||
} else {
|
||||
// Otherwise, the decorations for this identifier
|
||||
// indicate the type. Save the type for any right
|
||||
|
|
@ -2174,8 +2255,15 @@ tf_port_item_expr_opt
|
|||
;
|
||||
|
||||
tf_port_list /* IEEE1800-2005: A.2.7 */
|
||||
: { port_declaration_context.port_type = gn_system_verilog() ? NetNet::PINPUT : NetNet::PIMPLICIT;
|
||||
port_declaration_context.data_type = 0;
|
||||
}
|
||||
tf_port_item_list
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
: tf_port_list ',' tf_port_item
|
||||
tf_port_item_list
|
||||
: tf_port_item_list ',' tf_port_item
|
||||
{ vector<pform_tf_port_t>*tmp;
|
||||
if ($1 && $3) {
|
||||
size_t s1 = $1->size();
|
||||
|
|
@ -2201,30 +2289,34 @@ tf_port_list /* IEEE1800-2005: A.2.7 */
|
|||
{ yyerror(@2, "error: Syntax error in task/function port declaration.");
|
||||
$$ = $3;
|
||||
}
|
||||
| tf_port_list ','
|
||||
| tf_port_item_list ','
|
||||
{ yyerror(@2, "error: NULL port declarations are not allowed.");
|
||||
$$ = $1;
|
||||
}
|
||||
| tf_port_list ';'
|
||||
| tf_port_item_list ';'
|
||||
{ yyerror(@2, "error: ';' is an invalid port declaration separator.");
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
/* NOTE: Icarus Verilog is a little more generous with the
|
||||
timeunits declarations by allowing them to happen in multiple
|
||||
places in the file. So the rule is adjusted to be invoked by the
|
||||
"description" rule. This theoretically allows files to be
|
||||
concatenated together and still compile. */
|
||||
timeunits_declaration /* IEEE1800-2005: A.1.2 */
|
||||
: K_timeunit TIME_LITERAL ';'
|
||||
{ pform_set_timeunit($2, false, false); }
|
||||
{ pform_set_timeunit($2, allow_timeunit_decl); }
|
||||
| K_timeunit TIME_LITERAL '/' TIME_LITERAL ';'
|
||||
{ pform_set_timeunit($2, false, false);
|
||||
pform_set_timeprecision($4, false, false);
|
||||
{ bool initial_decl = allow_timeunit_decl && allow_timeprec_decl;
|
||||
pform_set_timeunit($2, initial_decl);
|
||||
pform_set_timeprec($4, initial_decl);
|
||||
}
|
||||
| K_timeprecision TIME_LITERAL ';'
|
||||
{ pform_set_timeprecision($2, false, false); }
|
||||
{ pform_set_timeprec($2, allow_timeprec_decl); }
|
||||
;
|
||||
|
||||
/* Allow zero, one, or two declarations. The second declaration might
|
||||
be a repeat declaration, but the pform functions take care of that. */
|
||||
timeunits_declaration_opt
|
||||
: /* empty */ %prec no_timeunits_declaration
|
||||
| timeunits_declaration %prec one_timeunits_declaration
|
||||
| timeunits_declaration timeunits_declaration
|
||||
;
|
||||
|
||||
value_range /* IEEE1800-2005: A.8.3 */
|
||||
|
|
@ -3259,6 +3351,11 @@ expression
|
|||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_WEQ attribute_list_opt expression
|
||||
{ PEBinary*tmp = new PEBComp('w', $1, $4);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_LE attribute_list_opt expression
|
||||
{ PEBinary*tmp = new PEBComp('L', $1, $4);
|
||||
FILE_NAME(tmp, @2);
|
||||
|
|
@ -3279,6 +3376,11 @@ expression
|
|||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_WNE attribute_list_opt expression
|
||||
{ PEBinary*tmp = new PEBComp('W', $1, $4);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| expression K_LOR attribute_list_opt expression
|
||||
{ PEBinary*tmp = new PEBLogic('o', $1, $4);
|
||||
FILE_NAME(tmp, @2);
|
||||
|
|
@ -3751,7 +3853,7 @@ expr_primary
|
|||
}
|
||||
}
|
||||
|
||||
| data_type '\'' '(' expression ')'
|
||||
| simple_type_or_string '\'' '(' expression ')'
|
||||
{ PExpr*base = $4;
|
||||
if (gn_system_verilog()) {
|
||||
PECastType*tmp = new PECastType($1, base);
|
||||
|
|
@ -4390,47 +4492,6 @@ cont_assign_list
|
|||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
/* We allow zero, one or two unique declarations. */
|
||||
local_timeunit_prec_decl_opt
|
||||
: /* Empty */
|
||||
| K_timeunit TIME_LITERAL '/' TIME_LITERAL ';'
|
||||
{ pform_set_timeunit($2, true, false);
|
||||
have_timeunit_decl = true;
|
||||
pform_set_timeprecision($4, true, false);
|
||||
have_timeprec_decl = true;
|
||||
}
|
||||
| local_timeunit_prec_decl
|
||||
| local_timeunit_prec_decl local_timeunit_prec_decl2
|
||||
;
|
||||
|
||||
/* By setting the appropriate have_time???_decl we allow only
|
||||
one declaration of each type in this module. */
|
||||
local_timeunit_prec_decl
|
||||
: K_timeunit TIME_LITERAL ';'
|
||||
{ pform_set_timeunit($2, true, false);
|
||||
have_timeunit_decl = true;
|
||||
}
|
||||
| K_timeprecision TIME_LITERAL ';'
|
||||
{ pform_set_timeprecision($2, true, false);
|
||||
have_timeprec_decl = true;
|
||||
}
|
||||
;
|
||||
local_timeunit_prec_decl2
|
||||
: K_timeunit TIME_LITERAL ';'
|
||||
{ pform_set_timeunit($2, true, false);
|
||||
have_timeunit_decl = true;
|
||||
}
|
||||
| K_timeprecision TIME_LITERAL ';'
|
||||
{ pform_set_timeprecision($2, true, false);
|
||||
have_timeprec_decl = true;
|
||||
}
|
||||
/* As the second item this form is always a check. */
|
||||
| K_timeunit TIME_LITERAL '/' TIME_LITERAL ';'
|
||||
{ pform_set_timeunit($2, true, true);
|
||||
pform_set_timeprecision($4, true, true);
|
||||
}
|
||||
;
|
||||
|
||||
/* This is the global structure of a module. A module is a start
|
||||
section, with optional ports, then an optional list of module
|
||||
items, and finally an end marker. */
|
||||
|
|
@ -4443,11 +4504,8 @@ module
|
|||
module_port_list_opt
|
||||
module_attribute_foreign ';'
|
||||
{ pform_module_set_ports($8); }
|
||||
local_timeunit_prec_decl_opt
|
||||
{ have_timeunit_decl = true; // Every thing past here is
|
||||
have_timeprec_decl = true; // a check!
|
||||
pform_check_timeunit_prec();
|
||||
}
|
||||
timeunits_declaration_opt
|
||||
{ pform_set_scope_timescale(@2); }
|
||||
module_item_list_opt
|
||||
module_end
|
||||
{ Module::UCDriveType ucd;
|
||||
|
|
@ -4484,8 +4542,6 @@ module
|
|||
}
|
||||
}
|
||||
pform_endmodule($4, in_celldefine, ucd);
|
||||
have_timeunit_decl = false; // We will allow decls again.
|
||||
have_timeprec_decl = false;
|
||||
}
|
||||
endlabel_opt
|
||||
{ // Last step: check any closing name. This is done late so
|
||||
|
|
@ -4839,9 +4895,8 @@ module_item
|
|||
| attribute_list_opt
|
||||
IDENTIFIER parameter_value_opt gate_instance_list ';'
|
||||
{ perm_string tmp1 = lex_strings.make($2);
|
||||
pform_make_modgates(@2, tmp1, $3, $4);
|
||||
pform_make_modgates(@2, tmp1, $3, $4, $1);
|
||||
delete[]$2;
|
||||
if ($1) delete $1;
|
||||
}
|
||||
|
||||
| attribute_list_opt
|
||||
|
|
@ -4864,6 +4919,18 @@ module_item
|
|||
{ PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS, $3, $1);
|
||||
FILE_NAME(tmp, @2);
|
||||
}
|
||||
| attribute_list_opt K_always_comb statement_item
|
||||
{ PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS_COMB, $3, $1);
|
||||
FILE_NAME(tmp, @2);
|
||||
}
|
||||
| attribute_list_opt K_always_ff statement_item
|
||||
{ PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS_FF, $3, $1);
|
||||
FILE_NAME(tmp, @2);
|
||||
}
|
||||
| attribute_list_opt K_always_latch statement_item
|
||||
{ PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS_LATCH, $3, $1);
|
||||
FILE_NAME(tmp, @2);
|
||||
}
|
||||
| attribute_list_opt K_initial statement_item
|
||||
{ PProcess*tmp = pform_make_behavior(IVL_PR_INITIAL, $3, $1);
|
||||
FILE_NAME(tmp, @2);
|
||||
|
|
@ -4878,6 +4945,8 @@ module_item
|
|||
|
||||
| attribute_list_opt assertion_item
|
||||
|
||||
| timeunits_declaration
|
||||
|
||||
| class_declaration
|
||||
|
||||
| task_declaration
|
||||
|
|
@ -5001,14 +5070,6 @@ module_item
|
|||
| KK_attribute '(' error ')' ';'
|
||||
{ yyerror(@1, "error: Malformed $attribute parameter list."); }
|
||||
|
||||
| K_timeunit_check TIME_LITERAL ';'
|
||||
{ pform_set_timeunit($2, true, true); }
|
||||
| K_timeunit_check TIME_LITERAL '/' TIME_LITERAL ';'
|
||||
{ pform_set_timeunit($2, true, true);
|
||||
pform_set_timeprecision($4, true, true);
|
||||
}
|
||||
| K_timeprecision_check TIME_LITERAL ';'
|
||||
{ pform_set_timeprecision($2, true, true); }
|
||||
;
|
||||
|
||||
module_item_list
|
||||
|
|
@ -6241,6 +6302,8 @@ statement_item /* This is roughly statement_item in the LRM */
|
|||
$$ = tmp;
|
||||
}
|
||||
|
||||
| procedural_assertion_statement { $$ = $1; }
|
||||
|
||||
| loop_statement { $$ = $1; }
|
||||
|
||||
| jump_statement { $$ = $1; }
|
||||
|
|
@ -6417,7 +6480,7 @@ statement_item /* This is roughly statement_item in the LRM */
|
|||
$$ = tmp;
|
||||
}
|
||||
| K_wait K_fork ';'
|
||||
{ PEventStatement*tmp = new PEventStatement(0);
|
||||
{ PEventStatement*tmp = new PEventStatement((PEEvent*)0);
|
||||
FILE_NAME(tmp,@1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
|
|||
23
parse_api.h
23
parse_api.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_parse_api_H
|
||||
#define IVL_parse_api_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -42,28 +42,21 @@ struct enum_type_t;
|
|||
*/
|
||||
extern std::map<perm_string,Module*> pform_modules;
|
||||
extern std::map<perm_string,PUdp*> pform_primitives;
|
||||
extern std::map<perm_string,data_type_t*> pform_typedefs;
|
||||
extern std::set<enum_type_t*> pform_enum_sets;
|
||||
extern std::map<perm_string,PTaskFunc*> pform_tasks;
|
||||
extern std::map<perm_string,PClass*> pform_classes;
|
||||
extern std::vector<PPackage*> pform_units;
|
||||
extern std::map<perm_string,PPackage*> pform_packages;
|
||||
|
||||
extern void pform_dump(std::ostream&out, const PClass*pac);
|
||||
extern void pform_dump(std::ostream&out, const PPackage*pac);
|
||||
extern void pform_dump(std::ostream&out, const PTaskFunc*tf);
|
||||
|
||||
extern void elaborate_rootscope_enumerations(Design*des);
|
||||
extern void elaborate_rootscope_classes(Design*des);
|
||||
extern void elaborate_rootscope_tasks(Design*des);
|
||||
|
||||
/*
|
||||
* This code actually invokes the parser to make modules. The first
|
||||
* parameter is the name of the file that is to be parsed. The
|
||||
* optional second parameter is the opened descriptor for the file. If
|
||||
* the descriptor is 0 (or skipped) then the function will attempt to
|
||||
* open the file on its own.
|
||||
* This code actually invokes the parser to make modules. If the path
|
||||
* parameter is "-", the parser reads from stdin, otherwise it attempts
|
||||
* to open and read the specified file. When reading from a file, if
|
||||
* the ivlpp_string variable is not set to null, the file will be piped
|
||||
* through the command specified by ivlpp_string before being parsed.
|
||||
*/
|
||||
extern int pform_parse(const char*path, FILE*file =0);
|
||||
extern int pform_parse(const char*path);
|
||||
|
||||
extern string vl_file;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_parse_misc_H
|
||||
#define IVL_parse_misc_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -71,12 +71,6 @@ extern unsigned long based_size;
|
|||
extern bool in_celldefine;
|
||||
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
|
||||
extern UCDriveType uc_drive;
|
||||
/*
|
||||
* Flags to control if we are declaring or checking a timeunit or
|
||||
* timeprecision statement.
|
||||
*/
|
||||
extern bool have_timeunit_decl;
|
||||
extern bool have_timeprec_decl;
|
||||
|
||||
/*
|
||||
* The parser signals back to the lexor that the next identifier
|
||||
|
|
|
|||
29
pform.h
29
pform.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_pform_H
|
||||
#define IVL_pform_H
|
||||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -147,7 +147,11 @@ extern bool pform_in_interface(void);
|
|||
*/
|
||||
extern PWire* pform_get_wire_in_scope(perm_string name);
|
||||
|
||||
extern PWire* pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetNet::PortType port_type, ivl_variable_type_t vt_type);
|
||||
extern PWire* pform_get_make_wire_in_scope(const struct vlltype&li,
|
||||
perm_string name,
|
||||
NetNet::Type net_type,
|
||||
NetNet::PortType port_type,
|
||||
ivl_variable_type_t vt_type);
|
||||
|
||||
/*
|
||||
* The parser uses startmodule and endmodule together to build up a
|
||||
|
|
@ -165,8 +169,8 @@ extern void pform_startmodule(const struct vlltype&loc, const char*name,
|
|||
bool program_block, bool is_interface,
|
||||
LexicalScope::lifetime_t lifetime,
|
||||
list<named_pexpr_t>*attr);
|
||||
extern void pform_check_timeunit_prec();
|
||||
extern void pform_module_set_ports(vector<Module::port_t*>*);
|
||||
extern void pform_set_scope_timescale(const struct vlltype&loc);
|
||||
|
||||
/* These functions are used when we have a complete port definition, either
|
||||
in an ansi style or non-ansi style declaration. In this case, we have
|
||||
|
|
@ -386,11 +390,11 @@ extern void pform_set_reg_idx(perm_string name,
|
|||
|
||||
extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr);
|
||||
|
||||
extern void pform_set_struct_type(struct_type_t*struct_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*attr);
|
||||
extern void pform_set_struct_type(const struct vlltype&li, struct_type_t*struct_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*attr);
|
||||
|
||||
extern void pform_set_string_type(const string_type_t*string_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*attr);
|
||||
extern void pform_set_string_type(const struct vlltype&li, const string_type_t*string_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*attr);
|
||||
|
||||
extern void pform_set_class_type(class_type_t*class_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*addr);
|
||||
extern void pform_set_class_type(const struct vlltype&li, class_type_t*class_type, std::list<perm_string>*names, NetNet::Type net_type, std::list<named_pexpr_t>*addr);
|
||||
|
||||
|
||||
/* pform_set_attrib and pform_set_type_attrib exist to support the
|
||||
|
|
@ -478,7 +482,8 @@ extern void pform_makegates(const struct vlltype&loc,
|
|||
extern void pform_make_modgates(const struct vlltype&loc,
|
||||
perm_string type,
|
||||
struct parmvalue_t*overrides,
|
||||
svector<lgate>*gates);
|
||||
svector<lgate>*gates,
|
||||
list<named_pexpr_t>*attr);
|
||||
|
||||
/* Make a continuous assignment node, with optional bit- or part- select. */
|
||||
extern void pform_make_pgassign_list(list<PExpr*>*alist,
|
||||
|
|
@ -566,8 +571,12 @@ extern void parm_to_defparam_list(const string¶m);
|
|||
*/
|
||||
extern bool get_time_unit(const char*cp, int &unit);
|
||||
extern int pform_get_timeunit();
|
||||
extern void pform_set_timeunit(const char*txt, bool in_module, bool only_check);
|
||||
extern void pform_set_timeprecision(const char*txt, bool in_module,
|
||||
bool only_check);
|
||||
extern void pform_set_timeunit(const char*txt, bool initial_decl);
|
||||
extern void pform_set_timeprec(const char*txt, bool initial_decl);
|
||||
/*
|
||||
* Flags to determine whether this is an initial declaration.
|
||||
*/
|
||||
extern bool allow_timeunit_decl;
|
||||
extern bool allow_timeprec_decl;
|
||||
|
||||
#endif /* IVL_pform_H */
|
||||
|
|
|
|||
|
|
@ -22,18 +22,18 @@
|
|||
# include "parse_misc.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
static void pform_set_class_type(class_type_t*class_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
static void pform_set_class_type(const struct vlltype&li, class_type_t*class_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_CLASS);
|
||||
PWire*net = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, IVL_VT_CLASS);
|
||||
assert(net);
|
||||
net->set_data_type(class_type);
|
||||
pform_bind_attributes(net->attributes, attr, true);
|
||||
}
|
||||
|
||||
void pform_set_class_type(class_type_t*class_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
void pform_set_class_type(const struct vlltype&li, class_type_t*class_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
for (list<perm_string>::iterator cur = names->begin()
|
||||
; cur != names->end() ; ++ cur) {
|
||||
pform_set_class_type(class_type, *cur, net_type, attr);
|
||||
pform_set_class_type(li, class_type, *cur, net_type, attr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2017 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
|
||||
|
|
@ -121,6 +121,15 @@ std::ostream& operator << (std::ostream&out, ivl_process_type_t pt)
|
|||
case IVL_PR_ALWAYS:
|
||||
out << "always";
|
||||
break;
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
out << "always_comb";
|
||||
break;
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
out << "always_ff";
|
||||
break;
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
out << "always_latch";
|
||||
break;
|
||||
case IVL_PR_FINAL:
|
||||
out << "final";
|
||||
break;
|
||||
|
|
@ -627,10 +636,10 @@ void PGBuiltin::dump(ostream&out, unsigned ind) const
|
|||
out << "bufif1 ";
|
||||
break;
|
||||
case PGBuiltin::NOTIF0:
|
||||
out << "bufif0 ";
|
||||
out << "notif0 ";
|
||||
break;
|
||||
case PGBuiltin::NOTIF1:
|
||||
out << "bufif1 ";
|
||||
out << "notif1 ";
|
||||
break;
|
||||
case PGBuiltin::NAND:
|
||||
out << "nand ";
|
||||
|
|
@ -729,6 +738,7 @@ void PGModule::dump(ostream&out, unsigned ind) const
|
|||
dump_pins(out);
|
||||
}
|
||||
out << ");" << endl;
|
||||
dump_attributes_map(out, attributes, 8);
|
||||
}
|
||||
|
||||
void Statement::dump(ostream&out, unsigned ind) const
|
||||
|
|
@ -843,7 +853,7 @@ void PCase::dump(ostream&out, unsigned ind) const
|
|||
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
|
||||
PCase::Item*cur = (*items_)[idx];
|
||||
|
||||
if (cur->expr.size()) {
|
||||
if (! cur->expr.empty()) {
|
||||
out << setw(ind+2) << "" << "default:";
|
||||
|
||||
} else {
|
||||
|
|
@ -1175,6 +1185,11 @@ void AProcess::dump(ostream&out, unsigned ind) const
|
|||
case IVL_PR_ALWAYS:
|
||||
out << setw(ind) << "" << "analog";
|
||||
break;
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
assert(0);
|
||||
break;
|
||||
case IVL_PR_FINAL:
|
||||
out << setw(ind) << "" << "analog final";
|
||||
break;
|
||||
|
|
@ -1705,8 +1720,10 @@ void PPackage::pform_dump(std::ostream&out) const
|
|||
dump_localparams_(out, 4);
|
||||
dump_parameters_(out, 4);
|
||||
dump_enumerations_(out, 4);
|
||||
dump_wires_(out, 4);
|
||||
dump_tasks_(out, 4);
|
||||
dump_funcs_(out, 4);
|
||||
dump_var_inits_(out, 4);
|
||||
out << "endpackage" << endl;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,11 @@ void pform_package_import(const struct vlltype&, PPackage*pkg, const char*ident)
|
|||
|
||||
scope->imports[cur->first] = pkg;
|
||||
}
|
||||
|
||||
for (set<enum_type_t*>::const_iterator cur = pkg->enum_sets.begin()
|
||||
; cur != pkg->enum_sets.end() ; ++ cur) {
|
||||
scope->enum_sets.insert(*cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,18 +21,17 @@
|
|||
# include "parse_misc.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
static void pform_set_string_type(const string_type_t*, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
static void pform_set_string_type(const struct vlltype&li, const string_type_t*, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_STRING);
|
||||
PWire*net = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, IVL_VT_STRING);
|
||||
assert(net);
|
||||
pform_bind_attributes(net->attributes, attr, true);
|
||||
}
|
||||
|
||||
void pform_set_string_type(const string_type_t*string_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
void pform_set_string_type(const struct vlltype&li, const string_type_t*string_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
for (list<perm_string>::iterator cur = names->begin()
|
||||
; cur != names->end() ; ++ cur) {
|
||||
pform_set_string_type(string_type, *cur, net_type, attr);
|
||||
pform_set_string_type(li, string_type, *cur, net_type, attr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,20 +62,20 @@ ivl_variable_type_t struct_type_t::figure_packed_base_type(void) const
|
|||
* out the base type of the packed variable. Elaboration, later on,
|
||||
* well figure out the rest.
|
||||
*/
|
||||
static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
static void pform_set_packed_struct(const struct vlltype&li, struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
ivl_variable_type_t base_type = struct_type->figure_packed_base_type();
|
||||
|
||||
PWire*net = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, base_type);
|
||||
PWire*net = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, base_type);
|
||||
assert(net);
|
||||
net->set_data_type(struct_type);
|
||||
pform_bind_attributes(net->attributes, attr, true);
|
||||
}
|
||||
|
||||
static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
static void pform_set_struct_type(const struct vlltype&li, struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
if (struct_type->packed_flag) {
|
||||
pform_set_packed_struct(struct_type, name, net_type, attr);
|
||||
pform_set_packed_struct(li, struct_type, name, net_type, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -83,11 +83,11 @@ static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, N
|
|||
// a "sorry" message, so no need to do anything here.
|
||||
}
|
||||
|
||||
void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
void pform_set_struct_type(const struct vlltype&li, struct_type_t*struct_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
|
||||
{
|
||||
for (list<perm_string>::iterator cur = names->begin()
|
||||
; cur != names->end() ; ++ cur) {
|
||||
pform_set_struct_type(struct_type, *cur, net_type, attr);
|
||||
pform_set_struct_type(li, struct_type, *cur, net_type, attr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ static void pform_makewire(const struct vlltype&li,
|
|||
{
|
||||
ivl_variable_type_t base_type = struct_type->figure_packed_base_type();
|
||||
|
||||
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::WIRE, ptype, base_type);
|
||||
PWire*cur = pform_get_make_wire_in_scope(li, name, NetNet::WIRE, ptype, base_type);
|
||||
assert(cur);
|
||||
FILE_NAME(cur, li);
|
||||
cur->set_data_type(struct_type);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_pform_types_H
|
||||
#define IVL_pform_types_H
|
||||
/*
|
||||
* Copyright (c) 2007-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2007-2018 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
|
||||
|
|
@ -33,6 +33,10 @@
|
|||
# include <map>
|
||||
# include <memory>
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#define unique_ptr auto_ptr
|
||||
#endif
|
||||
|
||||
/*
|
||||
* parse-form types.
|
||||
*/
|
||||
|
|
@ -117,7 +121,7 @@ struct name_component_t {
|
|||
struct decl_assignment_t {
|
||||
perm_string name;
|
||||
std::list<pform_range_t>index;
|
||||
std::auto_ptr<PExpr> expr;
|
||||
std::unique_ptr<PExpr> expr;
|
||||
};
|
||||
|
||||
struct pform_tf_port_t {
|
||||
|
|
@ -170,14 +174,14 @@ struct enum_type_t : public data_type_t {
|
|||
ivl_variable_type_t base_type;
|
||||
bool signed_flag;
|
||||
bool integer_flag; // True if "integer" was used
|
||||
std::auto_ptr< list<pform_range_t> > range;
|
||||
std::auto_ptr< list<named_pexpr_t> > names;
|
||||
std::unique_ptr< list<pform_range_t> > range;
|
||||
std::unique_ptr< list<named_pexpr_t> > names;
|
||||
LineInfo li;
|
||||
};
|
||||
|
||||
struct struct_member_t : public LineInfo {
|
||||
std::auto_ptr<data_type_t> type;
|
||||
std::auto_ptr< list<decl_assignment_t*> > names;
|
||||
std::unique_ptr<data_type_t> type;
|
||||
std::unique_ptr< list<decl_assignment_t*> > names;
|
||||
void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
};
|
||||
|
||||
|
|
@ -188,7 +192,7 @@ struct struct_type_t : public data_type_t {
|
|||
|
||||
bool packed_flag;
|
||||
bool union_flag;
|
||||
std::auto_ptr< list<struct_member_t*> > members;
|
||||
std::unique_ptr< list<struct_member_t*> > members;
|
||||
};
|
||||
|
||||
struct atom2_type_t : public data_type_t {
|
||||
|
|
@ -234,7 +238,7 @@ struct vector_type_t : public data_type_t {
|
|||
bool reg_flag; // True if "reg" was used
|
||||
bool integer_flag; // True if "integer" was used
|
||||
bool implicit_flag; // True if this type is implicitly logic/reg
|
||||
std::auto_ptr< list<pform_range_t> > pdims;
|
||||
std::unique_ptr< list<pform_range_t> > pdims;
|
||||
};
|
||||
|
||||
struct array_base_t : public data_type_t {
|
||||
|
|
@ -243,7 +247,7 @@ struct array_base_t : public data_type_t {
|
|||
: base_type(btype), dims(pd) { }
|
||||
|
||||
data_type_t*base_type;
|
||||
std::auto_ptr< list<pform_range_t> > dims;
|
||||
std::unique_ptr< list<pform_range_t> > dims;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -376,4 +380,8 @@ extern std::ostream& operator<< (std::ostream&out, const pform_name_t&);
|
|||
extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
|
||||
extern std::ostream& operator<< (std::ostream&out, const index_component_t&that);
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#undef unique_ptr
|
||||
#endif
|
||||
|
||||
#endif /* IVL_pform_types_H */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_svector_H
|
||||
#define IVL_svector_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -57,7 +57,7 @@ template <class TYPE> class svector {
|
|||
items_[l.nitems_+idx] = r[idx];
|
||||
}
|
||||
|
||||
svector(const svector<TYPE>&l, TYPE r)
|
||||
svector(const svector<TYPE>&l, TYPE&r)
|
||||
: nitems_(l.nitems_ + 1), items_(new TYPE[nitems_])
|
||||
{ for (unsigned idx = 0 ; idx < l.nitems_ ; idx += 1)
|
||||
items_[idx] = l[idx];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2017 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -143,14 +143,21 @@ static bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
|||
}
|
||||
}
|
||||
|
||||
// Don't scan up past a module boundary.
|
||||
if (scope->type()==NetScope::MODULE && !scope->nested_module())
|
||||
break;
|
||||
// Don't scan up if we are searching within a prefixed scope.
|
||||
if (prefix_scope)
|
||||
break;
|
||||
|
||||
scope = scope->parent();
|
||||
// Don't scan up past a module boundary.
|
||||
if (scope->type()==NetScope::MODULE && !scope->nested_module())
|
||||
scope = 0;
|
||||
else
|
||||
scope = scope->parent();
|
||||
|
||||
// Last chance - try the compilation unit.
|
||||
if (scope == 0 && start_scope != 0) {
|
||||
scope = start_scope->unit();
|
||||
start_scope = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Last chance: this is a single name, so it might be the name
|
||||
|
|
|
|||
11
syn-rules.y
11
syn-rules.y
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2000-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -304,6 +304,15 @@ static void syn_start_process(NetProcTop*t)
|
|||
last_ = first_;
|
||||
ptr_ = first_;
|
||||
|
||||
// Can the following be converted into S_ALWAYS?
|
||||
if ((t->type() == IVL_PR_ALWAYS_COMB) ||
|
||||
(t->type() == IVL_PR_ALWAYS_FF) ||
|
||||
(t->type() == IVL_PR_ALWAYS_LATCH)) {
|
||||
cerr << t->get_fileline() << ": internal error: "
|
||||
<< " Need to check if this can be synthesized." << endl;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
first_->token = (t->type() == IVL_PR_ALWAYS)? S_ALWAYS : S_INITIAL;
|
||||
first_->top = t;
|
||||
first_->next_ = 0;
|
||||
|
|
|
|||
5
synth.cc
5
synth.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2017 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
|
||||
|
|
@ -134,6 +134,9 @@ void synth_f::process(Design*des, NetProcTop*top)
|
|||
top_ = top;
|
||||
switch (top->type()) {
|
||||
case IVL_PR_ALWAYS:
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
proc_always_(des);
|
||||
break;
|
||||
case IVL_PR_INITIAL:
|
||||
|
|
|
|||
26
t-dll-api.cc
26
t-dll-api.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
|
||||
*
|
||||
|
|
@ -93,10 +93,7 @@ extern "C" void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes,
|
|||
assert (nscopes && scopes);
|
||||
if (des->root_scope_list.size() == 0) {
|
||||
size_t fill = 0;
|
||||
des->root_scope_list.resize(des->root_tasks.size() + des->packages.size() + des->roots.size() + des->classes.size());
|
||||
for (map<const NetScope*,ivl_scope_t>::iterator idx = des->root_tasks.begin()
|
||||
; idx != des->root_tasks.end() ; ++ idx)
|
||||
des->root_scope_list[fill++] = idx->second;
|
||||
des->root_scope_list.resize(des->packages.size() + des->roots.size() + des->classes.size());
|
||||
|
||||
for (map<const NetScope*,ivl_scope_t>::iterator idx = des->classes.begin()
|
||||
; idx != des->classes.end() ; ++ idx)
|
||||
|
|
@ -1238,6 +1235,8 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
|
|||
case IVL_LPM_CMP_GT:
|
||||
case IVL_LPM_CMP_NE:
|
||||
case IVL_LPM_CMP_NEE:
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
case IVL_LPM_CMP_WNE:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
case IVL_LPM_MULT:
|
||||
|
|
@ -1393,6 +1392,8 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net)
|
|||
case IVL_LPM_CMP_EQX:
|
||||
case IVL_LPM_CMP_EQZ:
|
||||
case IVL_LPM_CMP_NEE:
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
case IVL_LPM_CMP_WNE:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
case IVL_LPM_MULT:
|
||||
|
|
@ -1519,6 +1520,7 @@ extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net)
|
|||
case IVL_LPM_CONCATZ:
|
||||
cerr << "error: ivl_lpm_selects() is no longer supported for "
|
||||
"IVL_LPM_CONCAT, use ivl_lpm_size() instead." << endl;
|
||||
// fallthrough
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
|
@ -1543,6 +1545,8 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
|
|||
case IVL_LPM_CMP_GT:
|
||||
case IVL_LPM_CMP_NE:
|
||||
case IVL_LPM_CMP_NEE:
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
case IVL_LPM_CMP_WNE:
|
||||
case IVL_LPM_DIVIDE:
|
||||
case IVL_LPM_MOD:
|
||||
case IVL_LPM_MULT:
|
||||
|
|
@ -2134,7 +2138,7 @@ extern "C" int ivl_scope_func_signed(ivl_scope_t net)
|
|||
assert(net);
|
||||
assert(net->type_==IVL_SCT_FUNCTION);
|
||||
assert(net->func_type==IVL_VT_LOGIC || net->func_type==IVL_VT_BOOL);
|
||||
return net->func_signed? !0 : 0;
|
||||
return net->func_signed? 1 : 0;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_scope_func_width(ivl_scope_t net)
|
||||
|
|
@ -2812,6 +2816,16 @@ extern "C" uint64_t ivl_stmt_delay_val(ivl_statement_t net)
|
|||
return net->u_.delay_.value;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_stmt_needs_t0_trigger(ivl_statement_t net)
|
||||
{
|
||||
assert(net);
|
||||
if (net->type_ == IVL_ST_WAIT) {
|
||||
return net->u_.wait_.needs_t0_trigger;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net)
|
||||
{
|
||||
assert(net);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -847,12 +847,15 @@ bool dll_target::proc_wait(const NetEvWait*net)
|
|||
|
||||
/* This is a wait fork statement. */
|
||||
if ((net->nevents() == 1) && (net->event(0) == 0)) {
|
||||
stmt_cur_->u_.wait_.needs_t0_trigger = 0;
|
||||
stmt_cur_->u_.wait_.event = 0;
|
||||
stmt_cur_->type_ = IVL_ST_WAIT;
|
||||
stmt_cur_->u_.wait_.stmt_->type_ = IVL_ST_NOOP;
|
||||
return true;
|
||||
}
|
||||
|
||||
stmt_cur_->u_.wait_.needs_t0_trigger = net->has_t0_trigger();
|
||||
|
||||
// This event processing code is also in the NB assign above.
|
||||
if (net->nevents() > 1) {
|
||||
stmt_cur_->u_.wait_.events = (ivl_event_t*)
|
||||
|
|
|
|||
42
t-dll.cc
42
t-dll.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -261,12 +261,6 @@ ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
if (cur->type()==NetScope::TASK || cur->type()==NetScope::FUNC) {
|
||||
map<const NetScope*,ivl_scope_t>::const_iterator idx = des.root_tasks.find(cur);
|
||||
if (idx != des.root_tasks.end())
|
||||
return idx->second;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0; idx < des.roots.size(); idx += 1) {
|
||||
assert(des.roots[idx]);
|
||||
ivl_scope_t scope = find_scope_from_root(des.roots[idx], cur);
|
||||
|
|
@ -650,22 +644,6 @@ void dll_target::add_root(const NetScope *s)
|
|||
case NetScope::CLASS:
|
||||
root_->type_ = IVL_SCT_CLASS;
|
||||
break;
|
||||
case NetScope::TASK: {
|
||||
const NetTaskDef*def = s->task_def();
|
||||
if (def == 0) {
|
||||
cerr << "?:?" << ": internal error: "
|
||||
<< "task " << root_->name_
|
||||
<< " has no definition." << endl;
|
||||
}
|
||||
assert(def);
|
||||
root_->type_ = IVL_SCT_TASK;
|
||||
root_->tname_ = def->scope()->basename();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NetScope::FUNC:
|
||||
fill_in_scope_function(root_, s);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -694,11 +672,6 @@ void dll_target::add_root(const NetScope *s)
|
|||
des_.classes[s] = root_;
|
||||
break;
|
||||
|
||||
case NetScope::TASK:
|
||||
case NetScope::FUNC:
|
||||
des_.root_tasks[s] = root_;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
|
@ -740,11 +713,7 @@ bool dll_target::start_design(const Design*des)
|
|||
}
|
||||
assert(idx == des_.disciplines.size());
|
||||
|
||||
list<NetScope *> scope_list = des->find_roottask_scopes();
|
||||
for (list<NetScope*>::const_iterator cur = scope_list.begin()
|
||||
; cur != scope_list.end() ; ++ cur) {
|
||||
add_root(*cur);
|
||||
}
|
||||
list<NetScope *> scope_list;
|
||||
|
||||
scope_list = des->find_package_scopes();
|
||||
for (list<NetScope*>::const_iterator cur = scope_list.begin()
|
||||
|
|
@ -1275,6 +1244,12 @@ void dll_target::net_case_cmp(const NetCaseCmp*net)
|
|||
case NetCaseCmp::NEQ:
|
||||
obj->type = IVL_LPM_CMP_NEE;
|
||||
break;
|
||||
case NetCaseCmp::WEQ:
|
||||
obj->type = IVL_LPM_CMP_WEQ;
|
||||
break;
|
||||
case NetCaseCmp::WNE:
|
||||
obj->type = IVL_LPM_CMP_WNE;
|
||||
break;
|
||||
case NetCaseCmp::XEQ:
|
||||
obj->type = IVL_LPM_CMP_EQX;
|
||||
break;
|
||||
|
|
@ -2544,6 +2519,7 @@ void dll_target::scope(const NetScope*net)
|
|||
case NetScope::PACKAGE:
|
||||
cerr << "?:?" << ": internal error: "
|
||||
<< "Package scopes should not have parents." << endl;
|
||||
// fallthrough
|
||||
case NetScope::MODULE:
|
||||
scop->type_ = IVL_SCT_MODULE;
|
||||
scop->tname_ = net->module_name();
|
||||
|
|
|
|||
5
t-dll.h
5
t-dll.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_t_dll_H
|
||||
#define IVL_t_dll_H
|
||||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -645,7 +645,7 @@ struct ivl_parameter_s {
|
|||
* that generally only matters for VPI calls.
|
||||
*/
|
||||
struct ivl_process_s {
|
||||
ivl_process_type_t type_ : 2;
|
||||
ivl_process_type_t type_ : 3;
|
||||
unsigned int analog_flag : 1;
|
||||
ivl_scope_t scope_;
|
||||
ivl_statement_t stmt_;
|
||||
|
|
@ -862,6 +862,7 @@ struct ivl_statement_s {
|
|||
} utask_;
|
||||
|
||||
struct { /* IVL_ST_TRIGGER IVL_ST_WAIT */
|
||||
unsigned needs_t0_trigger;
|
||||
unsigned nevent;
|
||||
union {
|
||||
ivl_event_t event;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (C) 2011-2017 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -79,11 +79,14 @@ void init_fp_lexor(FILE*fd)
|
|||
yyrestart(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||
*/
|
||||
void destroy_fp_lexor()
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -394,6 +394,12 @@ static void show_lpm_cmp_eeq(ivl_lpm_t net)
|
|||
case IVL_LPM_CMP_NEE:
|
||||
str = "NEE";
|
||||
break;
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
str = "WEQ";
|
||||
break;
|
||||
case IVL_LPM_CMP_WNE:
|
||||
str = "WNE";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
|
@ -1043,6 +1049,8 @@ static void show_lpm(ivl_lpm_t net)
|
|||
case IVL_LPM_CMP_EQX:
|
||||
case IVL_LPM_CMP_EQZ:
|
||||
case IVL_LPM_CMP_NEE:
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
case IVL_LPM_CMP_WNE:
|
||||
show_lpm_cmp_eeq(net);
|
||||
break;
|
||||
|
||||
|
|
@ -1158,6 +1166,24 @@ static int show_process(ivl_process_t net, void*x)
|
|||
else
|
||||
fprintf(out, "always\n");
|
||||
break;
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
if (ivl_process_analog(net))
|
||||
assert(0);
|
||||
else
|
||||
fprintf(out, "always_comb\n");
|
||||
break;
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
if (ivl_process_analog(net))
|
||||
assert(0);
|
||||
else
|
||||
fprintf(out, "always_ff\n");
|
||||
break;
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
if (ivl_process_analog(net))
|
||||
assert(0);
|
||||
else
|
||||
fprintf(out, "always_latch\n");
|
||||
break;
|
||||
case IVL_PR_FINAL:
|
||||
if (ivl_process_analog(net))
|
||||
fprintf(out, "analog final\n");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2017 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
|
||||
|
|
@ -393,6 +393,9 @@ static int show_process(ivl_process_t net, void*x)
|
|||
fprintf(out, " initial\n");
|
||||
break;
|
||||
case IVL_PR_ALWAYS:
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
fprintf(out, " always\n");
|
||||
break;
|
||||
case IVL_PR_FINAL:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* VHDL code generation for statements.
|
||||
*
|
||||
* Copyright (C) 2008-2013 Nick Gasson (nick@nickg.me.uk)
|
||||
* Copyright (C) 2008-2018 Nick Gasson (nick@nickg.me.uk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -683,8 +683,10 @@ static void get_nexuses_from_expr(ivl_expr_t expr, set<ivl_nexus_t> &out)
|
|||
break;
|
||||
case IVL_EX_TERNARY:
|
||||
get_nexuses_from_expr(ivl_expr_oper3(expr), out);
|
||||
// fallthrough
|
||||
case IVL_EX_BINARY:
|
||||
get_nexuses_from_expr(ivl_expr_oper2(expr), out);
|
||||
// fallthrough
|
||||
case IVL_EX_UNARY:
|
||||
get_nexuses_from_expr(ivl_expr_oper1(expr), out);
|
||||
break;
|
||||
|
|
@ -1248,6 +1250,7 @@ static void process_number(vhdl_binop_expr *all, vhdl_var_ref *test,
|
|||
switch (bits[i]) {
|
||||
case 'x':
|
||||
if (is_casez) break;
|
||||
// fallthrough
|
||||
case '?':
|
||||
case 'z':
|
||||
continue; // Ignore these.
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ void vhdl_element::print() const
|
|||
// Trap allocations of vhdl_element subclasses.
|
||||
// This records the pointer allocated in a static field of vhdl_element
|
||||
// so we can delete it just before the code generator exits.
|
||||
void* vhdl_element::operator new(size_t size) throw (bad_alloc)
|
||||
void* vhdl_element::operator new(size_t size)
|
||||
{
|
||||
// Let the default new handle the allocation
|
||||
void* ptr = ::operator new(size);
|
||||
|
|
@ -171,4 +171,3 @@ int vhdl_element::free_all_objects()
|
|||
|
||||
return freed;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class vhdl_element {
|
|||
public:
|
||||
virtual ~vhdl_element() {}
|
||||
|
||||
void* operator new(size_t size) throw (std::bad_alloc);
|
||||
void* operator new(size_t size);
|
||||
void operator delete(void* ptr);
|
||||
|
||||
virtual void emit(std::ostream &of, int level=0) const = 0;
|
||||
|
|
@ -74,4 +74,3 @@ std::string nl_string(int level);
|
|||
void blank_line(std::ostream &of, int level);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2013 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2011-2017 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -21,6 +21,24 @@
|
|||
# include "config.h"
|
||||
# include "vlog95_priv.h"
|
||||
|
||||
static unsigned need_ivl_top_module = 0;
|
||||
|
||||
void emit_icarus_generated_top_module()
|
||||
{
|
||||
if (need_ivl_top_module) {
|
||||
fprintf(vlog_out,
|
||||
"\n"
|
||||
"/*\n"
|
||||
" * This module is used to trigger any always_comb or always_latch processes\n"
|
||||
" * at time zero to make sure all the outputs have the correct values.\n"
|
||||
"*/\n"
|
||||
"module IVL_top_priv_module;\n"
|
||||
" event IVL_T0_trigger_event;\n"
|
||||
" initial #0 -> IVL_T0_trigger_event;\n"
|
||||
"endmodule /* IVL_top_priv_module */\n");
|
||||
}
|
||||
}
|
||||
|
||||
void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
|
||||
{
|
||||
unsigned eidx, nevents, first = 1;
|
||||
|
|
@ -68,4 +86,12 @@ void emit_event(ivl_scope_t scope, ivl_statement_t stmt)
|
|||
emit_id(ivl_event_basename(event));
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is an always_comb/latch then we need to add a trigger to
|
||||
* get the correct functionality. */
|
||||
if (ivl_stmt_needs_t0_trigger(stmt)) {
|
||||
assert(first == 0);
|
||||
fprintf(vlog_out, " or IVL_top_priv_module.IVL_T0_trigger_event");
|
||||
need_ivl_top_module = 1;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2014 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2011-2018 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -44,8 +44,10 @@ static expr_sign_t expr_get_binary_sign_type(ivl_expr_t expr)
|
|||
switch (ivl_expr_opcode(expr)) {
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'w':
|
||||
case 'N':
|
||||
case 'n':
|
||||
case 'W':
|
||||
case '<':
|
||||
case 'L':
|
||||
case '>':
|
||||
|
|
@ -417,8 +419,10 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid,
|
|||
case 'p': oper = "**"; break;
|
||||
case 'E': oper = "==="; break;
|
||||
case 'e': oper = "=="; break;
|
||||
case 'w': oper = "==?"; break;
|
||||
case 'N': oper = "!=="; break;
|
||||
case 'n': oper = "!="; break;
|
||||
case 'W': oper = "!=?"; break;
|
||||
case '<': oper = "<"; break;
|
||||
case 'L': oper = "<="; break;
|
||||
case '>': oper = ">"; break;
|
||||
|
|
@ -447,6 +451,7 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid,
|
|||
ivl_expr_file(expr), ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
}
|
||||
//fallthrough
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
|
|
@ -465,6 +470,14 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid,
|
|||
fprintf(vlog_out, " %s ", oper);
|
||||
emit_expr(scope, oper2, wid, 0, can_skip_unsigned, is_full_prec);
|
||||
break;
|
||||
case 'w':
|
||||
case 'W':
|
||||
fprintf(stderr, "%s:%u: vlog95 error: The wild equality operators "
|
||||
"cannot be converted.\n",
|
||||
ivl_expr_file(expr),
|
||||
ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
// fallthrough
|
||||
case 'E':
|
||||
case 'e':
|
||||
case 'N':
|
||||
|
|
@ -492,6 +505,7 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid,
|
|||
ivl_expr_file(expr), ivl_expr_lineno(expr));
|
||||
vlog_errors += 1;
|
||||
}
|
||||
// fallthrough
|
||||
case 'l':
|
||||
case 'r':
|
||||
emit_expr(scope, oper1, wid, 0, 0, 0);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2016 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2011-2018 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -398,6 +398,8 @@ static ivl_nexus_t get_lpm_output(ivl_scope_t scope, ivl_lpm_t lpm)
|
|||
case IVL_LPM_CMP_GT:
|
||||
case IVL_LPM_CMP_NE:
|
||||
case IVL_LPM_CMP_NEE:
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
case IVL_LPM_CMP_WNE:
|
||||
case IVL_LPM_CONCAT:
|
||||
case IVL_LPM_CONCATZ:
|
||||
case IVL_LPM_DIVIDE:
|
||||
|
|
@ -1194,19 +1196,19 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm,
|
|||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_CMP_EQX:
|
||||
// HERE: Need to heck that this is not a real nexus.
|
||||
// HERE: Need to check that this is not a real nexus.
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " ==? ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Compare wildcard equal "
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Compare wildcard equal (caseX) "
|
||||
"operator is not supported.\n",
|
||||
ivl_lpm_file(lpm), ivl_lpm_lineno(lpm));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
case IVL_LPM_CMP_EQZ:
|
||||
// HERE: Need to heck that this is not a real nexus.
|
||||
// HERE: Need to check that this is not a real nexus.
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " == ");
|
||||
|
|
@ -1245,6 +1247,28 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm,
|
|||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
break;
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " ==? ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Wild equality "
|
||||
"operator is not supported.\n",
|
||||
ivl_lpm_file(lpm), ivl_lpm_lineno(lpm));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
case IVL_LPM_CMP_WNE:
|
||||
fprintf(vlog_out, "(");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0);
|
||||
fprintf(vlog_out, " !=? ");
|
||||
emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0);
|
||||
fprintf(vlog_out, ")");
|
||||
fprintf(stderr, "%s:%u: vlog95 error: Wild inequality "
|
||||
"operator is not supported.\n",
|
||||
ivl_lpm_file(lpm), ivl_lpm_lineno(lpm));
|
||||
vlog_errors += 1;
|
||||
break;
|
||||
/* A concat-Z should never be generated, but report it as an
|
||||
* error if one is generated. */
|
||||
case IVL_LPM_CONCATZ:
|
||||
|
|
@ -1252,6 +1276,7 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm,
|
|||
"should not be generated.\n",
|
||||
ivl_lpm_file(lpm), ivl_lpm_lineno(lpm));
|
||||
vlog_errors += 1;
|
||||
// fallthrough
|
||||
case IVL_LPM_CONCAT:
|
||||
emit_lpm_concat(scope, lpm);
|
||||
break;
|
||||
|
|
@ -2429,10 +2454,9 @@ void dump_nexus_information(ivl_scope_t scope, ivl_nexus_t nex)
|
|||
case IVL_VT_BOOL: fprintf(stderr, " bool"); break;
|
||||
case IVL_VT_LOGIC: fprintf(stderr, " logic"); break;
|
||||
case IVL_VT_STRING: fprintf(stderr, " string"); break;
|
||||
case IVL_VT_DARRAY: fprintf(stderr, " dynamic array");
|
||||
case IVL_VT_CLASS: fprintf(stderr, " class");
|
||||
case IVL_VT_QUEUE: fprintf(stderr, " queue");
|
||||
break;
|
||||
case IVL_VT_DARRAY: fprintf(stderr, " dynamic array"); break;
|
||||
case IVL_VT_CLASS: fprintf(stderr, " class"); break;
|
||||
case IVL_VT_QUEUE: fprintf(stderr, " queue"); break;
|
||||
}
|
||||
if (ivl_signal_signed(sig)) fprintf(stderr, " <signed>");
|
||||
} else fprintf(stderr, "Error: No/missing information!");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2014 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2011-2017 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -1606,6 +1606,9 @@ void emit_process(ivl_scope_t scope, ivl_process_t proc)
|
|||
fprintf(vlog_out, "initial");
|
||||
break;
|
||||
case IVL_PR_ALWAYS:
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
fprintf(vlog_out, "always");
|
||||
break;
|
||||
case IVL_PR_FINAL:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2016 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2010-2017 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
static const char*version_string =
|
||||
"Icarus Verilog VLOG95 Code Generator " VERSION " (" VERSION_TAG ")\n\n"
|
||||
"Copyright (C) 2010-2015 Cary R. (cygcary@yahoo.com)\n\n"
|
||||
"Copyright (C) 2010-2017 Cary R. (cygcary@yahoo.com)\n\n"
|
||||
" This program is free software; you can redistribute it and/or modify\n"
|
||||
" it under the terms of the GNU General Public License as published by\n"
|
||||
" the Free Software Foundation; either version 2 of the License, or\n"
|
||||
|
|
@ -219,9 +219,12 @@ int target_design(ivl_design_t des)
|
|||
/* Emit any UDP definitions that the design used. */
|
||||
emit_udp_list();
|
||||
|
||||
/* Emit any UDPs that are Icarus generated (D-FF). */
|
||||
/* Emit any UDPs that are Icarus generated (D-FF or latch). */
|
||||
emit_icarus_generated_udps();
|
||||
|
||||
/* Emit the Icarus top module used to trigger translated always_comb/latch processes at T0. */
|
||||
emit_icarus_generated_top_module();
|
||||
|
||||
/* If there were errors then add this information to the output. */
|
||||
if (vlog_errors) {
|
||||
fprintf(vlog_out, "\n");
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_vlog95_priv_H
|
||||
#define IVL_vlog95_priv_H
|
||||
/*
|
||||
* Copyright (C) 2010-2016 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2010-2017 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -106,7 +106,6 @@ extern void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex,
|
|||
extern void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex);
|
||||
extern void emit_const_nexus(ivl_scope_t scope, ivl_net_const_t const_net);
|
||||
extern void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig);
|
||||
extern void emit_icarus_generated_udps(void);
|
||||
|
||||
extern void add_udp_to_list(ivl_udp_t udp);
|
||||
extern void emit_udp_list(void);
|
||||
|
|
@ -118,6 +117,9 @@ extern void emit_number(const char *bits, unsigned nbits, unsigned is_signed,
|
|||
const char *file, unsigned lineno);
|
||||
extern void emit_string(const char *string);
|
||||
|
||||
extern void emit_icarus_generated_udps(void);
|
||||
extern void emit_icarus_generated_top_module(void);
|
||||
|
||||
/*
|
||||
* Find the enclosing module scope.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -398,6 +398,8 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
|||
case IVL_LPM_CONCATZ:
|
||||
case IVL_LPM_CMP_EEQ:
|
||||
case IVL_LPM_CMP_EQ:
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
case IVL_LPM_CMP_WNE:
|
||||
case IVL_LPM_CMP_EQX:
|
||||
case IVL_LPM_CMP_EQZ:
|
||||
case IVL_LPM_CMP_GE:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2018 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
|
||||
|
|
@ -73,6 +73,15 @@ void draw_switch_in_scope(ivl_switch_t sw)
|
|||
}
|
||||
|
||||
switch (ivl_switch_type(sw)) {
|
||||
case IVL_SW_RTRAN:
|
||||
fprintf(vvp_out, " .rtran");
|
||||
break;
|
||||
case IVL_SW_RTRANIF0:
|
||||
fprintf(vvp_out, " .rtranif0");
|
||||
break;
|
||||
case IVL_SW_RTRANIF1:
|
||||
fprintf(vvp_out, " .rtranif1");
|
||||
break;
|
||||
case IVL_SW_TRAN:
|
||||
fprintf(vvp_out, " .tran");
|
||||
break;
|
||||
|
|
@ -88,8 +97,7 @@ void draw_switch_in_scope(ivl_switch_t sw)
|
|||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s:%u: tgt-vvp sorry: resistive switch modeling "
|
||||
"is not currently supported.\n",
|
||||
fprintf(stderr, "%s:%u: tgt-vvp error: unrecognised switch type.\n",
|
||||
ivl_switch_file(sw), ivl_switch_lineno(sw));
|
||||
vvp_errors += 1;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ static int eval_darray_new(ivl_expr_t ex)
|
|||
unsigned idx;
|
||||
switch (ivl_type_base(element_type)) {
|
||||
case IVL_VT_BOOL:
|
||||
case IVL_VT_LOGIC:
|
||||
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
|
||||
draw_eval_vec4(ivl_expr_parm(init_expr,idx));
|
||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||
|
|
@ -110,6 +111,11 @@ static int eval_darray_new(ivl_expr_t ex)
|
|||
errors += 1;
|
||||
break;
|
||||
}
|
||||
} else if (init_expr && (ivl_expr_value(init_expr) == IVL_VT_DARRAY)) {
|
||||
ivl_signal_t sig = ivl_expr_signal(init_expr);
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
|
||||
fprintf(vvp_out, " %%scopy;\n");
|
||||
|
||||
} else if (init_expr && number_is_immediate(size_expr,32,0)) {
|
||||
/* In this case, there is an init expression, the
|
||||
expression is NOT an array_pattern, and the size
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2017 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
|
||||
|
|
@ -57,6 +57,8 @@ static void draw_binary_real(ivl_expr_t expr)
|
|||
switch (ivl_expr_opcode(expr)) {
|
||||
case 'E':
|
||||
case 'N':
|
||||
case 'w':
|
||||
case 'W':
|
||||
case 'l':
|
||||
case 'r':
|
||||
case 'R':
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2013-2017 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
|
||||
|
|
@ -385,8 +385,7 @@ static void draw_binary_vec4_compare(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%flag_get/vec4 4;\n");
|
||||
break;
|
||||
case 'n': /* != */
|
||||
fprintf(vvp_out, " %%cmp/e;\n");
|
||||
fprintf(vvp_out, " %%flag_inv 4;\n");
|
||||
fprintf(vvp_out, " %%cmp/ne;\n");
|
||||
fprintf(vvp_out, " %%flag_get/vec4 4;\n");
|
||||
break;
|
||||
case 'E': /* === */
|
||||
|
|
@ -394,10 +393,17 @@ static void draw_binary_vec4_compare(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%flag_get/vec4 6;\n");
|
||||
break;
|
||||
case 'N': /* !== */
|
||||
fprintf(vvp_out, " %%cmp/e;\n");
|
||||
fprintf(vvp_out, " %%flag_inv 6;\n");
|
||||
fprintf(vvp_out, " %%cmp/ne;\n");
|
||||
fprintf(vvp_out, " %%flag_get/vec4 6;\n");
|
||||
break;
|
||||
case 'w': /* ==? */
|
||||
fprintf(vvp_out, " %%cmp/we;\n");
|
||||
fprintf(vvp_out, " %%flag_get/vec4 4;\n");
|
||||
break;
|
||||
case 'W': /* !=? */
|
||||
fprintf(vvp_out, " %%cmp/wne;\n");
|
||||
fprintf(vvp_out, " %%flag_get/vec4 4;\n");
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -689,8 +695,10 @@ static void draw_binary_vec4(ivl_expr_t expr)
|
|||
|
||||
case 'e': /* == */
|
||||
case 'E': /* === */
|
||||
case 'n': /* !== */
|
||||
case 'n': /* != */
|
||||
case 'N': /* !== */
|
||||
case 'w': /* ==? */
|
||||
case 'W': /* !=? */
|
||||
draw_binary_vec4_compare(expr);
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2017 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
|
||||
|
|
@ -1643,6 +1643,7 @@ static int show_stmt_utask(ivl_statement_t net)
|
|||
|
||||
static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope)
|
||||
{
|
||||
static unsigned int cascade_counter = 0;
|
||||
/* Look to see if this is a SystemVerilog wait fork. */
|
||||
if ((ivl_stmt_nevent(net) == 1) && (ivl_stmt_events(net, 0) == 0)) {
|
||||
assert(ivl_statement_type(ivl_stmt_sub_stmt(net)) == IVL_ST_NOOP);
|
||||
|
|
@ -1655,11 +1656,17 @@ static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope)
|
|||
|
||||
if (ivl_stmt_nevent(net) == 1) {
|
||||
ivl_event_t ev = ivl_stmt_events(net, 0);
|
||||
fprintf(vvp_out, " %%wait E_%p;\n", ev);
|
||||
if (ivl_stmt_needs_t0_trigger(net)) {
|
||||
fprintf(vvp_out, "Ewait_%u .event/or E_%p, E_0x0;\n",
|
||||
cascade_counter, ev);
|
||||
fprintf(vvp_out, " %%wait Ewait_%u;\n", cascade_counter);
|
||||
cascade_counter += 1;
|
||||
} else {
|
||||
fprintf(vvp_out, " %%wait E_%p;\n", ev);
|
||||
}
|
||||
|
||||
} else {
|
||||
unsigned idx;
|
||||
static unsigned int cascade_counter = 0;
|
||||
ivl_event_t ev = ivl_stmt_events(net, 0);
|
||||
fprintf(vvp_out, "Ewait_%u .event/or E_%p", cascade_counter, ev);
|
||||
|
||||
|
|
@ -1667,6 +1674,7 @@ static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope)
|
|||
ev = ivl_stmt_events(net, idx);
|
||||
fprintf(vvp_out, ", E_%p", ev);
|
||||
}
|
||||
assert(ivl_stmt_needs_t0_trigger(net) == 0);
|
||||
fprintf(vvp_out, ";\n %%wait Ewait_%u;\n", cascade_counter);
|
||||
cascade_counter += 1;
|
||||
}
|
||||
|
|
@ -2358,6 +2366,9 @@ int draw_process(ivl_process_t net, void*x)
|
|||
break;
|
||||
|
||||
case IVL_PR_ALWAYS:
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
fprintf(vvp_out, " %%jmp T_%u;\n", thread_count);
|
||||
break;
|
||||
}
|
||||
|
|
@ -2368,6 +2379,9 @@ int draw_process(ivl_process_t net, void*x)
|
|||
|
||||
case IVL_PR_INITIAL:
|
||||
case IVL_PR_ALWAYS:
|
||||
case IVL_PR_ALWAYS_COMB:
|
||||
case IVL_PR_ALWAYS_FF:
|
||||
case IVL_PR_ALWAYS_LATCH:
|
||||
if (init_flag) {
|
||||
fprintf(vvp_out, " .thread T_%u, $init;\n", thread_count);
|
||||
} else if (push_flag) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2018 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
|
||||
|
|
@ -860,6 +860,7 @@ static void draw_udp_in_scope(ivl_net_logic_t lptr)
|
|||
* (.resolv, etc.) can be built before we build the .udp call.
|
||||
* This matches what is done for the other primitives.
|
||||
*/
|
||||
assert(ivl_logic_pins(lptr) > 0);
|
||||
ninp = ivl_logic_pins(lptr) - 1;
|
||||
input_strings = calloc(ninp, sizeof(char*));
|
||||
for (pdx = 0 ; pdx < ninp ; pdx += 1) {
|
||||
|
|
@ -922,7 +923,7 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
|||
ivl_drive_t str1 = ivl_logic_drive1(lptr);
|
||||
|
||||
int level;
|
||||
int ninp;
|
||||
unsigned ninp;
|
||||
const char **input_strings;
|
||||
|
||||
switch (ivl_logic_type(lptr)) {
|
||||
|
|
@ -1055,8 +1056,8 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
|
|||
|
||||
/* Get all the input label that I will use for parameters to
|
||||
the functor that I create later. */
|
||||
assert(ivl_logic_pins(lptr) > 0);
|
||||
ninp = ivl_logic_pins(lptr) - 1;
|
||||
assert(ninp >= 0);
|
||||
input_strings = calloc(ninp, sizeof(char*));
|
||||
for (pdx = 0 ; pdx < (unsigned)ninp ; pdx += 1)
|
||||
input_strings[pdx] = draw_net_input(ivl_logic_pin(lptr, pdx+1));
|
||||
|
|
@ -1521,6 +1522,16 @@ static void draw_lpm_cmp(ivl_lpm_t net)
|
|||
type = "nee";
|
||||
signed_string = "";
|
||||
break;
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
assert(dtc != IVL_VT_REAL); /* Should never get here! */
|
||||
type = "weq";
|
||||
signed_string = "";
|
||||
break;
|
||||
case IVL_LPM_CMP_WNE:
|
||||
assert(dtc != IVL_VT_REAL); /* Should never get here! */
|
||||
type = "wne";
|
||||
signed_string = "";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -2143,6 +2154,8 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
|
|||
case IVL_LPM_CMP_GT:
|
||||
case IVL_LPM_CMP_NE:
|
||||
case IVL_LPM_CMP_NEE:
|
||||
case IVL_LPM_CMP_WEQ:
|
||||
case IVL_LPM_CMP_WNE:
|
||||
draw_lpm_cmp(net);
|
||||
return;
|
||||
|
||||
|
|
@ -2292,7 +2305,7 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
|||
unsigned width = ivl_scope_mod_module_port_width(net,idx);
|
||||
if( name == 0 )
|
||||
name = "";
|
||||
fprintf( vvp_out, " .port_info %u %s %u \"%s\"\n",
|
||||
fprintf( vvp_out, " .port_info %u %s %u \"%s\";\n",
|
||||
idx, vvp_port_info_type_str(ptype), width,
|
||||
vvp_mangle_name(name) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2018 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
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
# include "verinum.h"
|
||||
# include <iostream>
|
||||
# include <cassert>
|
||||
# include <climits>
|
||||
# include <cmath> // Needed to get pow for as_double().
|
||||
# include <cstdio> // Needed to get snprintf for as_string().
|
||||
# include <algorithm>
|
||||
|
|
@ -1444,7 +1445,8 @@ verinum operator / (const verinum&left, const verinum&right)
|
|||
if (use_len <= (8*sizeof(long) - 1)) {
|
||||
long l = left.as_long();
|
||||
long r = right.as_long();
|
||||
long v = l / r;
|
||||
bool overflow = (l == LONG_MIN) && (r == -1);
|
||||
long v = overflow ? LONG_MIN : l / r;
|
||||
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
|
||||
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
||||
v >>= 1;
|
||||
|
|
@ -1518,7 +1520,8 @@ verinum operator % (const verinum&left, const verinum&right)
|
|||
/* Use native signed modulus to do the work. */
|
||||
long l = left.as_long();
|
||||
long r = right.as_long();
|
||||
long v = l % r;
|
||||
bool overflow = (l == LONG_MIN) && (r == -1);
|
||||
long v = overflow ? 0 : l % r;
|
||||
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
|
||||
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
||||
v >>= 1;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef VERIUSER_H
|
||||
#define VERIUSER_H
|
||||
/*
|
||||
* Copyright (c) 2002-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2018 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
|
||||
|
|
@ -159,6 +159,7 @@ extern void veriusertfs_register_table(p_tfcell vtable);
|
|||
|
||||
/* callback reasons */
|
||||
#define reason_checktf 1
|
||||
#define reason_sizetf 2
|
||||
#define reason_calltf 3
|
||||
#define reason_paramvc 7
|
||||
#define reason_synch 8
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_expression_H
|
||||
#define IVL_expression_H
|
||||
/*
|
||||
* Copyright (c) 2011-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2011-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2015 / Stephen Williams (steve@icarus.com),
|
||||
* Copyright CERN 2016
|
||||
* @author Maciej Suminski (maciej.suminski@cern.ch)
|
||||
|
|
@ -39,6 +39,10 @@ class VTypeArray;
|
|||
class VTypePrimitive;
|
||||
class ExpName;
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#define unique_ptr auto_ptr
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper class to recursively traverse an expression tree
|
||||
* (i.e. complex expressions).
|
||||
|
|
@ -273,8 +277,8 @@ class ExpAggregate : public Expression {
|
|||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
std::auto_ptr<Expression>expr_;
|
||||
std::auto_ptr<ExpRange> range_;
|
||||
std::unique_ptr<Expression>expr_;
|
||||
std::unique_ptr<ExpRange> range_;
|
||||
private: // not implemented
|
||||
choice_t& operator= (const choice_t&);
|
||||
};
|
||||
|
|
@ -778,7 +782,7 @@ class ExpName : public Expression {
|
|||
private:
|
||||
Expression*index(unsigned int number) const;
|
||||
|
||||
std::auto_ptr<ExpName> prefix_;
|
||||
std::unique_ptr<ExpName> prefix_;
|
||||
perm_string name_;
|
||||
std::list<Expression*>*indices_;
|
||||
};
|
||||
|
|
@ -1093,4 +1097,8 @@ private:
|
|||
Expression*delay_;
|
||||
};
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#undef unique_ptr
|
||||
#endif
|
||||
|
||||
#endif /* IVL_expression_H */
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2011-2017 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
|
||||
|
|
@ -748,7 +748,16 @@ yyscan_t prepare_lexor(FILE*fd)
|
|||
return scanner;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||
*/
|
||||
void destroy_lexor(yyscan_t scanner)
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy(scanner);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright CERN 2016
|
||||
* Copyright CERN 2016-2018
|
||||
* @author Maciej Suminski (maciej.suminski@cern.ch)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -201,7 +201,7 @@ void preload_std_funcs(void)
|
|||
args = new list<InterfacePort*>();
|
||||
args->push_back(new InterfacePort(&primitive_REAL));
|
||||
register_std_subprogram(new SubprogramBuiltin(perm_string::literal("integer"),
|
||||
perm_string::literal("$signed"),
|
||||
perm_string::literal("int'"),
|
||||
args, &primitive_INTEGER));
|
||||
|
||||
/* function std_logic_vector
|
||||
|
|
|
|||
|
|
@ -45,13 +45,14 @@ else
|
|||
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @file64_support@ @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CPPFLAGS = $(INCLUDE_PATH) @file64_support@ @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const @PICFLAG@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
# Object files for system.vpi
|
||||
O = sys_table.o sys_convert.o sys_countdrivers.o sys_darray.o sys_deposit.o sys_display.o \
|
||||
O = sys_table.o sys_convert.o sys_countdrivers.o sys_darray.o sys_deposit.o \
|
||||
sys_display.o \
|
||||
sys_fileio.o sys_finish.o sys_icarus.o sys_plusargs.o sys_queue.o \
|
||||
sys_random.o sys_random_mti.o sys_readmem.o sys_readmem_lex.o sys_scanf.o \
|
||||
sys_sdf.o sys_time.o sys_vcd.o sys_vcdoff.o vcd_priv.o mt19937int.o \
|
||||
|
|
@ -73,7 +74,8 @@ M = sys_clog2.o v2005_math.o
|
|||
# Object files for va_math.vpi
|
||||
V = va_math.o
|
||||
|
||||
V2009 = v2009_table.o v2009_array.o v2009_enum.o v2009_string.o
|
||||
V2009 = v2009_table.o v2009_array.o v2009_bitvec.o v2009_enum.o v2009_string.o \
|
||||
sys_priv.o
|
||||
|
||||
VHDL_SYS = vhdl_table.o sys_priv.o
|
||||
|
||||
|
|
|
|||
|
|
@ -45,83 +45,83 @@ variableScope:fstapi.c:6238
|
|||
variableScope:fstapi.c:6466
|
||||
// These functions are not used by Icarus
|
||||
// fstReaderClrFacProcessMask()
|
||||
unusedFunction:fstapi.c:3344
|
||||
unusedFunction:fstapi.c:3345
|
||||
// fstReaderClrFacProcessMaskAll()
|
||||
unusedFunction:fstapi.c:3373
|
||||
unusedFunction:fstapi.c:3374
|
||||
// fstReaderGetAliasCount()
|
||||
unusedFunction:fstapi.c:3436
|
||||
unusedFunction:fstapi.c:3437
|
||||
// fstReaderGetCurrentFlatScope()
|
||||
unusedFunction:fstapi.c:3182
|
||||
unusedFunction:fstapi.c:3183
|
||||
// fstReaderGetAliasCount()
|
||||
unusedFunction:fstapi.c:3279
|
||||
unusedFunction:fstapi.c:3280
|
||||
// fstReaderGetCurrentScopeUserInfo()
|
||||
unusedFunction:fstapi.c:3196
|
||||
unusedFunction:fstapi.c:3197
|
||||
// fstReaderGetDateString()
|
||||
unusedFunction:fstapi.c:3464
|
||||
unusedFunction:fstapi.c:3465
|
||||
// fstReaderGetDoubleEndianMatchState()
|
||||
unusedFunction:fstapi.c:3450
|
||||
unusedFunction:fstapi.c:3451
|
||||
// fstReaderGetDumpActivityChangeTime()
|
||||
unusedFunction:fstapi.c:3492
|
||||
unusedFunction:fstapi.c:3493
|
||||
// fstReaderGetDumpActivityChangeValue()
|
||||
unusedFunction:fstapi.c:3507
|
||||
unusedFunction:fstapi.c:3508
|
||||
// fstReaderGetEndTime()
|
||||
unusedFunction:fstapi.c:3401
|
||||
unusedFunction:fstapi.c:3402
|
||||
// fstReaderGetFacProcessMask()
|
||||
unusedFunction:fstapi.c:3307
|
||||
unusedFunction:fstapi.c:3308
|
||||
// fstReaderGetFileType()
|
||||
unusedFunction:fstapi.c:3471
|
||||
unusedFunction:fstapi.c:3472
|
||||
// fstReaderGetFseekFailed()
|
||||
unusedFunction:fstapi.c:3292
|
||||
unusedFunction:fstapi.c:3293
|
||||
// fstReaderGetMaxHandle()
|
||||
unusedFunction:fstapi.c:3429
|
||||
unusedFunction:fstapi.c:3430
|
||||
// fstReaderGetMemoryUsedByWriter()
|
||||
unusedFunction:fstapi.c:3408
|
||||
unusedFunction:fstapi.c:3409
|
||||
// fstReaderGetNumberDumpActivityChanges()
|
||||
unusedFunction:fstapi.c:3485
|
||||
unusedFunction:fstapi.c:3486
|
||||
// fstReaderGetScopeCount()
|
||||
unusedFunction:fstapi.c:3415
|
||||
unusedFunction:fstapi.c:3416
|
||||
// fstReaderGetStartTime()
|
||||
unusedFunction:fstapi.c:3394
|
||||
unusedFunction:fstapi.c:3395
|
||||
// fstReaderGetTimescale()
|
||||
unusedFunction:fstapi.c:3387
|
||||
unusedFunction:fstapi.c:3388
|
||||
// fstReaderGetTimezero()
|
||||
unusedFunction:fstapi.c:3478
|
||||
unusedFunction:fstapi.c:3479
|
||||
// fstReaderGetValueChangeSectionCount()
|
||||
unusedFunction:fstapi.c:3443
|
||||
unusedFunction:fstapi.c:3444
|
||||
// fstReaderGetValueFromHandleAtTime()
|
||||
unusedFunction:fstapi.c:5685
|
||||
unusedFunction:fstapi.c:5686
|
||||
// fstReaderGetVarCount()
|
||||
unusedFunction:fstapi.c:3422
|
||||
unusedFunction:fstapi.c:3423
|
||||
// fstReaderGetVersionString()
|
||||
unusedFunction:fstapi.c:3457
|
||||
unusedFunction:fstapi.c:3458
|
||||
// fstReaderIterBlocks()
|
||||
unusedFunction:fstapi.c:4652
|
||||
unusedFunction:fstapi.c:4653
|
||||
// fstReaderIterBlocksSetNativeDoublesOnCallback()
|
||||
unusedFunction:fstapi.c:3557
|
||||
unusedFunction:fstapi.c:3558
|
||||
// fstReaderIterateHier()
|
||||
unusedFunction:fstapi.c:3782
|
||||
unusedFunction:fstapi.c:3783
|
||||
// fstReaderIterateHierRewind()
|
||||
unusedFunction:fstapi.c:3762
|
||||
unusedFunction:fstapi.c:3763
|
||||
// fstReaderOpen()
|
||||
unusedFunction:fstapi.c:4550
|
||||
unusedFunction:fstapi.c:4551
|
||||
// fstReaderOpenForUtilitiesOnly()
|
||||
unusedFunction:fstapi.c:4542
|
||||
unusedFunction:fstapi.c:4543
|
||||
// fstReaderPushScope()
|
||||
unusedFunction:fstapi.c:3244
|
||||
unusedFunction:fstapi.c:3245
|
||||
// fstReaderResetScope()
|
||||
unusedFunction:fstapi.c:3233
|
||||
unusedFunction:fstapi.c:3234
|
||||
// fstReaderSetFacProcessMask()
|
||||
unusedFunction:fstapi.c:3326
|
||||
unusedFunction:fstapi.c:3327
|
||||
// fstReaderSetFacProcessMaskAll()
|
||||
unusedFunction:fstapi.c:3362
|
||||
unusedFunction:fstapi.c:3363
|
||||
// fstReaderSetLimitTimeRange()
|
||||
unusedFunction:fstapi.c:3522
|
||||
unusedFunction:fstapi.c:3523
|
||||
// fstReaderSetUnlimitedTimeRange()
|
||||
unusedFunction:fstapi.c:3535
|
||||
unusedFunction:fstapi.c:3536
|
||||
// fstReaderSetVcdExtensions()
|
||||
unusedFunction:fstapi.c:3546
|
||||
unusedFunction:fstapi.c:3547
|
||||
// fstUtilityEscToBin()
|
||||
unusedFunction:fstapi.c:6485
|
||||
unusedFunction:fstapi.c:6544
|
||||
// fstWriterCreateVar2()
|
||||
unusedFunction:fstapi.c:2528
|
||||
// fstWriterEmitVariableLengthValueChange()
|
||||
|
|
@ -232,6 +232,10 @@ unusedLabel:fastlz.c:545
|
|||
// These functions are not used by Icarus
|
||||
// fastlz_compress_level()
|
||||
unusedFunction:fastlz.c:150
|
||||
// FASTLZ_COMPRESSOR()
|
||||
unusedFunction:fastlz.c:162
|
||||
// FASTLZ_DECOMPRESSOR()
|
||||
unusedFunction:fastlz.c:416
|
||||
|
||||
// lz4.c from GTKWave
|
||||
// These functions are not used by Icarus
|
||||
|
|
|
|||
566
vpi/fstapi.c
566
vpi/fstapi.c
File diff suppressed because it is too large
Load Diff
38
vpi/fstapi.h
38
vpi/fstapi.h
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2015 Tony Bybell.
|
||||
* Copyright (c) 2009-2018 Tony Bybell.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -39,6 +39,7 @@ extern "C" {
|
|||
#define FST_RDLOAD "FSTLOAD | "
|
||||
|
||||
typedef uint32_t fstHandle;
|
||||
typedef uint32_t fstEnumHandle;
|
||||
|
||||
enum fstWriterPackType {
|
||||
FST_WR_PT_ZLIB = 0,
|
||||
|
|
@ -168,7 +169,11 @@ enum fstHierType {
|
|||
FST_HT_ATTRBEGIN = 3,
|
||||
FST_HT_ATTREND = 4,
|
||||
|
||||
FST_HT_MAX = 4
|
||||
/* FST_HT_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */
|
||||
FST_HT_TREEBEGIN = 5,
|
||||
FST_HT_TREEEND = 6,
|
||||
|
||||
FST_HT_MAX = 6
|
||||
};
|
||||
|
||||
enum fstAttrType {
|
||||
|
|
@ -192,9 +197,10 @@ enum fstMiscType {
|
|||
FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */
|
||||
FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */
|
||||
FST_MT_VALUELIST = 6, /* use fstWriterSetValueList() to emit, followed by fstWriterCreateVar*() */
|
||||
FST_MT_UNKNOWN = 7,
|
||||
FST_MT_ENUMTABLE = 7, /* use fstWriterCreateEnumTable() and fstWriterEmitEnumTableRef() to emit */
|
||||
FST_MT_UNKNOWN = 8,
|
||||
|
||||
FST_MT_MAX = 7
|
||||
FST_MT_MAX = 8
|
||||
};
|
||||
|
||||
enum fstArrayType {
|
||||
|
|
@ -224,7 +230,10 @@ enum fstEnumValueType {
|
|||
FST_EV_SV_UNSIGNED_LONGINT = 12,
|
||||
FST_EV_SV_UNSIGNED_BYTE = 13,
|
||||
|
||||
FST_EV_MAX = 13
|
||||
FST_EV_REG = 14,
|
||||
FST_EV_TIME = 15,
|
||||
|
||||
FST_EV_MAX = 15
|
||||
};
|
||||
|
||||
enum fstPackType {
|
||||
|
|
@ -320,11 +329,21 @@ union {
|
|||
};
|
||||
|
||||
|
||||
struct fstETab
|
||||
{
|
||||
char *name;
|
||||
uint32_t elem_count;
|
||||
char **literal_arr;
|
||||
char **val_arr;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* writer functions
|
||||
*/
|
||||
void fstWriterClose(void *ctx);
|
||||
void * fstWriterCreate(const char *nam, int use_compressed_hier);
|
||||
fstEnumHandle fstWriterCreateEnumTable(void *ctx, const char *name, uint32_t elem_count, unsigned int min_valbits, const char **literal_arr, const char **val_arr);
|
||||
/* used for Verilog/SV */
|
||||
fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle);
|
||||
|
|
@ -333,9 +352,10 @@ fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir
|
|||
fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle,
|
||||
const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt);
|
||||
void fstWriterEmitDumpActive(void *ctx, int enable);
|
||||
void fstWriterEmitEnumTableRef(void *ctx, fstEnumHandle handle);
|
||||
void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
|
||||
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
|
||||
void fstWriterEmitDumpActive(void *ctx, int enable);
|
||||
void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
|
||||
void fstWriterFlushContext(void *ctx);
|
||||
int fstWriterGetDumpSizeLimitReached(void *ctx);
|
||||
|
|
@ -418,8 +438,12 @@ void fstReaderSetVcdExtensions(void *ctx, int enable);
|
|||
/*
|
||||
* utility functions
|
||||
*/
|
||||
int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len);
|
||||
int fstUtilityBinToEscConvertedLen(const unsigned char *s, int len); /* used for mallocs for fstUtilityBinToEsc() */
|
||||
int fstUtilityBinToEsc(unsigned char *d, const unsigned char *s, int len);
|
||||
int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len);
|
||||
struct fstETab *fstUtilityExtractEnumTableFromString(const char *s);
|
||||
void fstUtilityFreeEnumTable(struct fstETab *etab); /* must use to free fstETab properly */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ if (lo<hi)
|
|||
|
||||
static void wave_msort(struct lxt2_wr_symbol **a, int num)
|
||||
{
|
||||
struct lxt2_wr_symbol **b = malloc(((num/2)+1) * sizeof(struct lxt2_wr_symbol *));
|
||||
struct lxt2_wr_symbol **b = (struct lxt2_wr_symbol**)malloc(((num/2)+1) * sizeof(struct lxt2_wr_symbol *));
|
||||
|
||||
wave_mergesort(a, b, 0, num-1);
|
||||
|
||||
|
|
@ -583,7 +583,7 @@ unsigned int i;
|
|||
if((lt)&&(lt->numfacs))
|
||||
{
|
||||
struct lxt2_wr_symbol *s = lt->symchain;
|
||||
struct lxt2_wr_symbol **aliascache = calloc(lt->numalias ? lt->numalias : 1, sizeof(struct lxt2_wr_symbol *));
|
||||
struct lxt2_wr_symbol **aliascache = (struct lxt2_wr_symbol**)calloc(lt->numalias ? lt->numalias : 1, sizeof(struct lxt2_wr_symbol *));
|
||||
unsigned int aliases_encountered, facs_encountered;
|
||||
|
||||
lt->sorted_facs = (struct lxt2_wr_symbol **)calloc(lt->numfacs, sizeof(struct lxt2_wr_symbol *));
|
||||
|
|
@ -920,7 +920,7 @@ if(flags&LXT2_WR_SYM_F_DOUBLE)
|
|||
s->len = 32;
|
||||
}
|
||||
|
||||
s->value = malloc(s->len + 1);
|
||||
s->value = (char*)malloc(s->len + 1);
|
||||
memset(s->value, lt->initial_value, s->len);
|
||||
s->value[s->len]=0;
|
||||
|
||||
|
|
@ -1017,7 +1017,7 @@ static void lxt2_wr_emit_do_breakfile(struct lxt2_wr_trace *lt)
|
|||
{
|
||||
unsigned int len = strlen(lt->lxtname);
|
||||
int i;
|
||||
char *tname = malloc(len + 30);
|
||||
char *tname = (char*)malloc(len + 30);
|
||||
FILE *f2, *clone;
|
||||
off_t cnt, seg;
|
||||
char buf[32768];
|
||||
|
|
@ -1810,13 +1810,13 @@ while(s->aliased_to) /* find root alias if exists */
|
|||
valuelen = strlen(value); /* ensure string is proper length */
|
||||
if(valuelen == s->len)
|
||||
{
|
||||
vfix = wave_alloca(s->len+1);
|
||||
vfix = (char*)wave_alloca(s->len+1);
|
||||
strcpy(vfix, value);
|
||||
value = vfix;
|
||||
}
|
||||
else
|
||||
{
|
||||
vfix = wave_alloca(s->len+1);
|
||||
vfix = (char*)wave_alloca(s->len+1);
|
||||
|
||||
if(valuelen < s->len)
|
||||
{
|
||||
|
|
@ -2088,7 +2088,7 @@ if((lt)&&(lt->blackout))
|
|||
else
|
||||
{
|
||||
free(s->value);
|
||||
s->value = calloc(1, 1*sizeof(char));
|
||||
s->value = (char*)calloc(1, 1*sizeof(char));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2101,9 +2101,11 @@ if((lt)&&(lt->blackout))
|
|||
{
|
||||
if((!(s->flags&LXT2_WR_SYM_F_ALIAS))&&(s->rows<2))
|
||||
{
|
||||
char tmp[16]; /* To get rid of the warning */
|
||||
if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING)))
|
||||
{
|
||||
lxt2_wr_emit_value_bit_string(lt, s, 0, "x");
|
||||
strcpy(tmp, "x");
|
||||
lxt2_wr_emit_value_bit_string(lt, s, 0, tmp);
|
||||
}
|
||||
else if (s->flags&LXT2_WR_SYM_F_DOUBLE)
|
||||
{
|
||||
|
|
@ -2113,7 +2115,8 @@ if((lt)&&(lt->blackout))
|
|||
}
|
||||
else if (s->flags&LXT2_WR_SYM_F_STRING)
|
||||
{
|
||||
lxt2_wr_emit_value_string(lt, s, 0, "UNDEF");
|
||||
strcpy(tmp, "UNDEF");
|
||||
lxt2_wr_emit_value_string(lt, s, 0, tmp);
|
||||
}
|
||||
}
|
||||
s=s->symchain;
|
||||
|
|
@ -2202,4 +2205,3 @@ if(lt)
|
|||
lt->timezero = timeval;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue