以下程式會自動讀取 timing report 中的 hold time violation,跟據 clock pin name 找到 flip-flop,並且在 flip-flop output pin 的 net 上自動加入 delay cell。反覆執行以上動作直到所有的 hold time violation 都被修復為止。
In Tcl File:
proc fix_hold_time_violations {} {
report_timing -delay_type min > top_hold.rpt
set target_pin [exec python get_hold_time_violation.py top_hold.rpt]
while {$target_pin != {}} {
set target_net [get_nets -of_objects $target_pin]
insert_buffer [get_nets $target_net] DELAY_CELL_NAME
legalize_placement -cells [get_cells -hierarchical {eco_cell*}]
route_zrt_eco -reroute modified_nets_only
report_timing -delay_type min > top_hold.rpt
set target_pin [exec python get_hold_time_violation.py top_hold.rpt]
}
derive_pg_connection -power_net VDD -ground_net VSS -power_pin VDD -ground_pin VSS
}
In Python File:
import sys
clock_pin_name1 = "CP"
clock_pin_name2 = "CLK"
if len(sys.argv) == 2:
fname = sys.argv[1]
with open(fname, "r") as f:
lines = f.readlines()
need_fix = 0
for i in range(len(lines)):
line = lines[i]
if "slack" in line:
if "VIOLATED" in line:
need_fix = 1
break
if need_fix:
start = 0
for i in range(len(lines)):
line = lines[i]
if "clock network delay" in line:
start = i
break
if start:
target_cell = ""
for i in range(start, len(lines)):
line = lines[i]
if "/" + clock_pin_name1 in line or "/" + clock_pin_name2 in line:
start = i + 1
target_cell = line.split()[1][1:-1]
break
if target_cell != "":
for i in range(start, len(lines)):
line = lines[i]
if target_cell in line:
start = i + 1
target_pin = line.split()[0]
print(target_pin)
break