@@ -212,22 +212,224 @@ void CurrentCircuit::topological_sort() {
212212 }
213213 printf (" \n " );
214214
215+ // /// SENSITIZATION THINGS BELOW
216+
215217 // sensitize path
218+ // initialize crit path wires
216219 for (auto & name : crit_path_names) {
217220 auto & element = atpg_circuit.get_element (name);
218221 if (element.type == ATPGCircuitElementType::WIRE) {
219222 element.value = ATPGValue::CRIT_PATH;
220- } else {
221- // assume NAND for now..
222- for (auto & input : element.inputs ) {
223- if (std::find (crit_path_names.begin (), crit_path_names.end (), input) != crit_path_names.end ()) {
224- atpg_circuit.get_element (input).value = ATPGValue::CRIT_PATH;
223+ }
224+ }
225+
226+ // set offset to non-controlling values on crit path
227+ for (auto & name : crit_path_names) {
228+ auto & element = atpg_circuit.get_element (name);
229+ if (element.type == ATPGCircuitElementType::WIRE) {
230+ continue ;
231+ }
232+ // get input values
233+ std::vector<ATPGCircuitElement*> inputs;
234+ for (auto & input : element.inputs ) {
235+ auto & input_element = atpg_circuit.get_element (input);
236+ inputs.push_back (&input_element);
237+ }
238+
239+ if (inputs.size () != 2 ) {
240+ printf (" Only 2 input gates supported!\n " );
241+ break ;
242+ }
243+
244+ switch (element.type )
245+ {
246+ case ATPGCircuitElementType::NAND:
247+ case ATPGCircuitElementType::AND:
248+ if (inputs[0 ]->value == ATPGValue::CRIT_PATH) {
249+ if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
250+ inputs[1 ]->value = ATPGValue::ONE;
251+ } else if (inputs[1 ]->value != ATPGValue::ONE) {
252+ printf (" FAULT 248\n " );
253+ }
254+ } else if (inputs[1 ]->value == ATPGValue::CRIT_PATH) {
255+ if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
256+ inputs[0 ]->value = ATPGValue::ONE;
257+ } else if (inputs[0 ]->value != ATPGValue::ONE) {
258+ printf (" FAULT 255\n " );
259+ }
260+ }
261+ break ;
262+ case ATPGCircuitElementType::OR:
263+ case ATPGCircuitElementType::NOR:
264+ if (inputs[0 ]->value == ATPGValue::CRIT_PATH) {
265+ if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
266+ inputs[1 ]->value = ATPGValue::ZERO;
267+ } else if (inputs[1 ]->value != ATPGValue::ZERO) {
268+ printf (" FAULT 265\n " );
269+ }
270+ } else if (inputs[1 ]->value == ATPGValue::CRIT_PATH) {
271+ if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
272+ inputs[0 ]->value = ATPGValue::ZERO;
273+ } else if (inputs[0 ]->value != ATPGValue::ZERO) {
274+ printf (" FAULT 271\n " );
275+ }
276+ }
277+ break ;
278+ default :
279+ printf (" Not supported gate: %d\n " , element.type );
280+ break ;
281+ }
282+ }
283+
284+ // justify rest
285+ for (auto & element : atpg_circuit.elements ) {
286+ if (element.type == ATPGCircuitElementType::WIRE) {
287+ continue ;
288+ }
289+
290+ // get input values
291+ std::vector<ATPGCircuitElement*> inputs;
292+ bool has_not_initialized = false ;
293+ for (auto & input : element.inputs ) {
294+ auto & input_element = atpg_circuit.get_element (input);
295+ if (input_element.value == ATPGValue::NOT_INITIALIZED) {
296+ has_not_initialized = true ;
297+ }
298+ inputs.push_back (&input_element);
299+ }
300+ ATPGCircuitElement& output = atpg_circuit.get_element (element.outputs [0 ]);
301+ if (output.value == ATPGValue::NOT_INITIALIZED) {
302+ has_not_initialized = true ;
303+ }
304+
305+ // this gate is already done
306+ if (!has_not_initialized) {
307+ continue ;
308+ }
309+
310+ if (inputs.size () != 2 ) {
311+ printf (" Only 2 input gates supported!\n " );
312+ break ;
313+ }
314+
315+ if (output.value == ATPGValue::NOT_INITIALIZED) {
316+ switch (element.type )
317+ {
318+ case ATPGCircuitElementType::NAND:
319+ if (inputs[0 ]->value == ATPGValue::CRIT_PATH || inputs[1 ]->value == ATPGValue::CRIT_PATH) {
320+ if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
321+ inputs[0 ]->value = ATPGValue::ZERO;
322+ }
323+ if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
324+ inputs[1 ]->value = ATPGValue::ZERO;
325+ }
326+ output.value = ATPGValue::ONE;
327+ } else if (inputs[0 ]->value == ATPGValue::ZERO || inputs[1 ]->value == ATPGValue::ZERO) {
328+ if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
329+ inputs[0 ]->value = ATPGValue::DONT_CARE;
330+ }
331+ if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
332+ inputs[1 ]->value = ATPGValue::DONT_CARE;
333+ }
334+ output.value = ATPGValue::ONE;
335+ } else if (inputs[0 ]->value == ATPGValue::ONE && inputs[1 ]->value == ATPGValue::ONE) {
336+ output.value = ATPGValue::ZERO;
337+ } else {
338+ output.value = ATPGValue::DONT_CARE;
339+ }
340+ break ;
341+ case ATPGCircuitElementType::NOR:
342+ if (inputs[0 ]->value == ATPGValue::CRIT_PATH || inputs[1 ]->value == ATPGValue::CRIT_PATH) {
343+ if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
344+ inputs[0 ]->value = ATPGValue::ONE;
345+ }
346+ if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
347+ inputs[1 ]->value = ATPGValue::ONE;
348+ }
349+ output.value = ATPGValue::ZERO;
350+ } else if (inputs[0 ]->value == ATPGValue::ONE || inputs[1 ]->value == ATPGValue::ONE) {
351+ if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
352+ inputs[0 ]->value = ATPGValue::DONT_CARE;
353+ }
354+ if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
355+ inputs[1 ]->value = ATPGValue::DONT_CARE;
356+ }
357+ output.value = ATPGValue::ZERO;
358+ } else if (inputs[0 ]->value == ATPGValue::ZERO && inputs[1 ]->value == ATPGValue::ZERO) {
359+ output.value = ATPGValue::ONE;
225360 } else {
226- atpg_circuit. get_element (input). value = ATPGValue::ONE ;
361+ output. value = ATPGValue::DONT_CARE ;
227362 }
363+ break ;
364+ default :
365+ printf (" Not supported gate: %d\n " , element.type );
366+ break ;
367+ }
368+ } else if (output.value == ATPGValue::DONT_CARE) {
369+ // for(auto& value : input_values) {
370+ // if(value == ATPGValue::NOT_INITIALIZED) {
371+ // value = ATPGValue::DONT_CARE;
372+ // }
373+ // }
374+ } else if (output.value == ATPGValue::ONE) {
375+ switch (element.type )
376+ {
377+ case ATPGCircuitElementType::NAND:
378+ if (inputs[0 ]->value == ATPGValue::ZERO || inputs[1 ]->value == ATPGValue::ZERO) {
379+ if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
380+ inputs[0 ]->value = ATPGValue::DONT_CARE;
381+ }
382+ if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
383+ inputs[1 ]->value = ATPGValue::DONT_CARE;
384+ }
385+ } else if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED && inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
386+ inputs[0 ]->value = ATPGValue::ZERO;
387+ inputs[1 ]->value = ATPGValue::DONT_CARE;
388+ } else if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
389+ inputs[0 ]->value = ATPGValue::ZERO;
390+ } else if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
391+ inputs[1 ]->value = ATPGValue::ZERO;
392+ }
393+ break ;
394+ case ATPGCircuitElementType::NOR:
395+ inputs[0 ]->value = ATPGValue::ZERO;
396+ inputs[1 ]->value = ATPGValue::ZERO;
397+ break ;
398+ default :
399+ printf (" Not supported gate: %d\n " , element.type );
400+ break ;
401+ }
402+ } else if (output.value == ATPGValue::ZERO) {
403+ switch (element.type )
404+ {
405+ case ATPGCircuitElementType::NAND:
406+ inputs[0 ]->value = ATPGValue::ONE;
407+ inputs[1 ]->value = ATPGValue::ONE;
408+ break ;
409+ case ATPGCircuitElementType::NOR:
410+ if (inputs[0 ]->value == ATPGValue::ONE || inputs[1 ]->value == ATPGValue::ONE) {
411+ if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
412+ inputs[0 ]->value = ATPGValue::DONT_CARE;
413+ }
414+ if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
415+ inputs[1 ]->value = ATPGValue::DONT_CARE;
416+ }
417+ } else if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED && inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
418+ inputs[0 ]->value = ATPGValue::ONE;
419+ inputs[1 ]->value = ATPGValue::DONT_CARE;
420+ } else if (inputs[0 ]->value == ATPGValue::NOT_INITIALIZED) {
421+ inputs[0 ]->value = ATPGValue::ONE;
422+ } else if (inputs[1 ]->value == ATPGValue::NOT_INITIALIZED) {
423+ inputs[1 ]->value = ATPGValue::ONE;
424+ }
425+ break ;
426+ default :
427+ printf (" Not supported gate: %d\n " , element.type );
428+ break ;
228429 }
229430 }
230431 }
432+
231433 printf (" ************************\n " );
232434 for (auto & element : atpg_circuit.elements ) {
233435 printf (" %s[%d]\n " , element.name .c_str (), element.value );
0 commit comments