Fix the debugger to finish correctly.
[iverilog.git] / vvp / reduce.cc
blobfe18907f4d1492efddc0592e6ee44f22aaf8e4a2
1 /*
2 * Copyright (c) 2005-2007 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 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: reduce.cc,v 1.4 2006/05/01 20:47:03 steve Exp $"
21 #endif
23 # include "compile.h"
24 # include "schedule.h"
25 # include <limits.h>
26 # include <stdio.h>
27 # include <assert.h>
28 # include <stdlib.h>
29 #ifdef HAVE_MALLOC_H
30 # include <malloc.h>
31 #endif
34 * All the reduction operations take a single vector input and produce
35 * a scalar result. The vvp_reduce_base class codifies these general
36 * charactoristics, leaving only the calculation of the result for the
37 * base class.
39 class vvp_reduce_base : public vvp_net_fun_t {
41 public:
42 vvp_reduce_base();
43 virtual ~vvp_reduce_base();
45 void recv_vec4(vvp_net_ptr_t prt, const vvp_vector4_t&bit);
46 void recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
47 unsigned base, unsigned wid, unsigned vwid);
49 virtual vvp_bit4_t calculate_result() const =0;
51 protected:
52 vvp_vector4_t bits_;
55 vvp_reduce_base::vvp_reduce_base()
59 vvp_reduce_base::~vvp_reduce_base()
63 void vvp_reduce_base::recv_vec4(vvp_net_ptr_t prt, const vvp_vector4_t&bit)
65 bits_ = bit;
66 vvp_bit4_t res = calculate_result();
67 vvp_vector4_t rv (1, res);
68 vvp_send_vec4(prt.ptr()->out, rv);
71 void vvp_reduce_base::recv_vec4_pv(vvp_net_ptr_t prt, const vvp_vector4_t&bit,
72 unsigned base, unsigned wid, unsigned vwid)
74 if (bits_.size() == 0) {
75 bits_ = vvp_vector4_t(vwid);
77 assert(bits_.size() == vwid);
79 assert(bit.size() == wid);
80 bits_.set_vec(base, bit);
81 vvp_bit4_t res = calculate_result();
82 vvp_vector4_t rv (1, res);
83 vvp_send_vec4(prt.ptr()->out, rv);
86 class vvp_reduce_and : public vvp_reduce_base {
88 public:
89 vvp_reduce_and();
90 ~vvp_reduce_and();
91 vvp_bit4_t calculate_result() const;
94 vvp_reduce_and::vvp_reduce_and()
98 vvp_reduce_and::~vvp_reduce_and()
102 vvp_bit4_t vvp_reduce_and::calculate_result() const
104 vvp_bit4_t res = BIT4_1;
106 for (unsigned idx = 0 ; idx < bits_.size() ; idx += 1)
107 res = res & bits_.value(idx);
109 return res;
112 class vvp_reduce_or : public vvp_reduce_base {
114 public:
115 vvp_reduce_or();
116 ~vvp_reduce_or();
117 vvp_bit4_t calculate_result() const;
120 vvp_reduce_or::vvp_reduce_or()
124 vvp_reduce_or::~vvp_reduce_or()
128 vvp_bit4_t vvp_reduce_or::calculate_result() const
130 vvp_bit4_t res = BIT4_0;
132 for (unsigned idx = 0 ; idx < bits_.size() ; idx += 1)
133 res = res | bits_.value(idx);
135 return res;
138 class vvp_reduce_xor : public vvp_reduce_base {
140 public:
141 vvp_reduce_xor();
142 ~vvp_reduce_xor();
143 vvp_bit4_t calculate_result() const;
146 vvp_reduce_xor::vvp_reduce_xor()
150 vvp_reduce_xor::~vvp_reduce_xor()
154 vvp_bit4_t vvp_reduce_xor::calculate_result() const
156 vvp_bit4_t res = BIT4_0;
158 for (unsigned idx = 0 ; idx < bits_.size() ; idx += 1)
159 res = res ^ bits_.value(idx);
161 return res;
164 class vvp_reduce_nand : public vvp_reduce_base {
166 public:
167 vvp_reduce_nand();
168 ~vvp_reduce_nand();
169 vvp_bit4_t calculate_result() const;
172 vvp_reduce_nand::vvp_reduce_nand()
176 vvp_reduce_nand::~vvp_reduce_nand()
180 vvp_bit4_t vvp_reduce_nand::calculate_result() const
182 vvp_bit4_t res = BIT4_1;
184 for (unsigned idx = 0 ; idx < bits_.size() ; idx += 1)
185 res = res & bits_.value(idx);
187 return ~res;
190 class vvp_reduce_nor : public vvp_reduce_base {
192 public:
193 vvp_reduce_nor();
194 ~vvp_reduce_nor();
195 vvp_bit4_t calculate_result() const;
198 vvp_reduce_nor::vvp_reduce_nor()
202 vvp_reduce_nor::~vvp_reduce_nor()
206 vvp_bit4_t vvp_reduce_nor::calculate_result() const
208 vvp_bit4_t res = BIT4_0;
210 for (unsigned idx = 0 ; idx < bits_.size() ; idx += 1)
211 res = res | bits_.value(idx);
213 return ~res;
216 class vvp_reduce_xnor : public vvp_reduce_base {
218 public:
219 vvp_reduce_xnor();
220 ~vvp_reduce_xnor();
221 vvp_bit4_t calculate_result() const;
224 vvp_reduce_xnor::vvp_reduce_xnor()
228 vvp_reduce_xnor::~vvp_reduce_xnor()
232 vvp_bit4_t vvp_reduce_xnor::calculate_result() const
234 vvp_bit4_t res = BIT4_0;
236 for (unsigned idx = 0 ; idx < bits_.size() ; idx += 1)
237 res = res ^ bits_.value(idx);
239 return ~res;
242 static void make_reduce(char*label, vvp_net_fun_t*red, struct symb_s arg)
244 vvp_net_t*ptr = new vvp_net_t;
245 ptr->fun = red;
247 define_functor_symbol(label, ptr);
248 free(label);
250 input_connect(ptr, 0, arg.text);
253 void compile_reduce_and(char*label, struct symb_s arg)
255 vvp_reduce_and* reduce = new vvp_reduce_and;
256 make_reduce(label, reduce, arg);
259 void compile_reduce_or(char*label, struct symb_s arg)
261 vvp_reduce_or* reduce = new vvp_reduce_or;
262 make_reduce(label, reduce, arg);
265 void compile_reduce_xor(char*label, struct symb_s arg)
267 vvp_reduce_xor* reduce = new vvp_reduce_xor;
268 make_reduce(label, reduce, arg);
271 void compile_reduce_nand(char*label, struct symb_s arg)
273 vvp_reduce_nand* reduce = new vvp_reduce_nand;
274 make_reduce(label, reduce, arg);
277 void compile_reduce_nor(char*label, struct symb_s arg)
279 vvp_reduce_nor* reduce = new vvp_reduce_nor;
280 make_reduce(label, reduce, arg);
283 void compile_reduce_xnor(char*label, struct symb_s arg)
285 vvp_reduce_xnor* reduce = new vvp_reduce_xnor;
286 make_reduce(label, reduce, arg);