首页 > 编程知识 正文

python3,查看pyd文件源码

时间:2023-05-03 09:06:47 阅读:161872 作者:1732

Spyglass是重要的CDC检测工具,主要功能是抽象SOC,生成sgdc文件,支持RTL分析、CDC分析、功耗分析等。 完整的SOC项目可能会生成几十个sgdc文件,每个文件的行数将达到数万行。 手动分析sgdc文件很麻烦,需要使用脚本来帮助分析。

python版本: python 3.7

使用的工具:正则表达式

任务目标:分析所有sdgc文件,生成同名的csv文件。 csv文件中的详细表述抽象端口的信息

预处理文件必须首先在只读模式中打开Spyglass生成的sgdc文件。 不能破坏原始的sgdc文件。 打开sgdc文件后,有大量的约束换行。 具体情况如下。

clock-name ' XXX '-tag XXX-domain D7-period 40000-edge '0' ' 20000 ' clock-name ' XXX '-tag XXX - domaind0- period 1666.666626-edge '0' ' 833.333313 ' clock-name ' XXX '-tag XXX- domain D1-period 1250-edge ' 0

defsgdc_func(path,file_name ) :file1=open ) path'/'file_name, ' r ' ) file1_ temp _ name=file _ name [ :-5 ] ' _ revised ' '.sgdc ' file1_ temp=open (file1_ temp _ namp ) ) )、replaceandnwith'fillace 0) relocatethefilepointertofileheadfile1_ lines=file1_ temp.read lines )

file1_lines是一个列表,元素是sgdc文件中每行的约束条件,元素类型为字符串。

关键字匹配最重要的部分是基于去掉约束换行后提取,csv文件的报头信息如下:

file2_ name=file _ name [ :-5 ] '.CSV ' file2=open (file2_ name,' w ' ) file2.write (,'.Join ) ) clock/domain/source ',' direction/period/divide/value ' ) 'n ' ) name是端口名称,有三种类型:端口、时钟和复位。

width/clk/reset标记端口的位宽,区分clk和generated_clk,并标记reset;

模块/标记端口所属的模块、标记时钟的标记;

clock/domain/source标记端口受哪些时钟约束,标记时钟所属的时钟字段,generated_clk的source;

direction/period/divide/value标记端口方向,标记时钟周期,标记分频系数,标记重置值

abstract_port默认sdgc文件中的所有端口属于同一模块;

关键字abstract_port表示此语句约束端口。 代码如下所示。

num=0if file1_lines 3360 # file1_ linesisalistforiteminrange (len ) file1_ lines ) (:if ) re.search ) Abstrach file1_lines[item] ) (: # key word abstract_port匹配模式为abstract_port -ports。 这是因为有些注释也跟在abstract_port,-ports之后

计算位宽很麻烦。 因为sgdc文件的端口位宽有以下几种写法。

abstract _ port-ports ' XXX '-clock ' XXX '-module ' XXX ' abstract _ port-ports ' XXX [0] '-clock ' XXX-mod

tract_port -ports "xxx[6:4]" -clock "xxx" -module "xxx" -related_ports xxx[0] xxx[1]

总结规律: 多位宽一定会有[],但是有[]不一定是多位宽,因为-related_ports的参数 也可能包含[],不带[]一定是单位宽,带了[]也可能是单位宽;
python处理时将多位宽和单位宽分开处理,一个关键的匹配模式是:

if re.search(r"(?<=(-ports ))s*"?w*[d*:?(d*)?][^ b]",file1_lines[item]): # need to merge the port [A:B] and [A]

这个匹配模式 将related_ports中的中括号忽略了,不识别单位宽,识别了多位宽的所有形式;
将带 : 的形式与 不带 : 的形式分开处理, 带 : 的形式 分别提取出 : 左右两边的 数字, 作差以后取绝对值再加1,作为此行语句的对应位宽, 不带 : 位宽直接加1;
同时需要提取出当前行 和下一行的端口名字, 如果端口名字是一样的, 表明当前的端口描述还未结束,需要继续分析下一行,如果不一样,表明当前端口描述结束,计算出端口的位宽即可,具体代码如下:

if(re.search("abstract_port -ports",file1_lines[item])): # key word abstract_port list1 = [] if re.search(r"(?<=(-ports ))s*"?w*[d*:?(d*)?][^ b]",file1_lines[item]): # need to merge the port [A:B] and [A] if re.search(r"(?<=(-ports ))s*"?w*[d*:(d*)?][^ b]",file1_lines[item]): # in the form of A:B str1 = re.search(r"(?<=(-ports ))s*"?w*[d*:(d*)?][^ b]",file1_lines[item]).group() str1 = str1.strip().strip('"') str2 = re.search(r"(?<=([))[^:]*",str1).group() str3 = re.search(r"(?<=(:))[^]]*",str1).group() num_temp = abs(int(str3) - int(str2)) + 1 num += num_temp else: num += 1 # in the form of [A] str1 = re.search(r"(?<=(-ports ))s*"?w*[d*:?(d*)?][^ b]",file1_lines[item]).group() # str1 needs to be deassigned str1 = str1.strip().strip('"') str1 = re.match(r"[A-Za-z0-9_]*[^[:]]",str1).group() # the port name match not search if re.search(r"(?<=(-ports ))s*"?w*[d*:?(d*)?][^ b]",file1_lines[item+1]): str2 = re.search(r"(?<=(-ports ))s*"?w*[d*:?(d*)?][^ b]",file1_lines[item+1]).group() str2 = str2.strip().strip('"') str2 = re.match(r"[A-Za-z0-9_]*[^[:]]",str2).group() else: str2 = ' ' if(str1 == str2): continue else: list1.append(str1) list1.append(str(num)) num = 0

单位宽语句的处理,直接将位宽加1即可!

多余空格和引号的处理

实际分析sgdc文件时,发现 -ports等所有关键词与后面的参数之间,未必是固定一个空格,可能存在若干个不定数量的空格,且参数有可能用引号包裹,也有可能没有引号包裹,所以匹配模式的通用形式是

(?<=(-module ))s*"?[^ "b]*

-xxx表明关键字,但是 后面必须要有s*,否则会漏匹配一些语句,且python的正则表达式不支持将 不定长的内容用 ?<= 修饰,其实一般的正则表达式解释器是支持的,"?也很重要,因为参数可能用 " 包裹,也有可能没有引号!
匹配完成后一定要去掉多余的空格和引号,方法为:

str2 = str2.strip().strip('"') output与clock -name与 reset

这两个的处理方法与abstract_port接近,但是clock -name关键字会同时匹配到clock -name与generated_clock -name,所以还需要再次进行区分

多文件处理 import reimport osfrom sgdc_func import sgdc_funcpath = 'your_path'path_list = os.listdir(path)path_list_sgdc = []for item in path_list: if re.search(r'(.*.sgdc)[^ .swp]?',item): if re.search(r'(.*.sgdc)[^ .swp]?',item).group() == item: path_list_sgdc.append(item)print("There are %d sgdc files!n" %len(path_list_sgdc))path_list_sgdc.sort()

首先使用os.listdir()函数获取指定路径下所有的 文件名列表,注意区别sgdc格式的文件和sgdc.swp格式的文件。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。