hard Phy boundary No Path
1. shift mode;
shift cornor出现No Path的;
PHY SI SO在shift mode必须有timing的path; 展示为No constrained path;
check step:
report_timing -though
NO constrained path
set timing_report_unconstrained true
report again
you will get a potential path;
get the clock of startpiont
now the no path reason would be two case:
- start point & end point is in two difference clock group;
- Lib is no include the timing arc of this pin;
check the lib:
发现在shift mode吧 bypass func的lib也读入了; 通过remove lib 确认最终读如的lib:
重新读入lib, shift path 出现;
2.dc capture mode
同样发现 hard phy SI SO的出现 no path;
- 在DC capture mode 本身是不会颠末SI D path; 所以SI Q path不存在本身也是合理的;(结论是否正确)
- 存在的Path 为bypass 的pass ,是由于同属一个clock group ,DFT未插lock up latch导致; Path 为 true path, 须要后端修;
其他非SI SO pin的no path;
优先查看Lib中在此mode是否存在 timing arc;
附加处理lib的脚本;
- import re
- def read_pinlist(pinlist_file):
- """
- Read pinlist from a text file, where each line contains one pin_name.
- Parameters:
- pinlist_file (str): Path to the pinlist file.
- Returns:
- list: A list of pin_names.
- """
- try:
- with open(pinlist_file, 'r') as f:
- # Read lines, strip whitespace, and skip empty lines
- pinlist = [line.strip() for line in f.readlines() if line.strip()]
- return pinlist
- except FileNotFoundError:
- print(f"Error: File {pinlist_file} not found")
- return []
- def parse_lib(lib_content):
- """
- Parse the lib file content and return a dictionary with pin_name as keys and their corresponding timing block modes as values.
- Parameters:
- lib_content (str): The text content of the lib file.
- Returns:
- dict: A dictionary containing pin_name and its timing block modes.
- """
- pin_dict = {}
- # Regular expression to match pin blocks
- pin_pattern = r'pin\((.*?)\)\s*{([^{}]*)}'
- pin_matches = re.findall(pin_pattern, lib_content, re.DOTALL)
-
- for pin_match in pin_matches:
- # Extract pin_name and remove leading/trailing spaces and quotes
- pin_name = pin_match[0].strip().strip('"')
- pin_content = pin_match[1]
-
- # Match timing blocks
- timing_pattern = r'timing\(\)\s*{([^{}]*)}'
- timing_matches = re.findall(timing_pattern, pin_content, re.DOTALL)
-
- modes = []
- for timing_match in timing_matches:
- timing_content = timing_match
- # Match mode field
- mode_pattern = r'mode\(etm_mode\s*,\s*"([^"]*)"\s*\);'
- mode_match = re.search(mode_pattern, timing_content)
- if mode_match:
- mode_name = mode_match.group(1).strip() # Remove leading/trailing spaces from mode_name
- modes.append(mode_name)
-
- pin_dict[pin_name] = modes
-
- return pin_dict
- def check_pins(pinlist, pin_dict):
- """
- Check the status of each pin_name in pinlist based on the lib file and print the results.
- Parameters:
- pinlist (list): A list of pin_names to check.
- pin_dict (dict): A dictionary parsed from the lib file containing pin information.
- """
- for pin_name in pinlist:
- if pin_name not in pin_dict:
- print(f"{pin_name}: NO pin_name")
- else:
- modes = pin_dict[pin_name]
- if not modes:
- print(f"{pin_name}: NO timing arc")
- elif "stuckat_cap" not in modes:
- print(f"{pin_name}: NO stuckat_cap mode")
- else:
- print(f"{pin_name}: Exist stuckat_cap mode")
- def main():
- # Example lib file path (modify according to actual path)
- lib_file_path = "lib.txt"
- try:
- with open(lib_file_path, "r") as f:
- lib_content = f.read()
- except FileNotFoundError:
- print(f"Error: File {lib_file_path} not found")
- return
-
- # Parse the lib file
- pin_dict = parse_lib(lib_content)
-
- # Example pinlist (modify according to actual needs)
- pinlist = ["pin1", "pin2", "pin3", "pin4"]
-
- # Check and print results
- check_pins(pinlist, pin_dict)
- if __name__ == "__main__":
- main()
- import re
- def parse_lib(lib_content):
- """Parse the lib file content and return a dictionary with pin_name as keys and their corresponding pin content as values."""
- pins = {}
- lines = lib_content.split('\n')
- current_pin = None
- pin_content = []
- brace_level = 0
- collecting = False
- for line in lines:
- stripped = line.strip()
- if not collecting and stripped.startswith('pin('):
- # Extract pin name
- pin_start = stripped.find('(') + 1
- pin_end = stripped.find(')')
- if pin_end == -1:
- continue # Skip if format is incorrect
- current_pin = stripped[pin_start:pin_end].strip()
- brace_start = stripped.find('{', pin_end)
- if brace_start != -1:
- brace_level = 1
- collecting = True
- # Add the first line content (if any)
- rest = stripped[brace_start+1:].strip()
- if rest:
- pin_content.append(rest)
- elif collecting:
- # Calculate brace level
- brace_level += line.count('{')
- brace_level -= line.count('}')
-
- if brace_level > 0:
- pin_content.append(line)
- else:
- collecting = False
- pins[current_pin] = '\n'.join(pin_content)
- current_pin = None
- pin_content = []
- return pins
- def analyze_pin(pin_content):
- """Analyze the content of a single pin and return its status."""
- # Check if there are timing blocks
- timing_blocks = []
- in_timing = False
- current_block = []
- brace_level = 0
-
- for line in pin_content.split('\n'):
- stripped = line.strip()
- if not in_timing and stripped.startswith('timing('):
- in_timing = True
- brace_level = 0
- current_block = []
-
- if in_timing:
- current_block.append(line)
- brace_level += line.count('{')
- brace_level -= line.count('}')
-
- if brace_level <= 0:
- in_timing = False
- timing_blocks.append('\n'.join(current_block))
-
- if not timing_blocks:
- return "NO timing arc"
-
- # Check if any timing block contains stuckat_cap mode
- pattern = re.compile(r'mode\s*\(\s*etm_mode\s*,\s*"\s*stuckat_cap\s*"\s*\)')
- for block in timing_blocks:
- if pattern.search(block):
- return "OK"
-
- return "NO stuckat_cp mode"
- def main(pinlist_file, lib_file):
- with open(lib_file, 'r') as f:
- content = f.read()
-
- pins = parse_lib(content)
- pinlist= read_pinlist(pinlist_file);
- if not pinlist:
- print("Pinlist is empty or file not exist");
- return
-
- for pin_name in pinlist:
- if pin_name not in pins:
- print(f"{pin_name}: Not found")
- continue
-
- status = analyze_pin(pins[pin_name])
- print(f"{pin_name}: {status}")
- # Example usage
- if __name__ == "__main__":
- pinlist_file = "./file_name"# Replace with actual pin list
- lib_file = "your_lib.lib" # Replace with actual lib file path
- main(pinlist, lib_file)
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |