【芯片前端】auto_testbench的大版本升级——加入简单预期与自动比对

前言

前文提要:

【芯片前端】一键生成简易版本定向RTL验证环境的脚本——auto_verification_rtl脚本_尼德兰的喵的博客-CSDN博客

【芯片前端】可能是定向验证的巅峰之作——auto_testbench_autotestbench_尼德兰的喵的博客-CSDN博客

工具路径:

auto_testbench: 用于自动生成verilog rtl的定向用例仿真平台的脚本

在上次完成自诩为“定向验证的巅峰之作”之后,我觉得这个工具应该是写到头了,不过最近的实践中我发现,对于auto_testbench的主要应用场景——CBB与UT的验证而言,如果能不依赖于方法学进行一些简单预期和比对,还是可以大幅收敛debug时间的。

本次升级针对握手接口(因为好久没写其他类型接口了),脚本的功能概述为:

  1. 对于握手接口单输出的模块,会进行符合协议的输入随机,会自动生成采样与比对task,而根据输入生成预期的task需要手动填充;
  2. 对于不满足单输出的其他握手接口模块,会进行符合协议的输入随机,此时如果想要进行比对需要对环境进行比较大的改动;
  3. 对于其他接口模块,会生成整套验证环境,对接口进行初始化和随机驱动;
  4. 如果不进行仿真只想编译模块,在tb.f中注释掉testbench.sv路径然后在sim路径执行make cmp;

其他优化包括:

  1. 优化了生成的tb.f文件;
  2. 修正了模块中有注释是可能误读的问题;
  3. 美化和对齐了一下生成文件;

效果亲测

作为一个负责人的工具发布者,发布前我先亲自验证了一下这个工具的正确性,于是翻出来了去年写的一个cbb bypass_fifo进行了下验证,然后发现这个cbb有BUG!不过放心,我相信这个cbb是没有在工程中使用的。

bypass_fifo的功能是这样,对于输入的data,如果power为1则正常输出,如果为0则丢弃。这个cbb听起来很奇怪不过其实他是另外一个cbb的一部分(一对多的场景,每个数据可能有不同的通道需要)。那么看下出错的log:

对着log找到波形的错误处:

然后分析下问题不是出现在'h57eadcc1这个数身上,而是出现在前一个数'hb985d7ad,RTL出口没有就把valid和数变了!奇怪的是对于类似的场景,其他的数据在出口时序就很正确:

那么这个问题如果通过波形是否能发现呢?不是太容易:

因此,这个工具的新功能我初步认为是有效的。

使用说明

就以bypass_fifo的验证环境生成为例,看一下如何使用。

第一步还是切换到bypass_fifo的路径,执行:

auto_testbench -f bypass_fifo.v
#如果没有设置全局路径,请完整输入auto_testbench的脚本路径

打印信息为:

##====================================================================##
Gen over! please cd ./bypass_fifo_verification/sim
You need modify ./bypass_fifo_verification/top/testbench.svlike cp ./bypass_fifo_verification_bak/top/testbench.sv ./bypass_fifo_verification/top/
You need modify ./bypass_fifo_verification/cfg/tb.flike cp ./bypass_fifo_verification_bak/cfg/tb.f ./bypass_fifo_verification/cfg/
##====================================================================##

这里说明一下,我的本意是如果已经有bypass_fifo_verification目录了,就把bypass_fifo_verification重命名为bypass_fifo_verification_bak,不过吧脚本写的好像是有点问题导致这个功能时灵时不灵。

第二步,切换到bypass_fifo_verification/cfg路径,打开tb.f文件,并按照需求修改:

+libext+.v
-y /home/ICer/gitee_path/auto_testbench/src/../ver/bypass_fifo_pkg.sv
/home/ICer/gitee_path/auto_testbench/src/bypass_fifo.v
../top/testbench.sv

第三步,切换到bypass_fifo_verification/ver路径,检查bypass_fifo_pkg.sv是否符合预期:

package bypass_fifo_pkg;parameter ERROR_DEBUG_CNT = 5;parameter DEPTH = 8;parameter WIDTH = 128;int error_cnt = 0;bit check_en  = 0;typedef struct{bit [WIDTH -1:0] data_in;bit  data_in_power;} data_in_valid_struct;data_in_valid_struct data_in_valid_bus_q[$];typedef struct{bit [WIDTH -1:0] data_out;} data_out_valid_struct;data_out_valid_struct rm_q[$];data_out_valid_struct data_out_valid_bus_q[$];endpackage

重点说bypass_fifo_pkg文件,在这个文档中脚本根据每个valid信号的名字“推测”其它信号是否为该valid“管辖”的信号,并将结果按valid分组为struct结构。然后顺便把每个数据结构的队列进行声明,如果是输出的valid,那么同时声明reference model的预期队列。因此如果有多路valid输出握手的话,这里的rm声明会重复,需要手动修改。

ERROR_DEBUG_CNT表示发生错误的次数,check_en表示是否进行自动比对默认为0,需要进行比对时手动将这个值改为1。

第四步,切换到bypass_fifo_verification/top路径,打开testbench.sv文件,还是如此的赏心悦目:

其他部分之前都讲过,只需说明下新增的auto_verification部分即可。展开这部分可以看到如下代码:

task in_queue_gain();while(1)begin@(negedge clk);if(data_in_valid && data_in_ready)begindata_in_valid_struct data_in_valid_dat;data_in_valid_dat.data_in = data_in;data_in_valid_dat.data_in_power = data_in_power;data_in_valid_bus_q.push_back(data_in_valid_dat);end//if-end end//while-end 
endtask: in_queue_gain

对输入进行采样,如果有多路输入,会在这个task里均进行采样;

task out_queue_gain();while(1)begin@(negedge clk);if(data_out_valid && data_out_ready)begindata_out_valid_struct data_out_valid_dat;data_out_valid_dat.data_out = data_out;data_out_valid_bus_q.push_back(data_out_valid_dat);end//if-end end//while-end 
endtask: out_queue_gain

对输出进行采样,如果有多路输出,会在这个task里均进行采样;

task rm_queue_gain();data_in_valid_struct data_in_valid_dat;data_out_valid_struct data_out_valid_dat;//while(1)begin//wait(data_in_valid_bus_q.size > 0);//data_in_valid_dat = data_in_valid_bus_q.pop_front();//rm_q.push_back(data_out_valid_dat);//end
endtask: rm_queue_gain

rm_queue_gain是一个空壳task,用于产生预期,里面预置了数据类型和队列操作方法;

task queue_check();while(1)begindata_out_valid_struct rm_data;data_out_valid_struct dual_data;wait(data_out_valid_bus_q.size() > 0);dual_data = data_out_valid_bus_q.pop_front();if(rm_q.size() == 0) begin$display("dual_data = %0p, rm_queue.size = 0", dual_data);error_cnt += 1;endelse beginrm_data = rm_q.pop_front();if(dual_data != rm_data)beginerror_cnt += 1;$display("dual_data(%0p) != rm_data(%0p) at %t", dual_data, rm_data, $realtime);endelse begin//$display("dual_data(%0p) == rm_data(%0p) at %t", dual_data, rm_data, $realtime);endendif(error_cnt >= ERROR_DEBUG_CNT) begin$display("Check Error!!!");$finish;endend
endtask: queue_check

对rm_q[$]和RTL输出接口queue[$]进行自动比对,同样需要注意,如果有多路进行输出,这里只会比对其中一路;

代码的最后是固定的initial函数:

initial beginforkin_queue_gain();out_queue_gain();rm_queue_gain();if(check_en == 1) queue_check();join_none
end

然后是关键点,根据bypass_fifo的功能对rm_queue_gain task进行改写,完成简单的功能预期:

task rm_queue_gain();data_in_valid_struct data_in_valid_dat;data_out_valid_struct data_out_valid_dat;while(1)beginwait(data_in_valid_bus_q.size > 0);data_in_valid_dat = data_in_valid_bus_q.pop_front();if(data_in_valid_dat.data_in_power == 1)begindata_out_valid_dat.data_out = data_in_valid_dat.data_in;rm_q.push_back(data_out_valid_dat);endend
endtask: rm_queue_gain

至此CBB的简单验证环境就完成了。

切换到auto_verification/sim目录,执行:

make run wave=on

之后根据仿真结果和波形进行debug。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/92267.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue.js2+Cesium1.103.0 九、淹没分析效果

Vue.js2Cesium1.103.0 九、淹没分析效果 Demo <template><divid"cesium-container"style"width: 100%; height: 100%;"><spanid"button"style"position: absolute; right: 50px; top: 50px; z-index: 999; font-size: 24px…

Gitlab-第四天-CD到k8s集群的坑

一、.gitlab-ci.yml #CD到k8s集群的 stages: - deploy-test build-image-deploy-test: stage: deploy-test image: bitnami/kubectl:latest # 使用一个包含 kubectl 工具的镜像 tags: - k8s script: - ls -al - kubectl apply -f deployment.yaml # 根据实际情况替换…

SpringBoot请求响应

简单参数 1. 原始方式获取请求参数 Controller方法形参中声明httpServletRequest对象 调用对象的getParameter参数名 RestController public class RequestController {RequestMapping("/simpleParam")public String simpleParam(HttpServletRequest request){Strin…

理解 Go 中的切片:append 操作的深入分析(篇2)

理解 Go 语言中 slice 的性质对于编程非常有益。下面&#xff0c;我将通过代码示例来解释切片在不同函数之间传递并执行 append 操作时的具体表现。 本篇为第 2 篇&#xff0c;当切片的容量 cap 不够时 func main() {// slice1 当前长度为 3&#xff0c;容量大小也为 3slice1 :…

学习笔记整理-面向对象-05-内置对象

一、内置对象 1. 什么是包装类 Number()、String()和Boolean()分别是数字、字符串、布尔值的"包装类"。包装类的目的就是为了让基本类型值可以从它们的构造函数的prototype上获得方法。Number()、String()和Boolean()的实例都是object类型&#xff0c;它们的Primit…

Python是什么?它有什么用途?

Python是什么&#xff1f; Python是一门具有优雅和简洁语法的高级编程语言。它由荷兰程序员Guido van Rossum创造并于上世纪90年代初发布。Python的设计理念强调可读性和清晰性&#xff0c;使得代码编写变得轻松且容易理解。这门语言以其独特的缩进方式来标记代码块&#xff0…

7.利用matlab完成 符号方阵的特征值分解和 符号矩阵的奇异值分解 (matlab程序)

1.简述 &#xff08;1&#xff09;特征值分解&#xff1a;函数eig 格式&#xff1a;[V,D] eig(A) %计算A的特征值对角阵D和特征向量V&#xff0c;使AVVD成立。 注意&#xff1a;特征值分解时&#xff0c;使用eig&#xff0c;矩阵A必须是方阵。 A [0 1;1 1]; [V,D] ei…

【javaweb】学习日记Day1 - HTML CSS入门

目录 一、图片标签 ① 绝对路径 1.绝对磁盘路径 2.绝对网络路径 ② 相对路径 &#xff08;推荐&#xff09; 二、标题标签 三、水平线标签 四、标题样式 1、CSS引入样式 ① 行内样式 ② 内嵌样式 ③ 外嵌样式 2、CSS选择器 ① 元素选择器 ② id选择器 ③…

06 - 文件的差异和恢复

查看所有文章链接&#xff1a;&#xff08;更新中&#xff09;GIT常用场景- 目录 文章目录 1. 文件的差异2. 文件的恢复 工作区&#xff1a;本地进行修改的code 暂存区&#xff1a;执行了 git add <filename> 命令之后 版本库&#xff1a;执行了 git commit <...>…

写给 Android 应用工程师的 Binder 原理剖析

一. 前言 这篇文章我酝酿了很久&#xff0c;参考了很多学习文档&#xff0c;读了很多源码&#xff0c;却依旧不敢下笔。生怕自己理解上还有偏差&#xff0c;对大家造成误解&#xff0c;贻笑大方。又怕自己理解不够透彻&#xff0c;无法用清晰直白的文字准确的表达出 Binder 的…

【量化课程】08_2.深度学习量化策略基础实战

文章目录 1. 深度学习简介2. 常用深度学习模型架构2.1 LSTM 介绍2.2 LSTM在股票预测中的应用 3. 模块分类3.1 卷积层3.2 池化层3.3 全连接层3.4 Dropout层 4. 深度学习模型构建5. 策略实现 1. 深度学习简介 深度学习是模拟人脑进行分析学习的神经网络。 2. 常用深度学习模型架…

金蝶软件实现导入Excel数据分录行信息到单据体分录行中

>>>适合KIS云专业版V16.0|KIS云旗舰版V7.0|K/3 WISE 14.0等版本<<< 金蝶软件中实现[导入Excel数据业务分录行]信息到[金蝶单据体分录]中,在采购订单|采购入库单|销售订单|销售出库单等类型单据中,以少量的必要字段在excel表格中按模板填列好,很方便快捷地从…

学习笔记十四:K8S最小调度单元POD概述

K8S最小调度单元POD概述 k8s核心资源Pod介绍Pod是什么Pod如何管理多个容器Pod网络Pod存储代码自动发版更新收集业务日志 Pod工作方式自主式Pod控制器管理的Pod(防误删除) 如何基于Pod运行应用 k8s核心资源Pod介绍 K8s官方文档&#xff1a;https://kubernetes.io/ K8s中文官方文…

YOLOv5白皮书-第Y6周:模型改进

&#x1f4cc;本周任务&#xff1a;模型改进&#x1f4cc; 注&#xff1a;对yolov5l.yaml文件中的backbone模块和head模块进行改进。 任务结构图&#xff1a; YOLOv5s网络结构图: 原始模型代码&#xff1a; # YOLOv5 v6.0 backbone backbone:# [from, number, module, args]…

【C语言】静态通讯录 -- 详解

一、实现目标 1、功能 保存 1000 个联系人的信息添加联系人删除联系人修改联系人查找联系人排序 2、个人信息&#xff08;结构体&#xff09; 名字年龄性别电话地址 二、创建文件 test.c&#xff08;专门测试通讯录的功能&#xff09;contact.c&#xff08;接口的实现&#xf…

C语言实现三子棋游戏

大家好&#xff0c;欢迎观看Mr.kanglong的CSDN博客&#xff0c;今天和大家讨论的是如何使用C语言来实现三子棋游戏。相信大家儿时或多或少玩过三子棋游戏&#xff0c;那么怎么用C语言实现这样一个游戏呢&#xff1f;且听亢龙娓娓道来~ 目录 三子棋介绍 游戏效果 实现代码 gam…

大语言模型之二 GPT发展史简介

得益于数据、模型结构以及并行算力的发展&#xff0c;大语言模型应用现今呈井喷式发展态势&#xff0c;大语言神经网络模型成为了不可忽视的一项技术。 GPT在自然语言处理NLP任务上取得了突破性的进展&#xff0c;扩散模型已经拥有了成为下一代图像生成模型的代表的潜力&#x…

第三届“赣政杯”网络安全大赛 | 赛宁筑牢安全应急防线

​​为持续强化江西省党政机关网络安全风险防范意识&#xff0c;提高信息化岗位从业人员基础技能&#xff0c;提升应对网络安全风险处置能力。由江西省委网信办、江西省发展改革委主办&#xff0c;江西省大数据中心、国家计算机网络与信息安全管理中心江西分中心承办&#xff0…

Vue在页面输出JSON对象,测试接口可复制使用

效果图&#xff1a; 数据处理前&#xff1a; 数据处理后&#xff1a; 代码实现&#xff1a; HTML: <el-table height"600" :data"tableData" border style"width: 100%" tooltip-effect"dark" size"mini"><el-…

考研 408 | 【计算机网络】 应用层

导图 网络应用模型 客户/服务器&#xff08;c/s&#xff09;模型 P2P模型 DNS 域名 域名服务器 域名解析过程 文件传输协议FTP FTP服务器和用户端 FTP工作原理 电子邮件 电子邮件的信息格式 组成结构 邮件服务器的功能&#xff1a; 1.发送&接收邮件 2.给发件人报告邮…