Skip to content

Commit 48edca9

Browse files
committedJun 9, 2017
BUGFIX: Static timing analysis no longer goes into infinite recursion when we have a combinatorial loop. Report combinatorial loops as PAR warnings. Skip timing analysis if we have no timing data file. Reduced warning spam when timing data is incomplete from one message per path to one message total
1 parent 567ff4a commit 48edca9

File tree

3 files changed

+60
-8
lines changed

3 files changed

+60
-8
lines changed
 

Diff for: ‎src/gp4par/par_reporting.cpp

+49-8
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,12 @@ void PrintPlacementReport(PARGraph* netlist, Greenpak4Device* /*device*/)
247247
*/
248248
void PrintTimingReport(Greenpak4Netlist* netlist, Greenpak4Device* device)
249249
{
250+
if(!device->HasTimingData())
251+
{
252+
LogWarning("No timing data for target device, not running timing analysis\n");
253+
return;
254+
}
255+
250256
LogNotice("\nTiming report:\n");
251257
LogIndenter li;
252258

@@ -287,6 +293,7 @@ void PrintTimingReport(Greenpak4Netlist* netlist, Greenpak4Device* device)
287293

288294
//DEBUG: print all paths
289295
int i=0;
296+
bool incomplete = false;
290297
for(auto path : paths)
291298
{
292299
LogVerbose("Path %d\n", i++);
@@ -330,8 +337,9 @@ void PrintTimingReport(Greenpak4Netlist* netlist, Greenpak4Device* device)
330337
auto rscell = device->GetIOB(3);
331338
if(!rscell->GetCombinatorialDelay(previous_port, edge->m_sourceport, corner, delay))
332339
{
333-
LogWarning("Couldn't get timing data even from fallback pin\n");
334-
delay = CombinatorialDelay(0, 0);
340+
//LogWarning("Couldn't get timing data even from fallback pin\n");
341+
incomplete = true;
342+
continue;
335343
}
336344
}
337345

@@ -356,8 +364,9 @@ void PrintTimingReport(Greenpak4Netlist* netlist, Greenpak4Device* device)
356364
CombinatorialDelay delay;
357365
if(!srccell->GetCombinatorialDelay(previous_port, edge->m_sourceport, corner, delay))
358366
{
359-
LogWarning("Couldn't get timing data\n");
360-
delay = CombinatorialDelay(0, 0);
367+
//LogWarning("Couldn't get timing data\n");
368+
incomplete = true;
369+
continue;
361370
}
362371
float worst = delay.GetWorst();
363372
cdelay += worst;
@@ -381,8 +390,9 @@ void PrintTimingReport(Greenpak4Netlist* netlist, Greenpak4Device* device)
381390
{
382391
if(!xc->GetCombinatorialDelay("I", "O", corner, delay))
383392
{
384-
LogWarning("Couldn't get timing data\n");
385-
delay = CombinatorialDelay(0, 0);
393+
//LogWarning("Couldn't get timing data\n");
394+
incomplete = true;
395+
continue;
386396
}
387397
float worst = delay.GetWorst();
388398
cdelay += worst;
@@ -410,8 +420,9 @@ void PrintTimingReport(Greenpak4Netlist* netlist, Greenpak4Device* device)
410420
auto rscell = device->GetIOB(3);
411421
if(!rscell->GetCombinatorialDelay(edge->m_destport, "IO", corner, delay))
412422
{
413-
LogWarning("Couldn't get timing data even from fallback pin\n");
414-
delay = CombinatorialDelay(0, 0);
423+
//LogWarning("Couldn't get timing data even from fallback pin\n");
424+
incomplete = true;
425+
continue;
415426
}
416427
}
417428

@@ -432,6 +443,8 @@ void PrintTimingReport(Greenpak4Netlist* netlist, Greenpak4Device* device)
432443
"+--------------------------------------------------------------+------------+-----------"
433444
"+------------+------------+------------+\n");
434445
}
446+
if(incomplete)
447+
LogWarning("Timing data doesn't have info for all primitives, report is incomplete\n");
435448
}
436449

437450
/**
@@ -495,6 +508,34 @@ void FindCombinatorialPaths(
495508
{
496509
auto edge = destnode->GetEdgeByIndex(i);
497510

511+
//Verify that this edge is not already in the netlist. If it is, complain and stop
512+
bool loop = false;
513+
for(auto tedge : basepath)
514+
{
515+
if(edge == tedge)
516+
{
517+
loop = true;
518+
519+
LogWarning("Found combinatorial loop, not following it for static timing\n");
520+
LogIndenter li;
521+
522+
for(auto eedge : basepath)
523+
{
524+
auto snode = static_cast<Greenpak4NetlistEntity*>(eedge->m_sourcenode->GetData());
525+
auto dnode = static_cast<Greenpak4NetlistEntity*>(eedge->m_destnode->GetData());
526+
LogWarning("From cell %50s port %15s to %50s port %15s\n",
527+
snode->m_name.c_str(),
528+
eedge->m_sourceport.c_str(),
529+
dnode->m_name.c_str(),
530+
eedge->m_destport.c_str());
531+
}
532+
533+
break;
534+
}
535+
}
536+
if(loop)
537+
continue;
538+
498539
//Find all paths that begin with the new, longer path
499540
CombinatorialPath npath = basepath;
500541
npath.push_back(edge);

Diff for: ‎src/greenpak4/Greenpak4Device.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Greenpak4Device::Greenpak4Device(
3434
, m_disableChargePump(false)
3535
, m_ldoBypass(false)
3636
, m_nvmLoadRetryCount(1)
37+
, m_hasTimingData(false)
3738
{
3839
//Create power rails
3940
//These have to come first, since all other nodes will refer to these during construction
@@ -1413,5 +1414,7 @@ bool Greenpak4Device::LoadTimingData(json_object* object)
14131414
return false;
14141415
}
14151416

1417+
m_hasTimingData = true;
1418+
14161419
return true;
14171420
}

Diff for: ‎src/greenpak4/Greenpak4Device.h

+8
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,9 @@ class Greenpak4Device
336336
bool LoadTimingData(json_object* object);
337337
bool LoadTimingData(std::string fname);
338338

339+
bool HasTimingData()
340+
{ return m_hasTimingData; }
341+
339342
protected:
340343

341344
bool GenerateBitstream(bool* bitstream, uint8_t userid, bool readProtect);
@@ -496,6 +499,11 @@ class Greenpak4Device
496499
@brief Number of times to attempt re-reading NVM in case of boot failure
497500
*/
498501
int m_nvmLoadRetryCount;
502+
503+
/**
504+
@brief True if we have static timing data
505+
*/
506+
bool m_hasTimingData;
499507
};
500508

501509
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.