@@ -372,3 +372,155 @@ void Greenpak4BitstreamEntity::SaveTimingData(FILE* fp, PTVCorner corner)
372
372
fprintf (fp, " },\n " );
373
373
}
374
374
}
375
+
376
+ /* *
377
+ @brief Load our delay info
378
+ */
379
+ bool Greenpak4BitstreamEntity::LoadTimingData (json_object* object)
380
+ {
381
+ for (int i=0 ; i<json_object_array_length (object); i++)
382
+ {
383
+ auto child = json_object_array_get_idx (object, i);
384
+ if (!LoadTimingDataForCorner (child))
385
+ return false ;
386
+ }
387
+
388
+ return true ;
389
+ }
390
+
391
+ /* *
392
+ @brief Loads delay info for a single process-corner object in the JSON file
393
+ */
394
+ bool Greenpak4BitstreamEntity::LoadTimingDataForCorner (json_object* object)
395
+ {
396
+ // Look up the corner info
397
+ json_object* process;
398
+ if (!json_object_object_get_ex (object, " process" , &process))
399
+ {
400
+ LogError (" No process info for this corner\n " );
401
+ return false ;
402
+ }
403
+ string sprocess = json_object_get_string (process);
404
+
405
+ json_object* temp;
406
+ if (!json_object_object_get_ex (object, " temp" , &temp))
407
+ {
408
+ LogError (" No temp info for this corner\n " );
409
+ return false ;
410
+ }
411
+ int ntemp = json_object_get_int (temp);
412
+
413
+ json_object* voltage;
414
+ if (!json_object_object_get_ex (object, " voltage_mv" , &voltage))
415
+ {
416
+ LogError (" No voltage info for this corner\n " );
417
+ return false ;
418
+ }
419
+ int nvoltage = json_object_get_int (voltage);
420
+
421
+ // TODO: move this into PTVCorner class?
422
+ PTVCorner::ProcessSpeed speed;
423
+ if (sprocess == " fast" )
424
+ speed = PTVCorner::SPEED_FAST;
425
+ else if (sprocess == " slow" )
426
+ speed = PTVCorner::SPEED_SLOW;
427
+ else if (sprocess == " typical" )
428
+ speed = PTVCorner::SPEED_TYPICAL;
429
+
430
+ // This is the process corner we're loading
431
+ PTVCorner corner (speed, ntemp, nvoltage);
432
+
433
+ // This is the actual timing data!
434
+ json_object* delays;
435
+ if (!json_object_object_get_ex (object, " delays" , &delays))
436
+ {
437
+ LogError (" No delay info for this corner\n " );
438
+ return false ;
439
+ }
440
+
441
+ // Now that we know where to put it, we can load the actual timing data
442
+ for (int i=0 ; i<json_object_array_length (delays); i++)
443
+ {
444
+ auto child = json_object_array_get_idx (delays, i);
445
+
446
+ // We need to know the type of delay. "propagation" is handled by us
447
+ // Anything else is a derived class
448
+ json_object* type;
449
+ if (!json_object_object_get_ex (child, " type" , &type))
450
+ {
451
+ LogError (" No type info for this delay value\n " );
452
+ return false ;
453
+ }
454
+ string stype = json_object_get_string (type);
455
+
456
+ // Load rising/falling delays and save them
457
+ if (stype == " propagation" )
458
+ {
459
+ if (!LoadPropagationDelay (corner, child))
460
+ return false ;
461
+ continue ;
462
+ }
463
+
464
+ // Nope, something special
465
+ if (!LoadExtraTimingData (corner, stype, child))
466
+ return false ;
467
+ }
468
+
469
+ return true ;
470
+ }
471
+
472
+ /* *
473
+ @brief Loads propagation delay for a single endpoint and process corner
474
+ */
475
+ bool Greenpak4BitstreamEntity::LoadPropagationDelay (PTVCorner corner, json_object* object)
476
+ {
477
+ // Pull out all of the json stuff
478
+ json_object* from;
479
+ if (!json_object_object_get_ex (object, " from" , &from))
480
+ {
481
+ LogError (" No source for this delay\n " );
482
+ return false ;
483
+ }
484
+ string sfrom = json_object_get_string (from);
485
+
486
+ json_object* to;
487
+ if (!json_object_object_get_ex (object, " to" , &to))
488
+ {
489
+ LogError (" No dest for this delay\n " );
490
+ return false ;
491
+ }
492
+ string sto = json_object_get_string (to);
493
+
494
+ json_object* rising;
495
+ if (!json_object_object_get_ex (object, " rising" , &rising))
496
+ {
497
+ LogError (" No rising info for this corner\n " );
498
+ return false ;
499
+ }
500
+ float nrising = json_object_get_double (rising);
501
+
502
+ json_object* falling;
503
+ if (!json_object_object_get_ex (object, " falling" , &falling))
504
+ {
505
+ LogError (" No falling info for this corner\n " );
506
+ return false ;
507
+ }
508
+ float nfalling = json_object_get_double (falling);
509
+
510
+ // Finally, we can actually save the delay!
511
+ m_pinToPinDelays[corner][PinPair (sfrom, sto)] = CombinatorialDelay (nrising, nfalling);
512
+
513
+ return true ;
514
+ }
515
+
516
+ /* *
517
+ @brief Loads timing data other than normal propagation info
518
+
519
+ Base class implementation should never be called (base class should override) if there's any extra data,
520
+ but we need a default implementation to avoid every derived class having an empty stub
521
+ */
522
+ bool Greenpak4BitstreamEntity::LoadExtraTimingData (PTVCorner /* corner*/ , string /* delaytype*/ , json_object* /* object*/ )
523
+ {
524
+ LogWarning (" Greenpak4BitstreamEntity: Don't know what to do with delay type %s\n " , delaytype.c_str ());
525
+ return true ;
526
+ }
0 commit comments