数字asic流程实验(EX)VCS+Verdi前仿真&后仿真
数字asic流程实验(EX)VCS+Verdi前仿真&后仿真
1. 前言
写数字asic流程实验系列博客已经过去一年多了,现在也算结束了纯小白的状态,稍微有了一些数字前端开发经验。在老的系列教程里面用的前仿后仿工具还是modelsim,实际上业界主流工具还是功能更强大的VCS和Verdi。两个也都是synopsys家的工具,VCS是编译器,Verdi是波形查看工具。为什么主流会是这两个工具我就不去复读了,网上有很多解释,而且确实功能强大,谁用过谁知道。我自己切换到VCS+Verdi上做完两次数字设计了,这里share一下一些开发经验。
2. 前仿真
还是使用cic_filter的那个case。先来一个小插曲,那份代码最后梳状器的部分的逻辑有点问题,存在竞争冒险,后仿真出来的波形有毛刺就是因为这个原因。如果直接用原来的代码的话虽然modelsim里面能把波形仿出来,VCS里面却是不行的,所以我插了一级寄存器来处理,修改后的代码为:
module cic_filter(
input clk,
input rst_n,
input in,
output [18:0] out
);
reg [18:0]out_reg;
wire clk_div;
reg [18:0]sum1,sum2,sum3;
wire [18:0]sum1_nxt,sum2_nxt,sum3_nxt;
assign sum1_nxt = sum1 + in;
assign sum2_nxt = sum2 + sum1;
assign sum3_nxt = sum3 + sum2;
always @(posedge clk or negedge rst_n) begin
if (rst_n == 0) begin
sum1 <= 19'b0;
sum2 <= 19'b0;
sum3 <= 19'b0;
end
else begin
sum1 <= sum1_nxt;
sum2 <= sum2_nxt;
sum3 <= sum3_nxt;
end
end
divider div(
.clk(clk),
.rst_n(rst_n),
.clk_div(clk_div)
);
reg [18:0]sub1,sub2,sub3;
reg [18:0]sub1_nxt,sub2_nxt,sub3_nxt;
always @(posedge clk_div or negedge rst_n) begin
if (rst_n == 0) begin
sub1_nxt <= 19'b0;
sub2_nxt <= 19'b0;
sub3_nxt <= 19'b0;
end
else begin
sub1_nxt <= sum3_nxt - sub1;
sub2_nxt <= sub1_nxt - sub2;
sub3_nxt <= sub2_nxt - sub3;
end
end
always @(posedge clk_div or negedge rst_n) begin
if (rst_n == 0) begin
sub1 <= 19'b0;
sub2 <= 19'b0;
sub3 <= 19'b0;
end
else begin
sub1 <= sum3_nxt;
sub2 <= sub1_nxt;
sub3 <= sub2_nxt;
end
end
always @(posedge clk_div or negedge rst_n) begin
if (rst_n == 0) begin
out_reg <= 0;
end
else begin
out_reg <= sub3_nxt;
end
end
assign out = out_reg;
endmodule
VCS分成编译(compile)和仿真(simulation)两步,编译步骤会把verilog代码编译到可执行文件,仿真步骤会执行编译步骤输出的可执行文件。由于VCS的调用命令相对复杂,这里写了一个makefile的脚本:
.PHONY:vcs_com vcs_sim verdi
OUTPUT = cic_filter
TIMESCALE = 1ns/1ns
#start vcs compile
vcs_com:
cd ../vcs && vcs -full64 +v2k -debug_pp -timescale=${TIMESCALE} -cpp g++ -cc gcc -LDFLAGS -no-pie -LDFLAGS -Wl,--no-as-needed -CFLAGS -fPIE -fsdb -f file_list.f -o ${OUTPUT} -l compile.log
#start vcs sim
vcs_sim:
cd ../vcs && ./${OUTPUT} -l sim.log
#start verdi
verdi:
cd ../verdi && verdi -f ../vcs/file_list.f -ssf ../vcs/tb_${OUTPUT}.fsdb
脚本里OUTPUT和TIMESCALE两个变量可以根据自己的情况来修改。为了简化输入,这里读取文件使用了file_list.f这个文件来标记所有设计文件的路径:
//Macro define
+define+FSDB
// Source
../src/cic_filter.v
../src/divider64.v
// Netlist
//../icc/outputs/cic_filter_post_layout.v
// Library
//../lib/verilog/smic18.v
// Testbench
../tb/tb_cic_filter.v
在前仿真时保留Source和Testbench下的内容即可,Netlist和Library下的内容无关,直接注释掉。
testbench也针对VCS和Verdi的工具需求做了一下修改,主要是Verdi要吃fsdb文件(记录了信号波形),所以要用Dump命令把信号抽取出来。最后还有一段吃sdf文件来跑后仿真的代码,在前仿真时可以把post_sim的宏定义给注释掉,另外因为VCS仿真的结束需要在testbench里面控制,在initial块中记得加入$finish命令,否则到了vcs_sim那一步会一直卡住:
`define period 78.125
module testbench;
// input
reg clk,rst_n,in;
// output
wire [18:0]out;
// 设置时钟周期为156.25ns
always #`period clk <= ~clk;
// 初始化
initial begin
rst_n <= 1'b0;
clk <= 1'b0;
#500;
rst_n <= 1'b1;
#(10*12800*`period);
$finish;
end
integer i;
// 定义存储器mem
reg mem[0:3000000];
// 将1k1000mv.txt文件读入mem
initial $readmemb("../src/1k1000mv.txt",mem);
// 将mem中数据次序输出到in
always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
i = 0;
in <= 0;
end
else begin
in <= mem[i];
i = i + 1;
end
end
// 调用cic滤波器
cic_filter cic(
.clk(clk),
.rst_n(rst_n),
.in(in),
.out(out)
);
`ifdef FSDB
initial begin
$fsdbDumpfile("tb_cic_filter.fsdb");
$fsdbDumpvars;
$fsdbDumpMDA();
end
`endif
//`define post_sim
`ifdef post_sim
// sdf
initial begin
$sdf_annotate("../icc/outputs/cic_filter_post_layout.sdf", cic);
end
`endif
endmodule
我的路径处理上,将makefile放到了新创建的和src以及tb(testbench专门摆到这个里面来)平级的prj目录里,再平级创建一个vcs文件夹和一个verdi文件夹分别作为vcs和verdi的执行目录。运行整个脚本需要到达prj目录下,执行三步shell命令

make vcs_com
make vcs_sim
make verdi
执行每步命令后都可以看一下工具的输出,如果有报错就处理一下然后再重复步骤即可。Verdi内部可以读取代码,并直接选中要观察的变量,右键Add to waveform加到波形监视窗口。也可以在Instance中选中要观察的Instance,右键Add to waveform将其所有端口信号加到波形监视窗口。

至此前仿真结束。
3. 后仿真
后仿真的步骤很简单,首先修改一下file_list.f,改成吃网表和单元库:
//Macro define
+define+FSDB
// Source
//../src/cic_filter.v
//../src/divider64.v
// Netlist
../icc/outputs/cic_filter_post_layout.v
// Library
../lib/verilog/smic18.v
// Testbench
../tb/tb_cic_filter.v
其次取消testbench中对post_sim宏定义的注释,使得仿真时能够吃到sdf文件来反标延时信息。然后还是那三步shell命令即可:
`define period 78.125
module testbench;
// input
reg clk,rst_n,in;
// output
wire [18:0]out;
// 设置时钟周期为156.25ns
always #`period clk <= ~clk;
// 初始化
initial begin
rst_n <= 1'b0;
clk <= 1'b0;
#500;
rst_n <= 1'b1;
#(10*12800*`period);
$finish;
end
integer i;
// 定义存储器mem
reg mem[0:3000000];
// 将1k1000mv.txt文件读入mem
initial $readmemb("../src/1k1000mv.txt",mem);
// 将mem中数据次序输出到in
always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
i = 0;
in <= 0;
end
else begin
in <= mem[i];
i = i + 1;
end
end
// 调用cic滤波器
cic_filter cic(
.clk(clk),
.rst_n(rst_n),
.in(in),
.out(out)
);
`ifdef FSDB
initial begin
$fsdbDumpfile("tb_cic_filter.fsdb");
$fsdbDumpvars;
$fsdbDumpMDA();
end
`endif
`define post_sim
`ifdef post_sim
// sdf
initial begin
$sdf_annotate("../icc/outputs/cic_filter_post_layout.sdf", cic);
end
`endif
endmodule

实验文件我就不再打包上传了,所需的代码/脚本上面都已经有了。
数字asic流程实验(EX)VCS+Verdi前仿真&后仿真的更多相关文章
- FPGA前仿真后仿真
前仿真 后仿真 时序(综合后)仿真 时序仿真将时延考虑进去,包括综合后产生的(与.或.非)门时延,还有布局布线产生的时延. 综合(Synthesize),就是将HDL语言设计输入翻译成由与.或.非门和 ...
- 【转】Verilog HDL常用建模方式——《Verilog与数字ASIC设计基础》读书笔记(四)
Verilog HDL常用建模方式——<Verilog与数字ASIC设计基础>读书笔记(四) Verilog HDL的基本功能之一是描述可综合的硬件逻辑电路.所谓综合(Synthesis) ...
- 转:Modelsim和Vcs+Verdi使用技巧(Linux)
Modelsim脚本自动仿真 1.创建文件 run.do,"#"为注释符号 quit -sim #退出上次仿真 .main clear #清除上次仿真所有文件以及打印信息 vlib ...
- 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率
隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...
- try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后?
这是一道面试题,首先finally{}里面的code肯定是会执行的,至于在return前还是后, 看答案说的是在return后执行,我觉得不对,百度了一下,有说return前的,有说return后的, ...
- 腾讯云图片鉴黄集成到C# SQL Server 怎么在分页获取数据的同时获取到总记录数 sqlserver 操作数据表语句模板 .NET MVC后台发送post请求 百度api查询多个地址的经纬度的问题 try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后? js获取某个日期
腾讯云图片鉴黄集成到C# 官方文档:https://cloud.tencent.com/document/product/641/12422 请求官方API及签名的生成代码如下: public c ...
- 探究C语言中的前++和后++
小波带您探究c语言中的前++与后++: 欢迎吐槽,欢迎加QQ463431476. 欢迎关注! 现在来探究: 咱们先看第一个 i被赋值0,i++(后++)并没有输出1. 现在i被赋值0,++i,也 ...
- HMM 自学教程(七)前向后向算法
本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在 HMM 学习最佳范例,这是针对 国外网站上一个 HMM 教程 的翻译,作者功底很深,翻译得很精彩 ...
- STL——前闭后开区间表示法和function call 操作符
前开后闭开区间表示法[) 任何一个STL算法,都需要获得由一对迭代器(泛型指针)所标示的区间,用以表示操作范围,这一对迭代器所标示的是个所谓的前闭后开区间,以[first,last)表示,也就是说,整 ...
- HMM 前向后向算法(转)
最近研究NLP颇感兴趣,但由于比较懒,所以只好找来网上别人的比较好的博客,备份一下,也方便自己以后方便查找(其实,一般是不会再回过头来看的,嘿嘿 -_-!!) 代码自己重新写了一遍,所以就不把原文代码 ...
随机推荐
- 网页实现ping效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- leetcode1404
简介 简单的模拟二进制的加减法 code class Solution1404 { public: int numSteps(string s) { int n = s.size(); int cou ...
- qt 中文字乱码的处理方法 5.12+
简介 以前遇到这种问题 大规模 面向百度 很耗费时间特此记录 example code QString text(u8"<h2>BMesh 实现</h2>" ...
- 面试官:谈谈你AI项目的具体实现?
在如今比较卷的 Java 面试市场,会 AI 技术是比较吃香的,它也可以作为一个技术或项目亮点,帮你拿到更多的面试机会,当然,也会帮你大大的提升面试的通过率. 但是在面试的过程中,如何展现你的 AI ...
- GraphQL类型系统如何让FastAPI开发更高效?
扫描二维码 关注或者微信搜一搜:编程智域 前端至全栈交流与成长 发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/ 1. GraphQL类型系统基础 ...
- C-Kermit AND C-Kermit for Android
C-KERMIT 10.0 TUTORIAL https://www.kermitproject.org/ck10tutor.html#commands In the present age of g ...
- 一次完整的通话过程SIP报文分析
场景: 主叫方(1004,Yate客户端,端口号:52110) -> 通过FreeSWITCH(端口号:5070)呼叫 -> 被叫方(1000,ZoIPer客户端,端口号:5070) 被叫 ...
- 微信小程序SSL证书必须使用吗?
开发微信小程序,想要在微信上真正运行起来,除了要买服务器.域名以外,最重要的就是需要使用SSL证书,微信小程序平台为保证数据传输安全,提高业务安全性,公众平台不再支持http方式调用,强制要求所有需上 ...
- 浅谈C++ const
引入 分别考虑以下代码: #include <bits/stdc++.h> int main() { const int a = 1; const_cast<int &> ...
- DeepCompare文件深度对比软件:智能文本对比与差异统计功能完全指南
DeepCompare文件深度对比软件:智能文本对比与差异统计功能完全指南 智能文本对比功能详解 DeepCompare文件深度对比软件的智能文本对比功能是其核心特色之一,采用先进的对比算法能够精准识 ...