最近在做一个通用设计,需要根据不同的需求产生网表文件供其他人使用。不同参数的组合大概有1200种,如果每中需求都做一个工程并存档,重复工作太多,也很繁琐。忽然想到这种情况很适合使用non-project模式。
面对一个新需求,只需要修改几个参数,输入一行命令,就可以得到结果。同时只保留网表文件和编译信息也非常节省硬盘空间。
以下是TCL脚本的大致结构。
其中run.tcl的内容如下。
source ./define.tcl
source ./procs.tcl
set_param general.maxThreads 8
set topName [lindex [split $TOP {.}] 0]
set topPath ${FSRC}/misc/$TOP
set xdmaBdName [lindex [split $XDMA_BD {.}] 0]
set xdmaBdPath "${FBD}/${xdmaBdName}/${XDMA_BD}"
set udwNameList {"H2C_UDW0" "C2H_UDW0" "H2C_UDW1" "C2H_UDW1"}
set uwewNameList {"H2C_UWEW0" "C2H_UWEW0" "H2C_UWEW1" "C2H_UWEW1"}
foreach udw $UDW_LIST {
set prjName "${topName}_[lindex $udw 0]_[lindex $udw 1]_[lindex $udw 2]_[lindex $udw 3]"
set nameList {}
set valueList {}
for {set i 0} {$i < 4} {incr i} {
# lappend modify a LIST directly, so do not need '$'.
# lindex get a value from a LIST, so need '$'.
lappend nameList [lindex $udwNameList $i]
lappend nameList [lindex $uwewNameList $i]
lappend valueList [lindex $udw $i]
set wewTemp [expr {[lindex $udw $i]/8}]
lappend valueList $wewTemp
}
changeParam "${FSRC}/header/param_def.sv" $nameList $valueList
source ./findAllFiles.tcl
readSrc $FCODE_RECORD
readSrc $FCONS_RECORD
if {[expr {$HAS_BD == "yes"}]} {
read_verilog -library xil_defaultlib ${FBD}/${xdmaBdName}/hdl/${xdmaBdName}_wrapper.v
read_bd $xdmaBdPath
generate_target all [get_files $xdmaBdPath]
}
## Do not use the full path name for '-top' option, just use the top module name
## without extension.
set status [catch {[synth_design -top $topName -part $PART -mode $SYNTH_MODE -directive $SYNTH_DIRECTIVE > ${FLOG}/${prjName}_temp.log]} msg]
if {$status} {
puts $msg
}
pureMsg ${FLOG}/${prjName}
file delete ${FLOG}/${prjName}_temp.log
write_checkpoint -force ${FDCP}/$prjName
report_timing_summary -file ${FRPT}/${prjName}.rpt
close_project
}
编译过程中总是报如下错误,提示Block design中的IP被锁定。
重新生成Block design也未能解决问题。后来在ug939中看到这么一段话。
在non-project模式下,如果不创建im-memory工程,IP将会使用默认的器件产生输出文件。当该默认器件和synth_design使用的器件不同时,就会报以上的错误。在run.tcl中创建in-memory工程或者直接使用个set_part设置器件即可解决该问题。如添加以下命令。
create_project -in_memory -ip -part $PART xdma_inf_prj ./
如果不想创建in-memory工程也可以,使用set_part命令即可,该命令的说明如下。
Sets the part on the current project. If no project is open, then a diskless project is created.
如果之前未创建工程,set_part会创建一个diskless,也就是in-memory的工程。
知乎连接:
https://zhuanlan.zhihu.com/p/601792515