ExASIC
分享让工作更轻松

用python写综合脚本

本文写了三个示例,展示了三种综合脚本的写法,供大家可以参考。

一:直接f.write()

第一种写法,在文件开头定义常修改的综合配置,然后直接用write函数,写到syn.tcl里。最后调用os.system("dc_shell -f syn.tcl")来执行综合。

import os

# config
#prj_root = '/home/xxx/prj/e100'
prj_root = '.'

lib_path = prj_root + '/syn'
lib_max = 'slow.db'

rtl_path = prj_root + '/rtl'
rtl_flist = rtl_path + '/rtl.flist'

# write syn script
print('Generate syn.tcl ...')
tcl = open('syn.tcl', 'w')
tcl.write('set lib_path ' + lib_path + '\n')
tcl.write('set ss_lib ' + lib_max + '\n')
tcl.write('set search_path [concat $search_path $lib_path]\n')
tcl.write('set target_library [list $ss_lib]\n')
tcl.write('set synthetic_library [list dw_foundation.sldb]\n')
tcl.write('set link_library [list * $ss_lib $synthetic_library]\n')

rtls = open(rtl_flist, 'r').readlines()
for rtl in rtls:
    tcl.write('analyze -format verilog ' + rtl.rstrip() + '\n')
tcl.write('elaborate top\n')
tcl.write('link\n')
tcl.write('check_design\n')
# ... other syn script
print('Done')

# Do synthesis
print('Run Command: dc_shell -f syn.tcl')
#os.system('dc_shell -f syn.tcl')
# ...

二、把综合配置写在配置文件里

第一种方法里,综合配置写死在脚本里,每换一个项目都必须要修改脚本,不够通用。所以在第二个示例里,我们把配置写到json里。

配置文件如下:

{
    "prj_root": ".",
    "lib_path": "./syn",
    "lib_max": "slow.db",
    "rtl_path": "./rtl",
    "rtl_flist": "./rtl/rtl.flist"
}

在脚本开头,把json配置文件读进来(json.loads()),转换成python的字典类型。后续跟示例一相同。

import os
import json

# config
jsonfile = open('syn.json').read()
cfg = json.loads(jsonfile)
print(cfg)

#prj_root = '/home/xxx/prj/e100'
prj_root = cfg["prj_root"]

lib_path = cfg["lib_path"]
lib_max = cfg["lib_max"]

rtl_path = cfg["rtl_path"]
rtl_flist = cfg["rtl_flist"]

三、把综合命令提炼成模板

对于综合来说,总是按照一定的flow,一步步执行和调试。所以其中的命令大部分是不变的,变的只是少量参数。

下面是一个Mako模板示例(Mako这一种模板语言,详见https://www.makotemplates.org):

set lib_path ${lib_path}
set ss_lib ${lib_max}
set search_path [concat $search_path $lib_path]
set target_library [list $ss_lib]
set synthetic_library [list dw_foundation.sldb]
set link_library [list * $ss_lib $synthetic_library]
% for rtl in rtls:
analyze -format verilog ${rtl}
% endfor
elaborate top
link
check_design

可以看出变化的部分用${xxx}来表示,比如,${lib_path}${rtl}。还可以嵌入for循环,以提高效率。

在脚本里,根据json配置文件里定义的参数,来代替模板里的变化部分。这个替换的过程也叫做渲染(Render),下面是具体实现:

import os
import json
from mako.template import Template

# read config file
jsonfile = open('syn.json').read()
cfg = json.loads(jsonfile)
print(cfg)

prj_root = cfg["prj_root"]

lib_path = cfg["lib_path"]
lib_max = cfg["lib_max"]

rtl_path = cfg["rtl_path"]
rtl_flist = cfg["rtl_flist"]

rtls = open(rtl_flist, 'r').read().splitlines()
print(rtls)

# define a template
t = """
set lib_path ${lib_path}
set ss_lib ${lib_max}
set search_path [concat $search_path $lib_path]
set target_library [list $ss_lib]
set synthetic_library [list dw_foundation.sldb]
set link_library [list * $ss_lib $synthetic_library]
% for rtl in rtls:
analyze -format verilog ${rtl}
% endfor
elaborate top
link
check_design
"""

# write syn script
print('Generate syn.tcl ...')
mytemplate = Template(t)
scr = mytemplate.render(lib_path=lib_path,
                  lib_max=lib_max,
                  rtls=rtls)
tcl = open('syn.tcl', 'w')
tcl.write(scr)
print('Done')

# Do synthesis
print('Run Command: dc_shell -f syn.tcl')
#os.system('dc_shell -f syn.tcl')
# ...

补充几点

总结

文中的示例代码可以这里下载:https://github.com/chenfengrugao/pythontutorial/tree/master/day21

阅读数:
更多文章:文章目录
解惑专区
(支持markdown插入源代码)
欢迎使用ExASIC订阅服务
仅用于ExASIC最新文章通知,方便及时阅读。
友情链接: IC技术圈问答ReCclayCrazyFPGA