File: net_func.cc

package info (click to toggle)
iverilog 13.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 34,160 kB
  • sloc: cpp: 114,001; ansic: 65,058; yacc: 10,610; sh: 4,286; vhdl: 3,246; makefile: 1,884; perl: 1,813; python: 579; csh: 2
file content (128 lines) | stat: -rw-r--r-- 3,388 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * Copyright (c) 2002-2025 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

# include  "config.h"
# include  "netlist.h"
# include  "compiler.h"
# include  "PExpr.h"
# include  <iostream>

using namespace std;

/*
 * To make a NetUserFunc device, make as many pins as there are ports
 * in the function. Get the port count from the function definition,
 * which accounts for all the inputs, plus one for the phantom output
 * that is the result.
 */
NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d,
                         NetEvWait*trigger__)
: NetNode(s, n, d->func_def()->port_count()+1),
  def_(d), trigger_(trigger__)
{
      pin(0).set_dir(Link::OUTPUT);

      for (unsigned idx = 1 ;  idx < pin_count() ;  idx += 1) {

	    pin(idx).set_dir(Link::INPUT);
	    pin(idx).drive0(IVL_DR_HiZ);
	    pin(idx).drive1(IVL_DR_HiZ);
      }
}

NetUserFunc::~NetUserFunc()
{
}

unsigned NetUserFunc::port_width(unsigned port) const
{
      const NetFuncDef*fdef = def_->func_def();

	/* Port 0 is the return port. */
      if (port == 0) {
	    const NetNet*sig = fdef->return_sig();
	    assert(sig);
	    return sig->vector_width();
      }

      port -= 1;
      assert(port < fdef->port_count());
      const NetNet*port_sig = fdef->port(port);

      return port_sig->vector_width();
}

const NetScope* NetUserFunc::def() const
{
      return def_;
}

/*
 * This method of the PECallFunction class checks that the parameters
 * of the PECallFunction match the function definition. This is used
 * during elaboration to validate the parameters before using them.
 */
bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope) const
{
      assert(dscope);

      if (dscope->type() != NetScope::FUNC) {
	    cerr << get_fileline() << ": error: Attempt to call scope "
		 << scope_path(dscope) << " as a function." << endl;
	    des->errors += 1;
	    return false;
      }

      return true;
}


NetSysFunc::NetSysFunc(NetScope*s, perm_string n,
		       const struct sfunc_return_type*def,
		       unsigned ports, NetEvWait*trigger__)
: NetNode(s, n, ports), def_(def), trigger_(trigger__)
{
      pin(0).set_dir(Link::OUTPUT); // Q

      for (unsigned idx = 1 ;  idx < pin_count() ;  idx += 1) {

	    pin(idx).set_dir(Link::INPUT);
	    pin(idx).drive0(IVL_DR_HiZ);
	    pin(idx).drive1(IVL_DR_HiZ);
      }
}

NetSysFunc::~NetSysFunc()
{
}

const char*NetSysFunc::func_name() const
{
      return def_->name;
}

ivl_variable_type_t NetSysFunc::data_type() const
{
      return def_->type;
}

unsigned NetSysFunc::vector_width() const
{
      return def_->wid;
}