第18篇 :深入剖析systemverilog中 randomize 失败案例启示录(二)

今天我们继续修改之前的例子,你会有意想不到的收获。程序源代码,和上一节文章一样。

症状3:

这里,我们没有显式调用类的randomize() 函数,而是定义了一个类函数。在函数中 ,重新约束了类内的随机变量。请看如下代码:

`timescale 1ns/1ps 
`include "uvm_macros.svh"
import uvm_pkg::*;class my_obj1 extends uvm_test;`uvm_component_utils(my_obj1)rand int  src=4;rand int dst;constraint dst_c {dst inside {[7:9]};}rand bit [3:0]  crc = 4'b0111;constraint crc_c {crc inside {5,6,7,8};}function new(string name = "my_obj1" , uvm_component parent = null );super.new(name, parent);endfunction // newextern virtual function print ();extern virtual function pure_print ();virtual task run_phase(uvm_phase phase);super.run_phase(phase);endtask endclass //function my_obj1::print();randomize (src)   with {(src) inside {[5:5]};} ;  // 新增代码,意图重新约束src变量`uvm_info(get_type_name(),$psprintf("%0h,%0h,%0h",src,dst,crc),UVM_LOW)
endfunctionfunction my_obj1::pure_print();`uvm_info(get_type_name(),$psprintf("%0h,%0h,%0h",src,dst,crc),UVM_LOW)
endfunction
//module tb();import uvm_pkg::*;
`include "uvm_macros.svh"initial beginrun_test("my_obj1");endendmodule // tb

运行仿真代码,得到如下仿真结果: dst 结果为0, 也即是声明初始化的初始化值; 而且仿真抛出异常Error-

奇怪? 为什么没有进行预期[7:9]的随机取值呢?而且,我们明明是在调用randomize(src) 进行随机src 变量,为什么报错的是 dst 变量呢?

 源代码修改:

修改前:

    randomize (src)   with {(src) inside {[5:5]};} ;

修改后方案A: 

    std::randomize (src)   with {(src) inside {[5:5]};} ;

修改后的仿真结果:符合预期。 

 修改后方案B: 增加this.randomize() 的类函数显式调用,并保持程序源代码其它一致。

仿真结果: PASS。 通过增加 this.randomize() 的调用,其它代码均没有改变。我们得到预期的仿真结果。这里为什么?因为:首先如前面文章讲述,经过显式randomize() 调用之后,dst 的取值为8;后执行     randomize (src)   with {(src) inside {[5:5]};} ;   时候,会重新对 randomize() 的所有对象进行随机求解,此时 dst = 8, 在 【7:9】范围之内,所有不会报错。最后,经过此次随机,只会更改 src 的数值。

分析3: 

(1)其实,这里我们犯了一个错误,在systemverilog 标准语法说中,从头至尾没有提到: randomize (src)   with {(src) inside {[5:5]};} ; 该随机化方式。也即是:通过调用类的内置函数 randomize(xxx) with {},可以去单独随机类中的某一个变量。

(2)所以,我们很自然想到一种解决办法,那就是调用 systemverilog 的内置 std::randomize() with 的方式,去随机特定某一个变量。这样做,仿真预期,没有发生错误。

(3)再分析:为什么我们调用的是 randmozie(src), 而报错的是 dst 求解失败呢?

         答: 这里虽然是对src变量特定去随机,但是求解器,内部还是会对类的所有随机变量进行求解评估的。如果某些变量求解失败,会抛出异常错误的。

         这个问题是关于SystemVerilog中的约束随机化。在你的代码中,你尝试对src进行随机化,但是报错是关于dst的约束求解失败。

         出现这个错误的原因可能是在my_obj1类的实例化或随机化过程中,dst的约束dst_cdst的初始值或其他约束产生了冲突。SystemVerilog的约束求解器试图满足所有约束,但当它不能满足所有约束时,就会报错。

         在你的代码中,dst的约束dst_c要求其值在7到9之间,但如果dst的初始值0(在你的代码中未显示)不在这个范围内,或者在随机化过程中其他约束改变了dst的值并使其超出了这个范围,那么约束求解器就会失败。

(4)再分析:针对增加 this.randomize()的方案,在最后一次 randomize(src)的时候,返回结果并没有更新 dst.。说明:randmoize(xxx) with {} 还是可以针对某一随机变量进行随机化操作的。这里与(1)描述似乎存在矛盾,而又不矛盾。

(5)另外,需要注意:这里我们发现 dst 的两次随机,结果没有发生更改。 因为:调用randomize(src)的时候,只会评估dst 的约束求解,并不会更改上一次的随机值。

症状4:

我们在源代码基础之上,修改如下代码:增加对 src 随机变量的 constraint 块约束。

`timescale 1ns/1ps 
`include "uvm_macros.svh"
import uvm_pkg::*;class my_obj1 extends uvm_test;`uvm_component_utils(my_obj1)rand int  src=4;constraint src_c {src inside {[0:3]};}rand int dst=0;constraint dst_c {dst inside {[7:9]};}rand bit [3:0]  crc = 4'b0111;constraint crc_c {crc inside {5,6,7,8};}function new(string name = "my_obj1" , uvm_component parent = null );super.new(name, parent); endfunction // newextern virtual function print ();extern virtual function pure_print ();virtual task run_phase(uvm_phase phase);super.run_phase(phase);this.print();endtask endclass //function my_obj1::print();randomize (src)   with {(src) inside {[5:5]};} ;`uvm_info(get_type_name(),$psprintf("%0h,%0h,%0h",src,dst,crc),UVM_LOW)
endfunctionfunction my_obj1::pure_print();`uvm_info(get_type_name(),$psprintf("%0h,%0h,%0h",src,dst,crc),UVM_LOW)
endfunction
//module tb();import uvm_pkg::*;
`include "uvm_macros.svh"initial beginrun_test("my_obj1");endendmodule // tb

聪明的朋友们,对于上面的错误,相比大家都已经很清楚了。因为本篇内容的症状3已经做了分析。

但是,我们还是想做点什么。 

修改后:

 分析4:

通过增加this.randomzie(),  仿真可以跑通。这里不过多解释。我们想知道,为什么会发生冲突呢?

这个问题是因为SystemVerilog中的约束随机化的时候,会对相应随机变量的所有牵连约束,进行综合考量。如下三处之间产生了冲突。

第一处:

   rand int  src=4;

第二处:
   constraint src_c {
      src inside {[0:3]};
   }

第三处:

   randomize (src)   with {(src) inside {[5:5]};} ;

所以,我们不要认为:后面的约束会覆盖前面的约束。也即是:第三处约束,会覆盖第二处的约束。这是错误的认识。 覆盖的问题,我们稍后讲解。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

CC音乐 1.0 | 纯净版音乐软件,内置3条音源,支持无损和母带下载

CC音乐是一款全新上架的第三方音乐软件,界面纯净简洁且无广告。内置三条音源接口,用户可以畅听全网音乐。软件涵盖了电台、排行榜、歌单分类、视频、歌手等多个栏目,即使是会员和灰色歌曲也能随意畅听。此外,CC音乐还支持下载无损…

【销帮帮-注册_登录安全分析报告-试用页面存在安全隐患】

联通支付注册/登录安全分析报告 前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨…

windows中docker安装redis和redisinsight记录

创建一个Redis运行容器,命令如下 docker run -it -d --name redis -p 6379:6379 redis --bind 0.0.0.0 --protected-mode no -d 代表Redis容器后台运行 --name redis 给创建好的容器起名叫redis -p 6379:6379 将容器的6379端口映射到宿主机的6379端口,注…

问题排查:C++ exception with description “getrandom“ thrown in the test body

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 MotivationProcess Motivation 最近在做一个复杂系统集成到 Bazel 的工作。 在编译…

C++中类的默认成员函数

默认成员函数 1.构造函数2.析构函数3.拷贝构造函数4.赋值运算符重载4.1运算符重载4.2赋值运算符重载 #mermaid-svg-oipiwg9stvONvYK0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-oipiwg9stvONvYK0 .error-icon{f…

从0开始学习机器学习--Day20--优化算法的思路

确定执行的优先级(Prioritizing what to work on : Spam classification example) 在建立学习系统前,我们不仅要梳理框架,更重要的是我们要弄清楚有哪些事情是要优先做的,这可以帮我们节约大量的时间。 以垃圾邮件为例,按照之前…

利用JS实现图片轮播(示例)

我们平时在逛购物网站的时候会看到页面内的商品图片自动轮播,二要想实现着中效果应该如何做呢?下面详细讲解代码的运用,实现下面视频的效果。大家也可以自己试试看,或者复制最后的完整代码运行一下! 图片自动轮播效果 …

关于99.9% 达成读码率方案

1.标签样式 2.尺寸大小 长30mm*宽30mm 至 长40mm*宽40mm ; 3.位置 标签位置在箱体中间,可以误差5mm; 4.质量要求 ①无遮挡,标签不允许任何介质在上面,尤其是塑料片 ②平整,必须和箱子壁贴平,不允许翻边,飘荡。 ③码不能有模糊,手机摄像头扫码可以…

w~视觉~合集20~SAM

我自己的原文哦~ https://blog.51cto.com/whaosoft/12500982 #SAM 今天,Meta发布史上首个图像分割基础模型SAM,将NLP领域的prompt范式引进CV,让模型可以通过prompt一键抠图。网友直呼:CV不存在了! 就在刚刚,Meta AI…

三、直流有刷电机H桥驱动原理

1、H桥简介 H桥驱动电路:是一种用于控制直流电机正反转及速度的电路,其名称来源于其电路结构类似于字母“H”。H桥驱动电路由四个开关元件(如晶体管、MOSFET等)组成,这些开关元件被配置成可以控制电机两端电流的方向&…

Leetcode刷题

题目如下: 这道题呢,这里我写出了两种解决办法,一种遍历链表来得出中间结点,一种通过快慢指针来得出中间结点 第一种: 遍历: 首先我们设置一个计数器count,来记录链表的长度,写一…

游戏开发--C#面试题

游戏开发--C#面试题 C#1. 值类型和引用类型的区别2. 重载和重写的区别3. ArrayList和List的区别4. List底层是什么实现的?5. 抽象类和接口的区别6. 静态成员和⾮静态成员的区别7. 装箱和拆箱是指什么?8. 值和引用类型在变量赋值时的区别是什么&#xff1…

# 设置ubuntu为中文后,如何保留用户家目录等文件夹名为英文

设置ubuntu为中文后,如何保留用户家目录等文件夹名为英文 一、问题描述: 当我们安装完ubuntu系统后,通过【系统设置】,在【语言支持】里,设置为【汉语(中国)】,这时在终端中显示文…

STM32—独立看门狗(IWDG)和窗口看门狗(WWDG)

概述: WDG(Watchdog) 看门狗,看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能计时复位程序,避免程序陷入长时间的罢工状态,保证系…

Chrome与火狐哪个浏览器的性能表现更好

在数字时代,浏览器是我们日常生活中不可或缺的工具。无论是工作、学习还是娱乐,一个好的浏览器都能显著提高我们的效率和体验。市场上有许多优秀的浏览器,其中Google Chrome和Mozilla Firefox无疑是最受欢迎的两款。本文将比较这两款浏览器的…

现在国内优秀的广告联盟有哪些?

广告联盟是网络广告效果营销的主流方式之一,广告联盟的变现方式多种多样,主要有以下四种 CPA:按照下载或者注册进行付费(软件平台或游戏试玩平台)CPS:按照成交进行付费(淘宝客)CPM&…

机器学习,生成式AI ,LLM大模型,人工智能,他们之间的关系是什么?有什么不同?

这些概念都是现代计算机科学和人工智能领域的重要组成部分,它们之间既有联系,也有区别。以下是它们的关系和不同之处: 人工智能 (AI) 两个回答 人工智能是一个广义的概念,指的是计算机系统能够执行通常需要人类智能才能完成的任务…

[全网最细数据结构完整版]第七篇:3分钟带你吃透队列

目录 1->队列的概念及结构 2->队列的实现 2.1定义队列基本结构 struct QueueNode 和 struct Queue 2.2队列初始化函数 QueueInit 函数 2.3队列销毁函数 QueueDestroy 函数 2.4队列插入数据函数 QueuePush 函数 2.5判断队列是否为空,空返回true,非空返回false 2.6队列删…

点阵数显驱动IC数显LED驱动芯片VK1651

产品品牌:永嘉微电/VINKA 产品型号:VK1651 封装形式:SOP16 产品年份:新年份 产品简介:VK1651是一种带键盘扫描电路接口的 LED 驱动控制专用芯片,内部集成有数据锁存器、LED 驱动、键盘扫描等电路。SEG脚…

【进阶】java基础之集合(2)数据结构<树>

文章目录 二叉树的内部结构二叉查找树平衡二叉树平衡二叉树的旋转机制 二叉树的内部结构 二叉查找树 二叉查找树,又称二叉排序树或者二叉搜索树 特点: 每一个节点上最多有两个子节点任意节点左子树上的值都小于当前节点任意节点右子树上的值都大于当前节点 二叉…