Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / pavo / Cone_Netlist_Simulator.c
1 #include <stdlib.h>
2 #include <math.h>
3
4 #include AVT_H
5 #include MUT_H
6 #include CNS_H
7 /*#include STM_H
8 #include TTV_H
9 #include TAS_H*/
10 #include SDLR_H
11 #include "pavo_lib.h"
12
13 #define PAVO_CONE_INDEX 0xf0270705
14
15 static int DEBUG=1;
16
17 int randmode=0;
18
19 typedef struct
20 {
21 long ModificationDate;
22 float CurrentVoltage;
23 cone_list *CONE;
24 } ConeInformations;
25
26 typedef struct pavo_cone_simulator_info
27 {
28 ht *ExternalCones;
29 cnsfig_list *cf;
30 } pavo_ConeSimulatorInfo;
31
32 pavo_ConeSimulatorInfo CSI;
33
34 int pavo_get_cone_index(cone_list *cl)
35 {
36 ptype_list *pt;
37 if ((pt=getptype(cl->USER, PAVO_CONE_INDEX))!=NULL) return (int)(long)pt->DATA;
38 exit(6); // err msg
39 }
40
41 int pavo_get_input_cone(char *name)
42 {
43 long l;
44 if ((l=gethtitem(CSI.ExternalCones, namealloc(name)))==EMPTYHT) {exit(10); return -1;} // msg
45 return l;
46 }
47
48 int pavo_UpdateFunction(Scheduler *S, int index, void *data)
49 {
50 float newval=*(float *)data;
51 ConeInformations *ci;
52
53 ci=(ConeInformations *)Scheduler_GetRegisterObject(S, index);
54
55 if (DEBUG) avt_fprintf(stdout,"date ¤+%ld¤. : update '%s' %g -> %g\n", S->Date, ci->CONE->NAME, ci->CurrentVoltage, newval);
56
57 if (fabs(ci->CurrentVoltage-newval)>1e-3)
58 {
59 ci->CurrentVoltage=newval;
60 ci->ModificationDate=S->Date;
61 return 1; // event detected
62 }
63 // value is the same, no event detected
64 return 0;
65 }
66
67 void pavo_GetConeDelay_and_Voltage(Scheduler *S, cone_list *cl, long *delay, float *value)
68 {
69 ConeInformations *ci;
70 edge_list *el;
71
72 // positionning voltage on the cone inputs
73 for (el=cl->INCONE; el!=NULL; el=el->NEXT)
74 {
75 if ((el->TYPE & CNS_EXT)!=CNS_EXT)
76 {
77 ci=(ConeInformations *)Scheduler_GetRegisterObject(S, pavo_get_cone_index(el->UEDGE.CONE));
78 pavo_SetSignalVoltage(pavo_GetLosigByCone(CSI.cf, el->UEDGE.CONE), ci->CurrentVoltage);
79 }
80 }
81
82 // calling appropriate function
83 *value=pavo_CalcInternalNodeVoltage(cl);
84 *delay=1+(rand() % 10);
85
86 #if 0
87 // --- fake value and timing-- a remplacer par la fonction adequate
88 {
89 // evaluation de la sortie
90 int ra=rand() % 6;
91
92
93 if (ra==0 || ra==4) *value=0;
94 else if (ra==1 || ra==5) *value=1.6;
95 else if (ra==2) *value=PAVO_HZ_VOLTAGE;
96 else *value=PAVO_UNKNOWN_VOLTAGE;
97
98
99 // recuperation du temps de propagation
100 }
101 // ---------------------------
102 #endif
103 // cleaning
104 for (el=cl->INCONE; el!=NULL; el=el->NEXT)
105 {
106 if ((el->TYPE & CNS_EXT)!=CNS_EXT)
107 {
108 ci=(ConeInformations *)Scheduler_GetRegisterObject(S, pavo_get_cone_index(el->UEDGE.CONE));
109 pavo_RemoveSignalVoltage(pavo_GetLosigByCone(CSI.cf, el->UEDGE.CONE));
110 }
111 }
112 }
113
114
115 void pavo_ExecuteFunction(Scheduler *S, int index)
116 {
117 int output;
118 long timing;
119 float newval;
120 ConeInformations *ci;
121 edge_list *el;
122
123 ci=(ConeInformations *)Scheduler_GetRegisterObject(S, index);
124
125 for (el=ci->CONE->OUTCONE; el!=NULL; el=el->NEXT)
126 {
127 if ((el->TYPE & CNS_EXT)!=CNS_EXT)
128 {
129 output=pavo_get_cone_index(el->UEDGE.CONE);
130
131 pavo_GetConeDelay_and_Voltage(S, el->UEDGE.CONE, &timing, &newval);
132
133 if (DEBUG) printf("exec '%s'=f('%s') after %ld => %g\n",el->UEDGE.CONE->NAME, ci->CONE->NAME, timing, newval);
134 if (newval!=PAVO_HZ_VOLTAGE) Scheduler_AddTransaction(S, output, timing, &newval);
135 }
136 }
137 }
138
139 long nextpatterndate=0;
140 int endofpattern=0;
141
142 void pavo_RandomPatterns(Scheduler *S, long lastdate, long nextdate)
143 {
144 if (endofpattern==0 && nextpatterndate>=lastdate && nextpatterndate<=nextdate)
145 {
146 long delta=nextpatterndate-lastdate;
147 float newval;
148 int var, inewval;
149 char name[10];
150
151 if (DEBUG) avt_fprintf(stdout, "¤2reading patterns at %ld¤.\n",nextpatterndate);
152 else avt_fprintf(stdout, "\r¤2reading patterns at %ld¤.",nextpatterndate);
153 switch (nextpatterndate)
154 {
155 case 0:
156 newval=1.6; Scheduler_AddTransaction(S, pavo_get_input_cone("a"), delta, &newval);
157 nextpatterndate=1000;
158 break;
159 case 1000:
160 newval=0; Scheduler_AddTransaction(S, pavo_get_input_cone("b"), delta, &newval);
161 nextpatterndate=1500;
162 break;
163 case 1500:
164 newval=1.6; Scheduler_AddTransaction(S, pavo_get_input_cone("d"), delta, &newval);
165 nextpatterndate=3000;
166 break;
167 case 3000:
168 newval=0; Scheduler_AddTransaction(S, pavo_get_input_cone("c"), delta, &newval);
169 nextpatterndate=3200;
170 break;
171 case 3200:
172 newval=1.6; Scheduler_AddTransaction(S, pavo_get_input_cone("a"), delta, &newval);
173 newval=1.6; Scheduler_AddTransaction(S, pavo_get_input_cone("b"), delta, &newval);
174 newval=1.6; Scheduler_AddTransaction(S, pavo_get_input_cone("c"), delta, &newval);
175 newval=0; Scheduler_AddTransaction(S, pavo_get_input_cone("d"), delta, &newval);
176 nextpatterndate=5000;
177 break;
178 case 5000:
179 newval=0; Scheduler_AddTransaction(S, pavo_get_input_cone("a"), delta, &newval);
180 newval=0; Scheduler_AddTransaction(S, pavo_get_input_cone("b"), delta, &newval);
181 newval=1.6; Scheduler_AddTransaction(S, pavo_get_input_cone("c"), delta, &newval);
182 newval=1.6; Scheduler_AddTransaction(S, pavo_get_input_cone("d"), delta, &newval);
183 nextpatterndate=6000;
184 default:
185 // random
186 randmode=1;
187 var=rand() % 4;
188 sprintf(name,"%c",'a'+var);
189 if (rand() % 3==0) inewval=rand() % 4;
190 else inewval=rand() % 2;
191 if (inewval==1) newval=1.6;
192 else if (inewval==2) newval=PAVO_UNKNOWN_VOLTAGE;
193 else newval=0;
194 Scheduler_AddTransaction(S, pavo_get_input_cone(name), delta, &newval);
195 nextpatterndate+=1+(rand() % 10);
196
197 // endofpattern=1;
198 break;
199 }
200 }
201 }
202
203 void pavo_register_cones(cnsfig_list *cf, Scheduler *S, pavo_ConeSimulatorInfo *CSI)
204 {
205 cone_list *cl;
206 int number=0;
207 ConeInformations *ci;
208
209 CSI->ExternalCones=addht(100);
210
211 for (cl=cf->CONE; cl!=NULL; cl=cl->NEXT)
212 {
213 cl->USER=addptype(cl->USER, PAVO_CONE_INDEX, (void *)(long)number);
214 ci=(ConeInformations *)mbkalloc(sizeof(ConeInformations));
215 ci->CONE=cl;
216 Scheduler_RegisterObject(S, number, ci);
217 if (cl->TYPE & CNS_EXT)
218 {
219 addhtitem(CSI->ExternalCones, cl->NAME, number);
220 }
221 number++;
222 }
223 }
224
225 void pavo_initialize_cone(cnsfig_list *cf, Scheduler *S)
226 {
227 cone_list *cl;
228 int index;
229 ConeInformations *ci;
230
231 for (cl=cf->CONE; cl!=NULL; cl=cl->NEXT)
232 {
233 index=pavo_get_cone_index(cl);
234 ci=(ConeInformations *)Scheduler_GetRegisterObject(S, index);
235 ci->CurrentVoltage=PAVO_UNKNOWN_VOLTAGE;
236 ci->ModificationDate=0;
237 }
238 }
239
240 void pavo_uninitialize_cone(cnsfig_list *cf, Scheduler *S)
241 {
242 cone_list *cl;
243 int index;
244 ConeInformations *ci;
245
246 for (cl=cf->CONE; cl!=NULL; cl=cl->NEXT)
247 {
248 index=pavo_get_cone_index(cl);
249 ci=(ConeInformations *)Scheduler_GetRegisterObject(S, index);
250 mbkfree(ci);
251 }
252 }
253
254 void pavo_SimulateNetlist(cnsfig_list *cf, long UntilDate)
255 {
256 Scheduler *S;
257
258 S=Scheduler_CreateSimulator(sizeof(float), pavo_UpdateFunction, pavo_ExecuteFunction, pavo_RandomPatterns);
259
260 CSI.cf=cf;
261
262 pavo_register_cones(cf, S, &CSI);
263 pavo_initialize_cone(cf, S);
264
265 Scheduler_RunSimulator(S, UntilDate);
266
267 printf("%d transactions remaining\n",S->DS.TransactionCount);
268 printf("next date = %ld\n",Scheduler_GetNextDate(S));
269
270 pavo_uninitialize_cone(cf, S);
271 delht(CSI.ExternalCones);
272
273 Scheduler_DeleteSimulator(S);
274 }
275
276 void pavo_SimulateNetlist_test(char *name, long UntilDate)
277 {
278 cnsfig_list *cf;
279 if ((cf=getloadedcnsfig(name))!=NULL)
280 {
281 pavo_SimulateNetlist(cf, UntilDate);
282 }
283 else
284 {
285 printf("could not find cone netlist '%s', no simulation done.\n", name);
286 }
287 }
288
289 #if 0
290 int ymain(int ac, char *av[])
291 {
292 cnsfig_list *cf;
293 avtenv();
294 mbkenv();
295
296 srand(time(NULL));
297
298 // desassembler netlist
299
300 // lancer simulation
301 pavo_SimulateNetlist(cf, 4000);
302
303
304 return 0;
305 }
306 #endif