Pass local scope precision from compiler to vvp/etc.
[iverilog.git] / vvp / part.cc
blob27c1d7b14c5c3454c3291a131878d4383d76f221
1 /*
2 * Copyright (c) 2004 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ident "$Id: part.cc,v 1.12 2006/11/16 01:11:26 steve Exp $"
21 # include "compile.h"
22 # include "part.h"
23 # include <stdlib.h>
24 # include <limits.h>
25 #ifdef HAVE_MALLOC_H
26 # include <malloc.h>
27 #endif
28 # include <iostream>
29 # include <assert.h>
31 vvp_fun_part::vvp_fun_part(unsigned base, unsigned wid)
32 : base_(base), wid_(wid)
34 net_ = 0;
37 vvp_fun_part::~vvp_fun_part()
41 void vvp_fun_part::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
43 assert(port.port() == 0);
45 if (val_ .eeq( bit ))
46 return;
48 val_ = bit;
50 if (net_ == 0) {
51 net_ = port.ptr();
52 schedule_generic(this, 0, false);
57 * Handle the case that the part select node is actually fed by a part
58 * select assignment. It's not exactly clear what might make this
59 * happen, but is does seem to happen and this should have sell
60 * defined behavior.
62 void vvp_fun_part::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
63 unsigned base, unsigned wid, unsigned vwid)
65 assert(bit.size() == wid);
67 vvp_vector4_t tmp = val_;
68 if (tmp.size() == 0)
69 tmp = vvp_vector4_t(vwid);
71 assert(tmp.size() == vwid);
72 tmp.set_vec(base, bit);
73 recv_vec4(port, tmp);
76 void vvp_fun_part::run_run()
78 vvp_net_t*ptr = net_;
79 net_ = 0;
81 vvp_vector4_t res (wid_, BIT4_X);
82 for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
83 if (idx + base_ < val_.size())
84 res.set_bit(idx, val_.value(base_+idx));
86 vvp_send_vec4(ptr->out, res);
89 vvp_fun_part_pv::vvp_fun_part_pv(unsigned b, unsigned w, unsigned v)
90 : base_(b), wid_(w), vwid_(v)
94 vvp_fun_part_pv::~vvp_fun_part_pv()
98 void vvp_fun_part_pv::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
100 assert(port.port() == 0);
102 if (bit.size() != wid_) {
103 cerr << "internal error: part_pv data mismatch. "
104 << "base_=" << base_ << ", wid_=" << wid_
105 << ", vwid_=" << vwid_ << ", bit=" << bit
106 << endl;
108 assert(bit.size() == wid_);
110 vvp_send_vec4_pv(port.ptr()->out, bit, base_, wid_, vwid_);
113 vvp_fun_part_var::vvp_fun_part_var(unsigned w)
114 : base_(0), wid_(w)
118 vvp_fun_part_var::~vvp_fun_part_var()
122 void vvp_fun_part_var::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
124 unsigned long tmp;
125 switch (port.port()) {
126 case 0:
127 source_ = bit;
128 break;
129 case 1:
130 tmp = ULONG_MAX;
131 vector4_to_value(bit, tmp);
132 if (tmp == base_) return;
133 base_ = tmp;
134 break;
135 default:
136 fprintf(stderr, "Unsupported port type %d.\n", port.port());
137 assert(0);
138 break;
141 vvp_vector4_t res (wid_);
143 for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
144 unsigned adr = base_+idx;
145 if (adr >= source_.size())
146 break;
148 res.set_bit(idx, source_.value(adr));
151 if (! ref_.eeq(res)) {
152 ref_ = res;
153 vvp_send_vec4(port.ptr()->out, res);
159 * Given a node functor, create a network node and link it into the
160 * netlist. This form assumes nodes with a single input.
162 void link_node_1(char*label, char*source, vvp_net_fun_t*fun)
164 vvp_net_t*net = new vvp_net_t;
165 net->fun = fun;
167 define_functor_symbol(label, net);
168 free(label);
170 input_connect(net, 0, source);
173 void compile_part_select(char*label, char*source,
174 unsigned base, unsigned wid)
176 vvp_fun_part*fun = new vvp_fun_part(base, wid);
177 link_node_1(label, source, fun);
180 void compile_part_select_pv(char*label, char*source,
181 unsigned base, unsigned wid,
182 unsigned vector_wid)
184 vvp_fun_part_pv*fun = new vvp_fun_part_pv(base, wid, vector_wid);
185 link_node_1(label, source, fun);
188 void compile_part_select_var(char*label, char*source, char*var,
189 unsigned wid)
191 vvp_fun_part_var*fun = new vvp_fun_part_var(wid);
192 vvp_net_t*net = new vvp_net_t;
193 net->fun = fun;
195 define_functor_symbol(label, net);
196 free(label);
198 input_connect(net, 0, source);
199 input_connect(net, 1, var);