Subversion Repositories Vertical

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/* $Id: equivalent.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $ */
2
/*
3
 * $Log: equivalent.c,v $
4
 * Revision 1.1.1.1  2003/11/04 23:34:57  mjames
5
 * Imported into local repositrory
6
 *
7
 * Revision 1.9  2003/01/02 21:37:15  mjames
8
 * Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L
9
 * properties on the nets so that pin jumpers can be made without a problem.
10
 *
11
 * Still need to sort out pin assignments made to these not_routable nets
12
 * which will become legal in some cases so that pullups and pulldown
13
 * pins can be used on the FPGA.
14
 *
15
 * Revision 1.8  2002/09/09 10:26:56  mjames
16
 * Removed set generic range and replaced it with a set generic value command
17
 * that takes both integers and ranges.
18
 *
19
 * Revision 1.7  2002/01/15 12:36:22  mjames
20
 * DLL declarations put in,
21
 *
22
 * #ident used
23
 *
24
 * Revision 1.6  2001/11/01 11:06:49  mjames
25
 * Simplified code for connection of equivalent node sets to components
26
 *
27
 * Revision 1.5  2001/10/31 22:20:03  mjames
28
 * Tidying up problematical comments caused by CVS
29
 * 'intelligent' comment guessing
30
 *
31
 */
32
 
33
/* This file handles equivalent pins , being passthroughs or
34
   low value resistors which can be regarded as passthrough jumpers */
35
 
36
/* Extracted from ACFREAD syntax : pin equivalences within a chip or template
37
   declaration
38
 
39
 
40
pin_equivalence : EQUIVALENT LBRK { curr_equiv_list = begin_equivalent_pins(); }
41
                    equivalent_pins
42
                  RBRK end_item { check_equivalent_pins(current_chip,curr_equiv_list); }
43
                  ;
44
 
45
 
46
equivalent_pins : equivalent_pin SEMI equivalent_pins
47
                | equivalent_pin
48
                |
49
                ;
50
 
51
 
52
equivalent_pin : astring { add_equivalent_pin( current_chip,curr_equiv_list,$1); };
53
 
54
  in2 : input_pin = a1;
55
  in3 : input_pin = f1;
56
 
57
e.g. EQUIVALENT ( a1;f1);
58
 
59
*/
60
 
61
/* we approach the storage of nodes with caution , deferring the
62
   adding of information until it is correct */
63
 
64
#include "equivalent.h"
65
 
66
#include "cmdlog.h"
67
#include "cmdparse.h"
68
#include "database.h"
69
#include "expression.h"
70
#include "generic.h"
71
#include "jumpering.h"
72
#include "printout.h"
73
#include "vertcl_main.h"
74
 
75
#include <ctype.h>
76
#include <stdio.h>
77
#include <stdlib.h>
78
#include <string.h>
79
 
80
#ident                                                                                        \
81
    "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/equivalent.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
82
 
83
/********************************************************************/
84
/* this function starts to create a list of equivalent pins */
85
/********************************************************************/
86
equivalent_node_set_t *begin_equivalent_pins (void)
87
{
88
        equivalent_node_set_t *node_set;
89
        node_set = calloc (1, sizeof (equivalent_node_set_t));
90
        return node_set;
91
}
92
 
93
/********************************************************************/
94
/* add a pin to the list referred to by node_set */
95
/********************************************************************/
96
void add_equivalent_pin (socket_t *current_chip, equivalent_node_set_t *node_set, char *ident)
97
{
98
        equivalent_node_t *ptr;
99
        equivalent_node_t *equiv_node;
100
        node_t *node;
101
        if (!current_chip)
102
        {
103
                Log (LOG_ERROR, "-- Current chip not known for equivalent pin creation\n");
104
                return;
105
        }
106
 
107
        node = find_node (current_chip, Ident, ident, Create);
108
        /* no pin called 'ident ?? */
109
        if ((level & 1) && !node)
110
        {
111
                Log (
112
                    LOG_ERROR,
113
                    "-- Error : Pin Equivalent : cannot find pin %s(%s)\n",
114
                    current_chip->name,
115
                    ident);
116
                return;
117
        }
118
 
119
        /* pin already equivalent to another ? */
120
        if ((level & 1) && node->equivalent_nodes)
121
        {
122
                Log (
123
                    LOG_ERROR,
124
                    "-- Error : Pin Equivalent : pin %s(%s) already member of set\n",
125
                    current_chip->name,
126
                    ident);
127
                return;
128
        }
129
 
130
        /* pin is acceptable so note it */
131
        equiv_node = calloc (1, sizeof (equivalent_node_t));
132
        if (!node_set->nodes)
133
        {
134
                /* new node */
135
                node_set->nodes = equiv_node;
136
        }
137
        else
138
        {
139
                ptr = node_set->nodes;
140
                while (ptr->next)
141
                        ptr = ptr->next;
142
                ptr->next = equiv_node;
143
        }
144
        equiv_node->node = node;
145
}
146
 
147
/********************************************************************/
148
/* this function will verify the current list of nodes that are equivalent, and if there is
149
   more than one in the list then it will add them to the equivalent node list of the
150
   chip (if only one pin is equivalent to itself then it is a waste of time .... )   */
151
/********************************************************************/
152
void check_equivalent_pins (socket_t *current_chip, equivalent_node_set_t *node_set)
153
{
154
        equivalent_node_t *curr_node, *prev;
155
 
156
        int equiv_count;
157
 
158
        if (!node_set)
159
                return;
160
 
161
        /* count equivalent nodes */
162
        curr_node = node_set->nodes;
163
        equiv_count = 0;
164
        while (curr_node)
165
        {
166
                equiv_count++;
167
                curr_node = curr_node->next;
168
        };
169
 
170
        /* delete info if not sufficent equivalent nodes */
171
        if (equiv_count < 2)
172
        {
173
                curr_node = node_set->nodes;
174
                while (curr_node)
175
                {
176
                        prev = curr_node;
177
                        curr_node = curr_node->next;
178
                        free (prev);
179
                };
180
                free (node_set);
181
                Log (LOG_ERROR, "-- Warning : insufficient equivalent pins in list\n");
182
                return;
183
        }
184
 
185
        /* join the list to the socket as it is now validated */
186
        curr_node = node_set->nodes;
187
        while (curr_node)
188
        {
189
                /* flag each node as being a member of an equivalent set */
190
                curr_node->node->equivalent_nodes = node_set;
191
                curr_node = curr_node->next;
192
        }
193
 
194
        /* add an additional equivalent node set */
195
        node_set->next = current_chip->equivalent_node_set;
196
        current_chip->equivalent_node_set = node_set;
197
 
198
        return;
199
}
200
 
201
/********************************************************************/
202
 
203
void list_equivalent_pins (FILE *f, socket_t *dev)
204
{
205
        int itemcnt;
206
        equivalent_node_t *curr_node;
207
        equivalent_node_set_t *curr_set;
208
 
209
        curr_set = dev->equivalent_node_set;
210
 
211
        while (curr_set)
212
        {
213
                if (curr_set->nodes)
214
                {
215
                        curr_node = curr_set->nodes;
216
                        fprintf (f, "  EQUIVALENT ( ");
217
                        itemcnt = 2;
218
                        while (curr_node)
219
                        {
220
                                if (curr_node->next)
221
                                {
222
                                        fprintf (f, "%s; ", curr_node->node->identifier);
223
                                        itemcnt++;
224
                                        if (itemcnt > 6)
225
                                        {
226
                                                fprintf (f, "\n     ");
227
                                                itemcnt = 0;
228
                                        }
229
                                }
230
                                else
231
                                        fprintf (f, "%s);\n", curr_node->node->identifier);
232
                                curr_node = curr_node->next;
233
                        }
234
                }
235
                curr_set = curr_set->next;
236
        }
237
}
238
 
239
/********************************************************************
240
 * copies the equivalent pins list from template to device instance *
241
 * uses the functions above to ensure validation is consistently    *
242
 * performed
243
 ********************************************************************/
244
void copy_equivalent_pins (socket_t *template, socket_t *dev)
245
{
246
        equivalent_node_t *curr_node;
247
        equivalent_node_set_t *curr_set, *new_set;
248
 
249
        /* trap use of template when none is actually given */
250
        if (!template || !dev)
251
                return;
252
        if (level & 1)
253
        {
254
                Log (
255
                    LOG_GENERAL,
256
                    "copying equivalent pins from template %s to socket %s\n",
257
                    template->type,
258
                    dev->identifier);
259
        }
260
        curr_set = template->equivalent_node_set;
261
 
262
        while (curr_set)
263
        {
264
                new_set = begin_equivalent_pins ();
265
                /* create a set of equivalent pins to copy into */
266
 
267
                curr_node = curr_set->nodes;
268
 
269
                while (curr_node)
270
                {
271
                        add_equivalent_pin (dev, new_set, curr_node->node->identifier);
272
                        /* traverse list */
273
                        curr_node = curr_node->next;
274
                }
275
 
276
                check_equivalent_pins (dev, new_set);
277
                curr_set = curr_set->next;
278
        }
279
}
280
 
281
/* function to jumper together all equivalent pins on a device :
282
  at the moment it does not distinguish between EPLD and non -epld devices */
283
/* the endpoint is a socket that may be used */
284
void jumper_equivalent_pins (void)
285
{
286
        char equiv_buff[MAXIDLEN];
287
        equivalent_node_t *curr_ref;
288
        equivalent_node_set_t *node_set;
289
 
290
        socket_t *dev;
291
 
292
        net_t *top_net, *current_net;
293
 
294
        dev = socket_head;
295
 
296
        while (dev)
297
        {
298
                /* any equivalent pins */
299
                if (dev->equivalent_node_set)
300
                {
301
#if defined DEBUG_EQUIV
302
                        Log (
303
                            LOG_GENERAL,
304
                            "-- Device %s has equivalent pins\n",
305
                            dev->identifier);
306
#endif
307
                        node_set = dev->equivalent_node_set;
308
                        while (node_set)
309
                        {
310
                                /* create a top level jumper name made out device ID
311
                                 concatenated with current pin IDs */
312
                                sprintf (equiv_buff, "E_%s", dev->identifier);
313
                                curr_ref = node_set->nodes;
314
                                while (curr_ref)
315
                                {
316
                                        current_net = curr_ref->node->net;
317
                                        /* if there is a net attached to the pin it is a routed
318
                                           net.
319
                                           only make the jumper if it is actually a usable net
320
                                           for routing. */
321
                                        if (current_net &&
322
                                            IS_ROUTABLE (current_net->how_routed))
323
                                        {
324
                                                strcat (equiv_buff, "_");
325
                                                strcat (
326
                                                    equiv_buff, curr_ref->node->identifier);
327
                                        }
328
                                        curr_ref = curr_ref->next;
329
                                }
330
 
331
                                /*      printf("Making %s\n",equiv_buff); */
332
                                top_net = find_net (&routed_list, Ident, equiv_buff, Create);
333
                                top_net->how_joined = Jumpered;
334
#if defined DEBUG_EQUIV
335
                                Log (LOG_GENERAL, "--  making jumper %s\n", equiv_buff);
336
#endif
337
                                curr_ref = node_set->nodes;
338
                                while (curr_ref)
339
                                {
340
                                        current_net = curr_ref->node->net;
341
                                        /* if there is a net attached to the pin it is a routed
342
                                           net.
343
                                           only make the jumper if it is actually a usable net
344
                                           for routing. */
345
                                        if (current_net &&
346
                                            IS_ROUTABLE (current_net->how_routed))
347
                                        {
348
#if defined DEBUG_EQUIV
349
                                                Log (
350
                                                    LOG_GENERAL,
351
                                                    "--   connecting net %s ( pin %s(%s))\n",
352
                                                    curr_ref->node->net->identifier,
353
                                                    dev->identifier,
354
                                                    curr_ref->node->identifier);
355
#endif
356
                                                current_net->external_node =
357
                                                    NULL; /* jumpered by net name */
358
                                                transfer_net_to_subnet (
359
                                                    &routed_list, top_net, current_net);
360
                                        }
361
 
362
                                        curr_ref = curr_ref->next;
363
                                }
364
                                /* no child nets or jumper joins only one subnet : delete
365
                                 * jumper */
366
                                if (!top_net->subnets || !top_net->subnets->joined_nets)
367
                                        disconnect_jumper (&routed_list, top_net);
368
 
369
                                node_set = node_set->next;
370
                        }
371
                }
372
 
373
                dev = dev->next;
374
        }
375
}