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