1 #ifndef IVL_udp_H
2 #define IVL_udp_H
3 /*
4  * Copyright (c) 2005-2014 Stephen Williams (steve@icarus.com)
5  *
6  * (This is a rewrite of code that was ...
7  * Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>)
8  *
9  *    This source code is free software; you can redistribute it
10  *    and/or modify it in source code form under the terms of the GNU
11  *    General Public License as published by the Free Software
12  *    Foundation; either version 2 of the License, or (at your option)
13  *    any later version.
14  *
15  *    This program is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with this program; if not, write to the Free Software
22  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  */
24 
25 # include  "vvp_net.h"
26 # include  "schedule.h"
27 
28 struct udp_levels_table;
29 
30 struct vvp_udp_s {
31 
32     public:
33       explicit vvp_udp_s(char*label, char*name, unsigned ports,
34                          vvp_bit4_t init, bool type);
35       virtual ~vvp_udp_s();
36 
37 	// Return the number of input ports for the defined UDP. This
38 	// does *not* include the current output value for a
39 	// sequential UDP.
40       unsigned port_count() const;
is_sequentialvvp_udp_s41       bool is_sequential() const { return seq_; };
namevvp_udp_s42       char *name() { return name_; }
43 
44 	// Return the initial output value.
45       vvp_bit4_t get_init() const;
46 
47       virtual vvp_bit4_t calculate_output(const udp_levels_table&cur,
48 					  const udp_levels_table&prev,
49 					  vvp_bit4_t cur_out) =0;
50 
51     private:
52       char *name_;
53       unsigned ports_;
54       vvp_bit4_t init_;
55       bool seq_;
56 };
57 
58 /*
59  * The vvp_udp_async_s instance represents a *definition* of a
60  * primitive. netlist instances refer to these definitions.
61  *
62  * The ports argument of the constructor is the number of input ports
63  * to the device. The single output port is not counted. The port
64  * count must be greater than 0.
65  *
66  * A level sensitive UDP has a table that includes all the rows that
67  * generate a 0 output and another table that includes all the rows
68  * that generate a 1 output. A set of inputs is tested against the
69  * entries in both sets, and if there are no matches, the output is
70  * set to x.
71  *
72  * The levels0 and levels1 tables are each an array of levels
73  * tables. Each levels table is a mask of positions that are supposed
74  * to be 0, 1 and x. The LSB of each mask represents first port, and
75  * so on. If the bit is set in mask0, a bit4_0 is expected at that
76  * position, and similarly for mask1 and maskx. Only exactly 1 bit
77  * will be set in the three masks for each bit position.
78  *
79  * This table structure implies that the number of inputs to the level
80  * sensitive device is limited to the number of bits in an unsigned
81  * long.
82  *
83  * The array of strings passed to the compile_table method of a
84  * combinational UDP are strings of port_count()+1 characters. The
85  * expected inputs are in the order of the UDP inputs, and the output
86  * is the last character. For example, an AND gate has these strings
87  * passed to the compile_table function:
88  *
89  *    000   (Both inputs are 0)
90  *    010   (Second input is a 1)
91  *    100
92  *    111   (All inputs are 1, so generate a 1 output)
93  *
94  * The characters allowed in the input positions are:
95  *
96  *   0  -- Expect a 0
97  *   1  -- Expect a 1
98  *   x  -- Expect an x or z
99  *   b  -- 0 or 1
100  *   l  -- 0 or x
101  *   h  -- x or 1
102  *   ?  -- 0, x or 1
103  *
104  * Only 0, 1 and x characters are allowed in the output position.
105  */
106 
107 struct udp_levels_table {
108       unsigned long mask0;
109       unsigned long mask1;
110       unsigned long maskx;
111 };
112 extern ostream& operator<< (ostream&o, const struct udp_levels_table&t);
113 
114 class vvp_udp_comb_s : public vvp_udp_s {
115 
116     public:
117       vvp_udp_comb_s(char*label, char*name__, unsigned ports);
118       ~vvp_udp_comb_s();
119       void compile_table(char**tab);
120 
121 	// Test the cur table with the compiled rows, and return the
122 	// bit value that matches.
123       vvp_bit4_t test_levels(const udp_levels_table&cur);
124 
125       vvp_bit4_t calculate_output(const udp_levels_table&cur,
126 				  const udp_levels_table&prev,
127 				  vvp_bit4_t cur_out);
128 
129     private:
130 	// Level sensitive rows of the device.
131       struct udp_levels_table*levels0_;
132       struct udp_levels_table*levels1_;
133       unsigned nlevels0_, nlevels1_;
134 };
135 
136 /*
137  * udp sequential devices are a little more complex in that they have
138  * an additional output type: no-change. They also have, in addition
139  * to a table of levels, a table of edges that are similar to levels
140  * but one of the positions has an edge value.
141  *
142  * The port_count() for the device is the number of inputs. Sequential
143  * devices have an additional phantom port that is the current output
144  * value. This implies that the maximum port count for sequential
145  * devices is 1 less than for combinational.
146  *
147  * The input table that is passed to the compile_table method is very
148  * similar to that for the combinational UDP. The differences are that
149  * there is one extra entry in the beginning of each input row that is
150  * the current output, and there are more characters accepted at each
151  * bit position.
152  *
153  * The current output bit may contain the same characters as a
154  * combinational UDP input position. No edges.
155  *
156  * The next output position takes the possible values 0, x, 1 and -.
157  *
158  * The input bit positions take the combinational input characters,
159  * plus edge specification characters. Only one input of a row may
160  * have an edge input.
161  *
162  * The edges_table is similar to the levels, table, with the mask?
163  * bits having the same meaning as with the levels tables. The edge_*
164  * members specify the edge for a single bit position. In this case,
165  * the edge_mask* members give the mask of source bits for that
166  * position, and the edge_position the bit that has shifted. In the
167  * edge case, the mask* members give the final position and the
168  * edge_mask* bits the initial position of the bit.
169  */
170 struct udp_edges_table {
171       unsigned long edge_position : 8;
172       unsigned long edge_mask0 : 1;
173       unsigned long edge_mask1 : 1;
174       unsigned long edge_maskx : 1;
175       unsigned long mask0;
176       unsigned long mask1;
177       unsigned long maskx;
178 };
179 
180 class vvp_udp_seq_s : public vvp_udp_s {
181 
182     public:
183       vvp_udp_seq_s(char*label, char*name__, unsigned ports, vvp_bit4_t init);
184       ~vvp_udp_seq_s();
185 
186       void compile_table(char**tab);
187 
188       vvp_bit4_t calculate_output(const udp_levels_table&cur,
189 				  const udp_levels_table&prev,
190 				  vvp_bit4_t cur_out);
191 
192     private:
193       vvp_bit4_t test_levels_(const udp_levels_table&cur);
194 
195 	// Level sensitive rows of the device.
196       struct udp_levels_table*levels0_;
197       struct udp_levels_table*levels1_;
198       struct udp_levels_table*levelsx_;
199       struct udp_levels_table*levelsL_;
200       unsigned nlevels0_, nlevels1_, nlevelsx_, nlevelsL_;
201 
202       vvp_bit4_t test_edges_(const udp_levels_table&cur,
203 			     const udp_levels_table&prev);
204 
205 	// Edge sensitive rows of the device
206       struct udp_edges_table*edges0_;
207       struct udp_edges_table*edges1_;
208       struct udp_edges_table*edgesL_;
209       unsigned nedges0_, nedges1_, nedgesL_;
210 
211 };
212 
213 /*
214  * This looks up a UDP definition from its LABEL.
215  */
216 struct vvp_udp_s *udp_find(const char *label);
217 
218 /*
219  * The udp_fun_core is the core of the udp instance in the
220  * netlist. This core is a vvp_wide_fun_core that takes care of
221  * dispatching the output. This class also receives the inputs from
222  * the vvp_wide_fun_t objects and processes them to generate the
223  * output to be sent.
224  */
225 class vvp_udp_fun_core  : public vvp_wide_fun_core, private vvp_gen_event_s {
226 
227     public:
228       vvp_udp_fun_core(vvp_net_t*net, vvp_udp_s*def);
229       ~vvp_udp_fun_core();
230 
231       void recv_vec4_from_inputs(unsigned);
232 
233     private:
234       void run_run();
235 
236       vvp_udp_s*def_;
237       vvp_bit4_t cur_out_;
238       udp_levels_table current_;
239 };
240 
241 #endif /* IVL_udp_H */
242