接前面Quartus Prime Lite小记二,断断续续看了好几天Quaruts基本用法了,在学习Verilog或VHDL之前,应该把git和quartus整合搞定...
回顾
- 编写verilog文件 mytest2.v
- 编写脚本my_setup.tcl
- 运行quartus_sh命令,完成项目创建和编译工作,得到 mytest3.sof文件
在小记二中,我们有了一个 verilog文件 mytest2.v,文件内定义了一个mytest2的模块。
我们写了一个tcl脚本my_setup.tcl
| project_new mytest3 -overwrite
set_global_assignment -name FAMILY "MAX 10"
set_global_assignment -name DEVICE 10M50SAE144C8G
set_global_assignment -name TOP_LEVEL_ENTITY mytest2
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY "output_files"
set_global_assignment -name VERILOG_FILE mytest2.v
set_location_assignment PIN_6 -to x1
set_location_assignment PIN_7 -to x2
set_location_assignment PIN_8 -to f
|
通过执行如下命令创建一个完整工程:
| quartus_sh -t my_setup.tcl
|
得到文件
再执行编译
| quartus_sh --flow compile mytest3
|
即可得到:
那么..., 如何获取git信息,并体现在编译输出的文件名中...
Git基础
Git作为分布式的源码管理工具,没有可以类比SVN的递增值。
| git rev-parse --short HEAD
|
用这个东西肯定是正确的,但是现实中用它,对用户很不友好...,友好的方式可以选择...
- 打上tag,使用describe,可以获取类似 "v1.0-3-gabc123" 的字符串
如果偷懒的话,直接用提交数可以(确保和中央仓库同步),在一些小项目中,这么做比较简单,但是不严谨:
| git rev-list --count HEAD
|
| git log -1 --format=%cd --date=format:%Y%m%d%H%M%S
|
编译过程中执行自定义脚本
quaruts允许配置如下钩子:
PRE_FLOW_SCRIPT_FILE
指定流程开始前要执行的脚本
POST_MODULE_SCRIPT_FILE
指定编译每个阶段执行完执行的脚本(比如map、fit、asm每个阶段执行完的时候)
POST_FLOW_SCRIPT_FILE
指定流程结束后执行的脚本
在.qsf中进行配置,语法如下:
| set_global_assignment -name <assignment name> <executable>:<script name>
|
执行时,quartus会转换成如下命令进行执行
| <executable> -t <script name> <flow or module name> <project name> <revision name>
|
输出git信息
编写一个脚本 get_git_info.tcl:
| # 获取最新提交的哈希值
set commit_hash [exec git rev-parse HEAD]
set commit_count [exec git rev-list --count HEAD]
# 将哈希值写入文件
set file [open "version_info.txt" "w"]
puts $file "$commit_count $commit_hash"
close $file
|
加入到.qsf文件中:
| set_global_assignment -name PRE_FLOW_SCRIPT_FILE quartus_sh:get_git_info.tcl
|
在命令行中,或者在quartus中,执行编译操作,即可得到一个包含版本信息的文件
注意:该文件不会被 quartus_sh --clean
清理。
为了避免脚本在git仓库之外执行,或者git找不到造成崩溃问题,可以调整一下脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | # 尝试获取最新提交的哈希值和提交计数
set commit_hash ""
set commit_count ""
catch {
set commit_hash [exec git rev-parse HEAD]
set commit_count [exec git rev-list --count HEAD]
} err
# 检查是否成功获取了信息
if {$commit_hash eq "" || $commit_count eq ""} {
set commit_hash "unknown"
set commit_count "0"
}
# 将哈希值和计数写入文件
set file [open "version_info.txt" "w"]
puts $file "$commit_count $commit_hash"
close $file
|
这只是一个demo,理论上,我们应该可以将git信息输出到项目文件,或者被verilog或vhdl包含的文件中。进而编译进固件中,并可以被后续上位机读取。
修改sof文件名
没找到如何直接配置sof和pof的文件名,只要写一个tcl脚本,编译结束后,直接拷贝出来,拷贝成我们想要的文件名。
脚本 my_post.tcl:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 | # 定义源文件夹和目标文件夹
set source_folder "output_files"
set target_folder "./"
# 确保目标文件夹存在,如果不存在,则创建
if {![file exists $target_folder]} {
file mkdir $target_folder
}
# 获取Git提交次数
if {[catch {exec git rev-list --count HEAD} git_commit_count]} {
puts "Error getting git commit count: $git_commit_count"
exit 1
}
# 获取最后一次提交的日期,格式为YYYYMMDDHHMMSS
if {[catch {exec git log -1 --format=%cd --date=format:%Y%m%d%H%M%S} git_last_commit_date]} {
puts "Error getting last commit date: $git_last_commit_date"
exit 1
}
# 移除任何可能的双引号
set git_last_commit_date [string map {\" ""} $git_last_commit_date]
# 遍历指定类型的文件
foreach filetype {sof pof} {
set files [glob -nocomplain -directory $source_folder *.$filetype]
foreach file_path $files {
# 获取文件名(不含扩展名)
set filename [file rootname [file tail $file_path]]
# 获取文件扩展名
set extension [file extension $file_path]
# 构造新的文件名
set new_filename "${target_folder}/${filename}_${git_commit_count}_${git_last_commit_date}${extension}"
# 尝试复制文件,捕获并报告任何错误
if {[catch {file copy -force -- $file_path $new_filename} error_message]} {
puts "Error copying file from $file_path to $new_filename: $error_message"
} else {
puts "Successfully copied $file_path to $new_filename"
}
}
}
puts "Operation completed successfully."
|
在 .psf 进行配置:
| set_global_assignment -name POST_FLOW_SCRIPT_FILE quartus_sh:my_post.tcl
|
.gitignore
先记录一个 Git ignore file for quartus II projects · GitHub作为后续参考,后面需要时再调整
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 | # Need to keep all HDL files
# *.vhd
# *.v
# ignore Quartus II generated files
*_generation_script*
*_inst.vhd
*.bak
*.cmp
*.done
*.eqn
*.hex
*.html
*.jdi
*.jpg
# *.mif
*.pin
*.pof
*.ptf.*
*.qar
*.qarlog
*.qws
*.rpt
*.smsg
*.sof
*.sopc_builder
*.summary
*.tcl
*.txt # Explicitly add any text files used
*~
*example*
*sopc_*
# *.sdc # I want those timing files
# ignore Quartus II generated folders
*/db/
*/incremental_db/
*/simulation/
*/timing/
*/testbench/
*/*_sim/
incremental_db/
db/
_output_files/
PLLJ_PLLSPE_INFO.txt
|
禁止更新 .qsf文件
quartus执行时会自动 .qsf文件,这对于源码管控很不友好...
看一下通过GUI界面执行编译时,后台的命令:
| quartus_map --read_settings_files=on --write_settings_files=off mytest3 -c mytest3
quartus_fit --read_settings_files=off --write_settings_files=off mytest3 -c mytest3
quartus_asm --read_settings_files=off --write_settings_files=off mytest3 -c mytest3
quartus_pow --read_settings_files=off --write_settings_files=off mytest3 -c mytest3
quartus_sta mytest3 -c mytest3
|
估计问题出在quartus_sta
上?
先记录一下,后面慢慢了解...
参考