Synopsys数字前端工程自动产生脚本
随手弄了个Synopsys数字前端工程自动产生脚本,使用方式是在要创建工程的路径下python env_setup.py即可自动创建工程文件夹,随后进入prj子文件夹使用makefile调用工具即可。
写的比较仓促,有的功能没怎么测到,欢迎有bug或者修改意见在评论区反馈。
env_setup内容:
import os
# 定义文件树结构
file_tree = {
'lib': {},
'netlist': {},
'prj': {
'filelist.f': None,
'makefile': None
},
'src': {
'rtl': {},
'sdc': {}
},
'tb': {},
'work': {
'dc': {
'outputs': {},
'reports': {},
'scripts': {
'dc_post_syn.tcl': None,
'dc_read_design.tcl': None,
'dc_set_cons.tcl': None,
'dc_set_env.tcl': None,
'dc_setup.tcl': None,
'dc_syn.tcl': None,
'run_dc.tcl': None
}
},
'sg': {
'scripts': {}
},
'vcs': {},
'verdi': {}
}
}
# 创建文件树
def create_file_tree(base_path, tree, root_name):
for name, subtree in tree.items():
path = os.path.join(base_path, name)
if subtree is None:
# 创建文件
open(path, 'a').close()
else:
# 创建文件夹
os.makedirs(path, exist_ok=True)
create_file_tree(path, subtree, root_name)
# 在rtl文件夹下生成与root_dir同名的.v文件
if 'rtl' in tree:
rtl_file_path = os.path.join(base_path, 'rtl', f"{root_name}.v")
with open(rtl_file_path, 'w') as f:
rtl_content = f"""module {root_name} (
input clk,
input rst_n,
input [31:0] a,
input [31:0] b,
output reg [31:0] c
);
always @(posedge clk or negedge rst_n) begin
if (~rst_n)
c <= 32'h00000000;
else
c <= a + b;
end
endmodule
"""
f.write(rtl_content)
# 在tb文件夹下生成tb_{root_name}.v文件
if 'tb' in tree:
tb_file_path = os.path.join(base_path, 'tb', f"tb_{root_name}.v")
with open(tb_file_path, 'w') as f:
tb_content = f"""module tb_{root_name}();
reg clk;
reg rst_n;
reg [31:0] a;
reg [31:0] b;
wire [31:0] c;
always #10 clk = ~clk; //50MHz
initial begin
clk = 1'b0;
rst_n = 1'b0;
a = 32'h00000000;
b = 32'h00000000;
#10;
rst_n = 1'b1;
a = 32'h00001234;
b = 32'h00004321;
#100;
$finish;
end
{root_name} u_{root_name} (
.clk(clk),
.rst_n(rst_n),
.a(a),
.b(b),
.c(c)
);
`ifdef FSDB
initial begin
$fsdbDumpfile("tb_{root_name}.fsdb");
$fsdbDumpvars;
$fsdbDumpMDA();
end
`endif
endmodule
"""
f.write(tb_content)
# 在sdc文件夹下生成与root_dir同名的.sdc文件
if 'sdc' in tree:
sdc_file_path = os.path.join(base_path, 'sdc', f"{root_name}.sdc")
with open(sdc_file_path, 'w') as f:
sdc_content = f"""# Definition of Clock
set Tclk 20 ;#50MHz
set clk_name "clk"
set unc_perc 0.05
create_clock -name $clk_name -period $Tclk [get_ports clk]
set_clock_uncertainty -setup [expr $Tclk * $unc_perc] [get_clocks $clk_name]
set_clock_transition 0.4 [all_clocks]
# Set Ideal Network
set_dont_touch_network [get_ports clk]
set_ideal_network [get_port clk]
set_dont_touch_network [get_ports rst_n]
# Definition of IO
set_input_delay [expr $Tclk*1/5.0] -clock $clk_name [all_inputs]
remove_input_delay [get_ports clk]
set_output_delay [expr $Tclk*1/5.0] -clock $clk_name [all_outputs]
# Other Constraint
set_max_transition 0.6 [current_design]
set_max_fanout 64 [current_design]
set_max_capacitance 2 [current_design]
set_input_transition -max 0.5 [all_inputs]
set_load 2 [all_outputs]
set_max_leakage_power 0
set_max_area 0
"""
f.write(sdc_content)
# 在sdc文件夹下生成与root_dir同名的.sgdc文件
if 'sdc' in tree:
sgdc_file_path = os.path.join(base_path, 'sdc', f"{root_name}.sgdc")
with open(sgdc_file_path, 'w') as f:
sgdc_content = f"""current_design {root_name}
sdc_data -file ../../src/sdc/{root_name}.sdc
"""
f.write(sgdc_content)
# 在sg/scripts文件夹下生成run_sg.tcl文件
if 'scripts' in tree.get('sg', {}):
sg_script_path = os.path.join(base_path, 'sg', 'scripts', 'run_sg.tcl')
with open(sg_script_path, 'w') as f:
sg_script_content = f"""set design_name "{root_name}"
# read in files
read_file -type sourcelist ../../prj/filelist.f
# read_file -type gateslib ../../lib/
read_file -type sgdc ../../src/sdc/${{design_name}}.sgdc
# setup
set_option top ${{design_name}}
set_option sdc2sgdc yes
current_goal Design_Read -top ${{design_name}}
link_design -force
# run lint
current_goal lint/lint_rtl -top ${{design_name}}
run_goal
# save project
save_project -force
"""
f.write(sg_script_content)
# 在dc/scripts文件夹下生成多个tcl文件
if 'scripts' in tree.get('dc', {}):
dc_scripts = [
'dc_post_syn.tcl',
'dc_read_design.tcl',
'dc_set_cons.tcl',
'dc_set_env.tcl',
'dc_setup.tcl',
'dc_syn.tcl',
'run_dc.tcl'
]
for script in dc_scripts:
script_path = os.path.join(base_path, 'dc', 'scripts', script)
open(script_path, 'a').close()
# 获取用户输入的根目录
root_dir = input("请输入根目录路径: ")
# 获取根目录名称
root_name = os.path.basename(root_dir)
# 创建文件树
create_file_tree(root_dir, file_tree, root_name)
# 在makefile中生成内容
makefile_content = f""".PHONY:vcs verdi dc sg dve
OUTPUT = {root_name}
TIMESCALE = 1ns/1ps
#start vcs
vcs:
\tcd ../work/vcs && vcs -R -sverilog -full64 +v2k -debug_pp -timescale=${{TIMESCALE}} -cpp g++ -cc gcc -LDFLAGS -no-pie -LDFLAGS -Wl,--no-as-needed -CFLAGS -fPIE -fsdb -f ../../prj/filelist.f -o ${{OUTPUT}} -l compile.log
#start verdi
verdi:
\tcd ../work/verdi && verdi -sv -f ../../prj/filelist.f -ssf ../vcs/tb_${{OUTPUT}}.fsdb
#start dc
dc:
\tcd ../work/dc && dc_shell -f ./scripts/run_dc.tcl | tee ./syn.log && rm -r ~/synopsys_cache_O-2018.06-SP1
#start sg
sg:
\tcd ../work/sg && sg_shell -tcl ./scripts/run_sg.tcl
#start dve
dve:
\tcd ../work/vcs && ./${{OUTPUT}} -gui
"""
makefile_path = os.path.join(root_dir, 'prj', 'makefile')
with open(makefile_path, 'w') as f:
f.write(makefile_content)
# 在filelist.f中生成内容
filelist_content = f"""//Macro define
+define+FSDB
// pre_sim
../../src/rtl/{root_name}.v
// post_sim
//../../netlist/
// library
//../../lib/
// testbench
../../tb/tb_{root_name}.v
"""
filelist_path = os.path.join(root_dir, 'prj', 'filelist.f')
with open(filelist_path, 'w') as f:
f.write(filelist_content)
# 在run_dc.tcl中生成内容
run_dc_content = f""" # dc setup
source ./scripts/dc_setup.tcl
# read design
source ./scripts/dc_read_design.tcl
# define design environment
source ./scripts/dc_set_env.tcl
# set design constraints
source ./scripts/dc_set_cons.tcl
# synthesis and optimize design
source ./scripts/dc_syn.tcl
# analyze and resolve design problems
source ./scripts/dc_post_syn.tcl
"""
run_dc_path = os.path.join(root_dir, 'work', 'dc', 'scripts', 'run_dc.tcl')
with open(run_dc_path, 'w') as f:
f.write(run_dc_content)
# 在dc_syn.tcl中生成内容
dc_syn_content = f"""
check_design > $report_path/check_design_before_compile.rpt
check_timing > $report_path/check_timing_before_compile.rpt
compile_ultra
compile_ultra -incremental
"""
dc_syn_path = os.path.join(root_dir, 'work', 'dc', 'scripts', 'dc_syn.tcl')
with open(dc_syn_path, 'w') as f:
f.write(dc_syn_content)
# 在dc_setup.tcl中生成内容
dc_setup_content = f"""
set design_name "{root_name}"
# standard cell library
set stdcel_libs "
../../lib/
"
# memory library
set memory_libs "
../../lib/
"
# ip library
set ip_libs "
../../lib/
"
set target_library "$stdcel_libs"
set link_library "* $target_library $memory_libs $ip_libs"
sh mkdir -p ./reports
sh mkdir -p ./outputs
set report_path "./reports"
set output_path "./outputs"
set_svf $output_path/${{design_name}}.svf
"""
dc_setup_path = os.path.join(root_dir, 'work', 'dc', 'scripts', 'dc_setup.tcl')
with open(dc_setup_path, 'w') as f:
f.write(dc_setup_content)
# 在dc_set_env.tcl中生成内容
dc_set_env_content = f"""
set_operating_conditions "" -library ""
set_wire_load_model -name ""
set_wire_load_mode top
set_host_options -max_cores 16
set_dp_smartgen_options -all_options auto -optimize_for speed
set_critical_range 3 [current_design]
set_app_var enable_page_mode false
"""
dc_set_env_path = os.path.join(root_dir, 'work', 'dc', 'scripts', 'dc_set_env.tcl')
with open(dc_set_env_path, 'w') as f:
f.write(dc_set_env_content)
# 在dc_set_cons.tcl中生成内容
dc_set_cons_content = f"""
set sdc_path "../../src/sdc"
source "$sdc_path/${{design_name}}.sdc"
"""
dc_set_cons_path = os.path.join(root_dir, 'work', 'dc', 'scripts', 'dc_set_cons.tcl')
with open(dc_set_cons_path, 'w') as f:
f.write(dc_set_cons_content)
# 在dc_read_design.tcl中生成内容
dc_read_design_content = f"""
analyze -f verilog -vcs "-f ../../prj/filelist.f"
elaborate $design_name
current_design $design_name
link
"""
dc_read_design_path = os.path.join(root_dir, 'work', 'dc', 'scripts', 'dc_read_design.tcl')
with open(dc_read_design_path, 'w') as f:
f.write(dc_read_design_content)
# 在dc_post_syn.tcl中生成内容
dc_post_syn_content = f"""
write_sdf -version 2.1 $output_path/${{design_name}}_post_dc.sdf
write -f ddc -hier -output $output_path/${{design_name}}_post_dc.ddc
write -f verilog -hier -output $output_path/${{design_name}}_post_dc.v
write_sdc $output_path/${{design_name}}_post_dc.sdc
report_constraint -all_violators -verbose > $report_path/constraint.rpt
report_qor > $report_path/qor.rpt
report_power > $report_path/power.rpt
report_area > $report_path/area.rpt
report_cell > $report_path/cell.rpt
report_clock > $report_path/clk.rpt
report_hierarchy > $report_path/hierarchy.rpt
report_design > $report_path/design.rpt
report_reference > $report_path/reference.rpt
report_timing > $report_path/timing.rpt
check_design > $report_path/check_design_post_compile.rpt
check_timing > $report_path/check_timing_post_compile.rpt
"""
dc_post_syn_path = os.path.join(root_dir, 'work', 'dc', 'scripts', 'dc_post_syn.tcl')
with open(dc_post_syn_path, 'w') as f:
f.write(dc_post_syn_content)
print(f"模板工程已在 {root_dir} 生成")
Synopsys数字前端工程自动产生脚本的更多相关文章
- 前端工程优化:javascript的优化小结
我觉得优化javascript是一门高深的学问,在这里也只能站在前人的肩膀上,说一些我浅显的认识,更希望的是抛钻引玉,如有不对,敬请斧正. 首先,要认识到是,优化js的关键之处在于,优化它的运行速度 ...
- 前端工程精粹(一):静态资源版本更新与缓存(附精简js的工具)
转自:http://www.infoq.com/cn/articles/front-end-engineering-and-performance-optimization-part1/ 每个参与过开 ...
- TypeScript 前端工程最佳实践
作者:王春雨 前言 随着前端工程化的快速发展, TypeScript 变得越来越受欢迎,它已经成为前端开发人员必备技能. TypeScript 最初是由微软开发并开源的一种编程语言,自2012年10月 ...
- 企业IT管理员IE11升级指南【15】—— 代理自动配置脚本
企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...
- 前端工程模块化——以一个php项目为例
实现一个页面功能总是需要 JavaScript.CSS 和 Template 三种语言相互组织,所以我们真正需要的是一种可以将 JavaScript.CSS 和 Template 同时都考虑进去的模块 ...
- 前端工程之模块化(来自百度FEX)
模块化 是一种处理复杂系统分解成为更好的可管理模块的方式,它可以把系统代码划分为一系列职责单一,高度解耦且可替换的模块,系统中某一部分的变化将如何影响其它部分就会变得显而易见,系统的可维护性更加简单易 ...
- xcode8.3 shell 自动打包脚本 记录
题记 xcode升级8.3后发现之前所用的xcode自动打包基本无法使用,因此在网上零碎找到些资料,将之前的脚本简化.此次脚本是基于xcode证书配置进行打包(之前是指定描述文件.相对繁琐).因此代码 ...
- 前端工程构建工具FIS3
FIS3 是面向前端的工程构建工具.解决前端工程中性能优化.资源加载(异步.同步.按需.预加载.依赖管理.合并.内嵌).模块化开发.自动化工具.开发规范.代码部署等问题. 一.安装 全局安装fis3 ...
- React Native开发中自动打包脚本
React Native开发中自动打包脚本 在日常的RN开发中,我们避免不了需要将我们编写的代码编译成安装包,然后生成二维码,供需要测试的人员扫描下载.但是对于非原生的开发人员来说,可能不知如何使用X ...
- xcode8.3 shell 自动打包脚本
题记 xcode升级8.3后发现之前所用的xcode自动打包基本无法使用,因此在网上零碎找到些资料,将之前的脚本简化.此次脚本是基于xcode证书配置进行打包(之前是指定描述文件.相对繁琐).因此代码 ...
随机推荐
- Web前端入门第 77 问:JavaScript 由程序触发绑定事件的几种方式
开发中经常会遇这样的需求:点击 A 元素的时候,需要触发 B 元素的事件,比如:点击一个 div 元素,然后触发 input:file 的 click 事件,用来选择文件上传. click 方法 以上 ...
- 客户端和服务端通信的多种函数的对比。linux 网络编程
第一种普通的read recv write Makefile #LOCAL_LIBRARY += -L./lib -lpal #LOCAL_LDFLAGS += -lm -lopus -lwebsoc ...
- ETLCloud中如何执行SQL脚本
SQL脚本 在数据库管理与数据分析的广阔领域中,SQL(Structured Query Language,结构化查询语言)脚本扮演着举足轻重的角色.作为一门专为关系型数据库设计的编程语言,SQL不仅 ...
- 开发环境: googletest + abseil-cpp-20230802.1 + protobuf
googletest: mkdir build && cd build && cmake -DCMAKE_CXX_STANDARD=17 -DABSL_BUILD_TE ...
- Edu-English-Phonetic-IPA:国际音标发音学:英语音标的学习神器,终于找到
https://mp.weixin.qq.com/s?__biz=MzU3NTIzOTA5OA==&mid=2247493736&idx=1&sn=8ed10241adeaa1 ...
- babylon.js 学习笔记(7)
前面我们学习了如何画一堆房子(如下图),显然这单调的绿色大地,看上去效果并不好. babylon.js中,可以用图片模拟出地势高低不同的效果,比如下面这张图片: 颜色越深的地方,表示地势越低(即:盆地 ...
- Argo CD持续交付工具部署
介绍 Argo CD 是一款适用于 Kubernetes 的声明式 GitOps 持续交付工具. 架构 Argo CD 是作为一个 Kubernetes 控制器来实现的,它能持续监控运行中的应用程序, ...
- Javaweb-03后端基础:maven基础
Javaweb-03后端基础:maven基础 [ 任务列表 ] maven初识 maven概述 IDEA集成Maven 依赖管理 单元测试 maven常见问题解决 参考资料 1.maven初识 mav ...
- D - Tokitsukaze and Multiple
https://vjudge.net/contest/386223#problem/D Tokitsukaze has a sequence of length nn, denoted by aa ...
- Java面向对象基础——10.内部类
目录 Java内部类总结 1. 内部类(Inner Class) 2. 匿名类(Anonymous Class) 3. 静态内部类(Static Nested Class) 共性与差异 Java内部类 ...