1 /*
2 * *********************************************************************
3 * * Copyright (C) 1988, 1990 Stanford University. *
4 * * Permission to use, copy, modify, and distribute this *
5 * * software and its documentation for any purpose and without *
6 * * fee is hereby granted, provided that the above copyright *
7 * * notice appear in all copies. Stanford University *
8 * * makes no representations about the suitability of this *
9 * * software for any purpose. It is provided "as is" without *
10 * * express or implied warranty. Export of this software outside *
11 * * of the United States of America may require an export license. *
12 * *********************************************************************
13 */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17
18 /* generate lookup tables for switch level simulation */
19
20 /* number of states desired for logic level */
21 #define NVALUES 4
22
23 /* total number of logic states we need */
24 #define NSPECTRUM (2 * NVALUES + 1)
25
26 /* (NSPECTRUM choose 2) + NSPECTRUM */
27 #define NINTERVAL ((NSPECTRUM *(NSPECTRUM - 1)) / 2 + NSPECTRUM)
28
29 char *names[NSPECTRUM] =
30 {
31 "DH", "WH", "CH", "cH", "Z", "cL", "CL", "WL", "DL"
32 };
33
34 FILE *out;
35
36
37 /* name of interval */
pinterval(high,low)38 char *pinterval( high, low )
39 {
40 static char temp[100];
41
42 if( high != low )
43 sprintf( temp, "%s%s", names[high], names[low] );
44 else
45 sprintf( temp, "%s", names[high] );
46 return( temp );
47 }
48
49
50 /* return strength of value */
strength(i)51 int strength( i )
52 register int i;
53 {
54 if( (i -= NVALUES) < 0 )
55 i = -i;
56 return( i );
57 }
58
59 #define min( A, B ) ( ((A) < (B)) ? (A) : (B) )
60 #define max( A, B ) ( ((A) > (B)) ? (A) : (B) )
61
62 /* find the enclosing interval */
span(ihigh,ilow,jhigh,jlow)63 char *span( ihigh, ilow, jhigh, jlow )
64 {
65 return( pinterval( min( ihigh, jhigh ), max( ilow, jlow ) ) );
66 }
67
68
69 /* merge two intervals using least-upper bound operation */
merge(ihigh,ilow,jhigh,jlow)70 char *merge( ihigh, ilow, jhigh, jlow )
71 {
72 register int ahigh, alow;
73
74 if( strength( ihigh ) > strength( jhigh ) )
75 ahigh = ihigh;
76 else if( strength( ihigh ) < strength( jhigh ) )
77 ahigh = jhigh;
78 else if( ihigh < jhigh )
79 ahigh = ihigh;
80 else
81 ahigh = jhigh;
82
83 if( strength( ilow ) > strength( jlow ) )
84 alow = ilow;
85 else if( strength( ilow ) < strength( jlow ) )
86 alow = jlow;
87 else if( ilow > jlow )
88 alow = ilow;
89 else
90 alow = jlow;
91
92 return( pinterval( ahigh, alow ) );
93 }
94
95
96 /* convert interval to use weak values */
weak(i,j)97 char *weak( i, j )
98 {
99 if( i == 0 )
100 i = 1;
101 else if( i == (NSPECTRUM - 1) )
102 i = NSPECTRUM - 2;
103 if( j == 0 )
104 j = 1;
105 else if( j == (NSPECTRUM - 1) )
106 j = NSPECTRUM - 2;
107 return( pinterval( i, j ) );
108 }
109
110
main()111 main()
112 {
113 register int i, j, k, ii, jj, interval2;
114
115 if( (out = fopen( "stables.c", "w" )) == NULL )
116 {
117 fprintf( stderr, "cannot open stables.c for output\n" );
118 exit( 1 );
119 }
120
121 fprintf( out, "/* DO NOT EDIT: THIS FILE IS GENERATED USING gentbl */\n");
122 fprintf( out, "/* names for each value interval */\n" );
123 fprintf( out, "char *node_values[%d] = {\n", NINTERVAL+1 );
124 fprintf( out, "\t\"EMPTY\",\n" );
125 for( i = 0; i < NSPECTRUM; i += 1 )
126 for( j = i; j < NSPECTRUM; j += 1 )
127 fprintf( out, "\t\"%s\",\n", pinterval( i, j ) );
128 fprintf( out, "};\n\n" );
129
130 fprintf( out, "/* index for each value interval */\n" );
131 fprintf( out, "#define EMPTY\t%d\n\n", 0 );
132 for( i = 0, k = 1; i < NSPECTRUM; i += 1 )
133 for( j = i; j < NSPECTRUM; j += 1, k += 1 )
134 fprintf( out, "#define %s\t%d\n", pinterval( i, j ), k );
135 fprintf( out, "\n" );
136
137 fprintf( out, "/* conversion between interval and logic value */\n" );
138 fprintf( out, "char logic_state[%d] = {\n", NINTERVAL+1 );
139 fprintf( out, " 0,\t/* EMPTY */\n" );
140 for( i = 0; i < NSPECTRUM; i += 1 )
141 for( j = i; j < NSPECTRUM; j += 1 )
142 if( i < NVALUES && j < NVALUES )
143 fprintf( out, " HIGH,\t/* %s */\n", pinterval( i, j ) );
144 else if( i > NVALUES && j > NVALUES )
145 fprintf( out, " LOW,\t/* %s */\n", pinterval( i, j ) );
146 else
147 fprintf( out, " X,\t/* %s */\n", pinterval( i, j ) );
148 fprintf( out, "};\n\n" );
149
150 fprintf( out, "/* transmit interval through switch */\n" );
151 fprintf( out, "char transmit[%d][4] = {\n", NINTERVAL+1 );
152 fprintf( out, " 0,\t0,\t0,\t0,\t/* EMPTY */\n" );
153 for( i = 0; i < NSPECTRUM; i += 1 )
154 for( j = i; j < NSPECTRUM; j += 1 )
155 {
156 fprintf( out, " Z," ); /* off switch */
157 fprintf( out, "\t%s,", pinterval( i, j ) ); /* on switch */
158 fprintf( out, "\t%s,", span( i, j, NVALUES, NVALUES ) );
159 /* unknown switch */
160 fprintf( out, "\t%s,", weak( i, j ) ); /* weak switch */
161 fprintf( out, "\t/* %s */\n", pinterval( i, j ) );
162 }
163 fprintf( out, "};\n\n" );
164
165 /* compute smallest power of two greater than NINTERVAL */
166 for( interval2 = 1; interval2 < NINTERVAL; interval2 <<= 1 );
167
168 fprintf( out, "/* result of shorting two intervals */\n" );
169 fprintf( out, "char smerge[%d][%d] = {\n", NINTERVAL+1, NINTERVAL+1 );
170 fprintf( out, "\n/* EMPTY */\n" );
171 for( i = 0; i <= NINTERVAL; i +=1 )
172 {
173 fprintf( out, " 0 ," ); /* EMPTY */
174 if( i % 8 == 7 )
175 fprintf( out, "\n" );
176 }
177
178 for( i = 0; i < NSPECTRUM; i += 1 )
179 for( j = i; j < NSPECTRUM; j += 1 )
180 {
181 fprintf( out, "\n/* %s */\n", pinterval( i, j ) );
182 fprintf( out, " 0 ," );
183 for( ii = 0, k = 1; ii < NSPECTRUM; ii += 1 )
184 for( jj = ii; jj < NSPECTRUM; jj += 1, k += 1 )
185 {
186 fprintf( out, " %-4s,", merge( i, j, ii, jj ) );
187 if( k % 8 == 7 )
188 fprintf( out, "\n" );
189 }
190 }
191 fprintf( out, "\n};\n" );
192 exit(0);
193 }
194