记录几个SystemVerilog的语法——随机

1. 随机稳定性(random stability)

随机稳定性是指每个线程(thread)或对象(object)的random number generator(RNG)是私有的,一个线程返回的随机值序列与其他线程或对象的RNG是无关的。随机稳定性适用于以下情况:

  • 系统随机方法调用:$urandom()和$urandom_range();
  • 对象和进程设置种子方法:srandom();
  • 对象随机化方法:randomize();

在用户代码发生小改动时,Testbench带有这个特性就可以有更稳定的RNG行为。另外,可以通过手动调整线程和对象的seed,这样就可以更精确控制随机值的产生。

随机稳定性包含以下特性:

  • Initialization RNG(初始化RNG):每个module例化、interface例化、program例化和package都有一个初始化RNG。每一个初始化RNG都有默认的seed,它的值实现定义。一个初始化RNG用于创建静态进程和静态初始化器(initializer)。
  • Thread stability(线程稳定性):每一个线程都有一个独立的RNG,该线程中调用随机化的所有系统都会使用这个RNG。当一个新的动态线程创建时,它RNG的seed值是从parent线程生成的下一次随机值,该方式称为hierarchical seeding。对于一个静态进程创建时,它RNG的seed值是从声明该进程的初始化RNG (来自module instance、interface instance、program instance或者package)的下一个随机值来的。程序和线程的随机稳定性可以通过保持之前创建线程和RNG的顺序一致即可。当给现存testcase增加新的线程时,可以加在代码块的末尾,这样来保持之前创建流程的随机数稳定性。
  • Object stability(对象稳定性):每一个类的例化(object)都有一个独立的RNG,用于该类内部所有随机化方法。当一个object创建时,它RNG的seed是来源于创建该object的线程。当一个object是被静态初始化器创建时,它RNG的seed将会来源于该初始化RNG(来自module instance、interface instance、program instance或者package)的下一个随机值,因为这时候没有active线程提供seed的。对象稳定性可以通过保持之前创建object和RNG的顺序一致即可。为了保持RNG稳定性,新objects、线程和随机数的创建应该在现存objects创建之后进行。
  • Manual seeding(手动设置种子):所有没有初始化的RNGs可以手动设置seed。结合hierarchical seeding,该机制可以用于在一个subsystem的root thread定义一个简单seed,然后这个seed会作用到整个subsystem的运行。

2. 线程稳定性(Thread stability)例子

$urandom系统调用返回的随机值与线程执行顺序无关。如下例子:

integer x, y, z;forkbeginprocess::self.srandom(100);  // set a seed at the start of a threadx = $urandom;endbeginy = $urandom;process::self.srandom(200);  // set a seed during a threadendbeginz = $urandom + $urandom ;  // draw 2 values from the thread RNGendjoin

上述程序片段演示了一下几个特性:

  • Thread locality(线程局部性):x、y和z的返回值与线程的执行顺序无关。这是一个很重要的特性,因为它允许开发独立、可控和可预测的子系统;
  • Hierarchical seeding(分层设置种子):在创建线程时,将使用父线程的下一个随机值作为种子初始化它的随机状态。因此,这三个fork引起的线程都是从父线程中得到种子的;

每个线程都有一个唯一的种子值,仅由其父线程决定。线程执行的根(root)决定了它的子节点随机种子。这就允许设置根线程来自动和保留子节点线程的行为。

3. 对象稳定性(Object stability)例子

每个类中内置的randomize()可以确保对象的稳定性,这使得在一个实例中调用randomize()独立于其它实例中调用randomize(),并且独立于调用其它randomize()函数。例如:

class C1;rand integer x;endclassclass C2;rand integer y;endclassinitial beginC1 c1 = new();C2 c2 = new();integer z;void'(c1.randomize());// z = $random;void'(c2.randomize());end
  • c1.x和c2.x返回的值是互相独立的;
  • randomize()的调用是独立于$random系统调用。如果没有注释掉上述z=$random,那么分配给c1.x和c2.y的值也不会发生变化;
  • 每个实例都有一个可以独立设置种子的唯一的随机值源。该随机种子可以从父线程创建实例时获取;
  • Object可以在任何时候使用srandom()方法进行设置种子;
class C3function new (integer seed);//set a new seed for this instancethis.srandom(seed);endfunctionendclass

一旦对象被创建,就不能保证创建该对象的线程可以在另一个线程访问该对象之前更改该对象的随机状态。因此,对象最好从它们内部new()构造函数而不是从外部进行自我设置种子。

一个object的seed可以在任何线程里面改变。但是一个线程的seed只能在线程内部修改的。

4. 手动进行随机化设置例子

每个对象都维护自己内部的RNG,该RNG仅由其randomize()方法调用。这就允许对象独立于其它对象和调用其它系统随机化函数进行随机化。当一个对象被创建时,它的RNG将使用创建该对象的线程的RNG中的下一个值作为种子,这个过程称为分层对象设置种子(hierarchical object seeding)。

有时需要使用srandom()方法手动设置对象RNG的种子,这可以在类方法中完成,也可以在类定义外部完成。一个在类内部设置RNG种子的例子为:

class Packet;rand bit[15:0] header;...function new (int seed);this.srandom(seed);...endfunctionendclass

从外部设置RNG种子的例子为:

Packet p = new(200); // Create p with seed 200.p.srandom(300);  // Re-seed p with seed 300.

在对象的new()函数中调用srandom()确保对象的RNG在任何类成员值随机化之前使用新设置的种子。在类方法内部设置会比较靠谱点。

5. 唯一性约束(uniqueness constraints)

可以使用unique关键字来约束一组变量的随机值,使得该组变量再随机之后,任何两个变量的值都不一样。能使用该特性的变量类型有整型scalar变量、整型unpacked数组变量的一个leaf element或一片(slice) leaf element或全部leaf element。Leaf element指的是unpacked数组变量拆解到最末尾非unpacked数组类型。例子如下:

rand byte a[5];rand byte b;rand byte excluded;constraint u { unique {b, a[2:3], excluded}; }constraint exclusion { excluded == 5; }

这上述这个例子中,a[2], a[3], b和excluded变量的值在随机之后将会都不一样。因为在exclusion 块中excluded被约束为5,所以a[2], a[3]和b的值将都不会是5。

6. 迭代约束(iterative constraints)

迭代约束允许数组变量使用循环变量、索引表达式或数组缩减法(array reduction methods)去约束。Foreach迭代约束语法如下:

foreach ( ps_or_hierarchical_array_identifier [ loop_variables ] ) constraint_setloop_variables ::= [ index_variable_identifier ] { , [ index_variable_identifier ] }

例子如下:

class C;rand byte A[] ;constraint C1 { foreach ( A [ i ] ) A[i] inside {2,4,8,16}; }constraint C2 { foreach ( A [ j ] ) A[j] > 2 * j; }endclass

C1块约束了A的每个约束在{2,4,8,16},C2块约束了A的每个元素值大于它index的两倍。

循环变量与数组索引之间的映射是由维度的基数所决定的,如下所示:

//     1   2  3          3     4      1   2    -> Dimension numbersint A [2][3][4];    bit [3:0][2:1] B [5:1][4];foreach( A [ i, j, k ] ) ...foreach( B [ q, r, , s ] ) ...

第一个foreach会使i从0到1迭代,j从0到2迭代,k从0到3迭代。第二个foreach会使q从5到1迭代,r从0到3迭代,s从2到1迭代。

对于动态数组和队列来说,数组大小也可以被约束的,如果数组大小约束和迭代约束同时发生,那么会先求解数组大小约束,然后求解迭代约束。还有一个就是要防止迭代超出数组大小,用户必须自己排除这些无效的索引。比如下面例子的k<A.size-1就是防止数组索引溢出。

class C;rand int A[] ;constraint c1 { A.size inside {[1:10]}; }constraint c2 { foreach ( A[ k ] ) (k < A.size - 1) -> A[k + 1] > A[k]; }endclass

数组缩减法可以根据unpacked数组的元素值产生一个整型值,如:

class C;rand bit [7:0] A[] ;constraint c1 { A.size == 5; }constraint c2 { A.sum() with (int'(item)) < 1000; }endclass

c2约束块将会翻译成:

( int'(A[0])+int'(A[1])+int'(A[2])+int'(A[3])+int'(A[4]) ) < 1000

7. soft约束

与soft约束相对立的是hard约束,求解器solver必须要满足hard约束,否则solver求解失败。Soft约束可以被其它hard约束块或更高优先级的soft约束块覆盖掉,因此,soft约束通常用于给随机变量指定默认值或分布。

Soft约束之所以可以被其它soft约束覆盖掉,是因为soft约束之间有不同的优先级,在越后面约束的soft约束优先级越高,因此,验证环境中子层次比父层次具有更高的优先级。另外,如果只对soft约束求解,那么该次调用求解可以永远不失败。如果soft约束求解没有失败,那么求解的结果相当于是对hard约束求解一样。

Soft约束可以被discard掉,也就是不使能,使用disable soft语法可以将比该定义disable的约束块低优先级的soft约束都失效掉。比如:

class A;rand int x;constraint A1 { soft x == 3; }constraint A2 { disable soft x; } // discard soft constraintsconstraint A3 { soft x inside { 1, 2 }; }endclassinitial beginA a = new();a.randomize();end

A2约束块要求求解器忽略随机变量x所有优先级较低的soft约束,从而导致A1约束块被忽略。因此,求解器只需要满足最后的A3约束。上述示例将导致随机变量x取值为1或2。需要注意的是,如果省略了A3约束块,那么变量x将处于无任何约束的状态。

8. 随机化方法

每一个类内部都自带有randomize()这个virtual方法,它的定义如下:

virtual function int randomize();

randomize()是一个virtual方法,它为类对象中所有active随机变量提供了随机值,当然随机值要符合active约束。如果随机化成功,那么返回1;反之,返回0。

每一个类也自带pre_randomize()和post_randomize()方法,注意这两个方法不是virtual的。pre_randomize()是在randomize()之前调用的,post_randomize()是在randomize()之后调用的。定义如下:

function void pre_randomize();function void pre_randomize();

如果randomize()失败,那么post_randomize()也不会被调用的。如果randomize()失败,那么随机变量要保持原来的值。

9. In-line约束

In-line约束是指用randomize with的方法去随机类中的变量。当randomize()调用时没有传参数,那么它内部所有active 随机变量都要随机新值。当randomize()调用时传参数了,那么这些传的参数是该object指定随机变量的全集,其余随机变量都当作state variables。如下:

class CA;rand byte x, y;byte v, w;constraint c1 { x < v && y > w );endclassCA a = new;a.randomize();          // random variables: x, y   state variables: v, wa.randomize( x );       // random variables: x      state variables: y, v, wa.randomize( v, w );  // random variables: v, w  state variables: x, ya.randomize( w, x );  // random variables: w, x  state variables: y, v

据以上可知,randomize()传参可以改变类内部的任何属性,设置没有定义为rand或randc的都可以。不过该机制对于randc是无效的,它不能将非随机变量变成randc,也不能将randc变成non-randc的。

如果调用randomize()里传null参数,那么表示该次调用没有任何随机变量需要随机赋新值的,那么该方法相当于是一个checker,它只是返回随机状态,这样就可以用于检查内部约束块是否正确。如:

success = a.randomize( null );  // no random variables

10. local范围解析

在使用randomize() with constraint block的时候,可以引用类属性或调用方法中(randomize with)的local变量。如果这些变量没有加限制,那么工具会先搜寻object 类的内部,然后才去搜去调用方法(包含method)的范围。这样的话,如果object类和调用方法的范围内有相同名字的变量,且想要用local的就比较麻烦了,因此SV提供了local::去修改搜寻顺序。当一个变量采用local::标识了,那么工具会去local 范围内找,忽略object类内部的变量。如下例子:

class C;rand integer x;endclassfunction int F(C obj, integer x);F = obj.randomize() with { x < local::x; };endfunction

在obj.randomize() 调用的in-line约束块中,没有限定x则会绑定到C类属性(即正在被随机化的对象的范围内),而限定名称local::x则会绑定到函数F()的参数(局部作用域)。

11. 控制随机变量和约束块

rand_mode()可以用于控制是否将随机变量处于active或inactive状态。当随机变量是inactive时,那么它就像是没有被rand或randc修饰的变量一样。Inactive变量不会被randomize()随机赋值的,它们的值会被solver当作state variables。所有的随机变量的初始态都是active的。rand_mode()方法的定义如下:

task object[.random_variable]::rand_mode( bit on_off );orfunction int object.random_variable::rand_mode();

这里object是指任何能够获取到定义该随机变量的对象句柄的表达式。random_variable是指要对其执行操作的随机变量的名称。在作为任务调用时,可以未指定random_variable,则该操作将应用于指定对象内的所有随机变量。task方式是用于设定variable的mode,参数传1为active,参数传0为inactive。function方式时用于返回随机变量的mode,返回1表示active,返回0表示inactive。

constraint_mode()可以用于控制一个约束块是否是active或inactive的。如果约束块是inactive的,那么randomize()在调用时不会考虑该约束块的了。所有约束块的初始状态时active。constraint_mode()方法的定义如下:

task object[.constraint_identifier]::constraint_mode( bit on_off );orfunction int object.constraint_identifier::constraint_mode();

这里object是指任何能够获取定义该约束块所对应的对象句柄的表达式。constraint_identifier是指要被操作的约束块名字。如果constraint_identifier省略掉,那么object内部的所有constraints都一块设定。task方式用于设定约束块的mode,传1表示active,传0表示inactive。function方式时用于返回约束块的mode,返回1表示active,返回0表示inactive。

12. 随机数系统方法

系统函数$urandom()在每次调用时会返回一个32-bit的unsigned的伪随机数。定义如下:

function int unsigned $urandom [ (int seed ) ] ;

seed是可选的,seed可以是任何整数表达式。如果seed一致,那么random number generator(RNG)会产生相同的随机数序列。RNG是确定的,每一次程序执行时,它会从同一个随机序列周期性的取值。不过我们可以通过指定$urandom的不同seed来使得它变得不确定,如将每一天的时间作为seed。

系统函数$urandom_range()会返回在指定范围内的无符号整数。定义如下:

function int unsigned $urandom_range(int unsigned maxval, int unsigned minval = 0 );

它将返回maxval到minval之间的数,如果minval省略掉,那么范围是maxval到0。如果maxval小于minval,那么会自动翻转,确保第一个参数不小于第二个参数。

srandom()可以用于手动设置object或thread的RNG的种子。srandom()方法使用给定种子的值初始化对象的RNG。定义如下:

function void srandom( int seed );

还有get_randstate()和set_randstate()是用于获取或设置object的RNG的状态。

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

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

相关文章

初识 docker [下] 项目部署

项目部署Dockerfile构建镜像DockerCompose基本语法基础命令项目部署 前面我们一直在使用别人准备好的镜像&#xff0c;那如果我要部署一个Java项目&#xff0c;把它打包为一个镜像该怎么做呢&#xff1f; …省略一万字 站在巨人的肩膀上更适合我们普通人,所以直接介绍两种简单…

Android15广播ANR的源码流程分析

Android15的广播ANR源码流程跟了下实际代码的流程&#xff0c;大概如下哈&#xff1a;App.sendBroadcast() // 应用发起广播→ AMS.broadcastIntentWithFeature() // 通过Binder IPC进入system_server进程→ AMS.broadcastIntentLocked() // 权限校验广播分类&#xff08;前…

密码学中的概率论与统计学:从频率分析到现代密码攻击

在密码学的攻防博弈中&#xff0c;概率论与统计学始终是破解密码的“利器”。从古典密码时期通过字母频率推测凯撒密码的密钥&#xff0c;到现代利用线性偏差破解DES的线性密码分析&#xff0c;再到侧信道攻击中通过功耗数据的统计特性还原密钥&#xff0c;统计思维贯穿了密码分…

力扣刷题977——有序数组的平方

977. 有序数组的平方 题目&#xff1a; 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&…

应用加速游戏盾的安全作用

在数字娱乐产业蓬勃发展的今天&#xff0c;游戏已从单纯的娱乐工具演变为连接全球数十亿用户的社交平台与文化载体。然而&#xff0c;伴随游戏市场的指数级增长&#xff0c;网络攻击的频率与复杂性也呈爆发式上升。从DDoS攻击导致服务器瘫痪&#xff0c;到外挂程序破坏公平竞技…

linux安装zsh,oh-my-zsh,配置zsh主题及插件的方法

这是一份非常详细的指南&#xff0c;带你一步步在 Linux 系统中安装 Zsh、配置主题和安装插件。 Zsh&#xff08;Z Shell&#xff09;是一个功能强大的 Shell&#xff0c;相比于大多数 Linux 发行版默认的 Bash&#xff0c;它提供了更强的自定义能力、更智能的自动补全、更漂亮…

【设计模式系列】策略模式vs模板模式

策略模式是什么&#xff1f;如何定义并封装一系列算法策略模式 (Strategy Pattern)模板模式 (Template Pattern)模板模式与策略模式的深度对比与区分混合使用两种模式的场景策略模式 (Strategy Pattern) 应用场景&#xff1a;当需要根据不同条件选择不同算法或行为时&#xff…

aigc(1.1) opensora-2.0

open sora-2.0相关链接: arxiv链接 huggingface页面 HunyuanVideo VAE open sora2.0的VAE模型复用了HunyuanVideo的3D VAE,HunyuanVideo的arxiv链接。下图来自论文,可见VAE是一个因果注意力的3D结构。在配图左侧,视频会被编码为video token序列,而在配图右侧,去噪的vide…

Linux驱动21 --- FFMPEG 音频 API

目录 一、FFMPEG 音频 API 1.1 解码步骤 创建核心上下文指针 打开输入流 获取输入流 获取解码器 初始化解码器 创建输入流指针 创建输出流指针 初始化 SDL 配置音频参数 打开音频设备 获取一帧数据 发送给解码器 从解码器获取数据 开辟数据空间 初始化内存 音频重采样…

《计算机“十万个为什么”》之 [特殊字符] 序列化与反序列化:数据打包的奇妙之旅 ✈️

《计算机“十万个为什么”》之 &#x1f4e6; 序列化与反序列化&#xff1a;数据打包的奇妙之旅 ✈️欢迎来到计算机“十万个为什么”系列&#xff01; 本文将以「序列化与反序列化」为主题&#xff0c;深入探讨计算机世界中数据的打包与解包过程。 让我们一起解开数据的神秘面…

机器学习与深度学习评价指标

机器学习与深度学习评价指标完全指南 📊 为什么需要评价指标? 想象你是一位医生,需要判断一个诊断模型的好坏。如果模型说"这个病人有癌症",你需要知道: 这个判断有多准确? 会不会漏掉真正的癌症患者? 会不会误诊健康的人? 评价指标就像是给AI模型打分的&…

Hugging Face-环境配置

打开anaconda promptconda activate pytorchpip install -i https://pypi.tuna.tsinghua.edu.cn/simple transformers datasets tokenizerspycharm找到pytorch下的python.exe#将模型下载到本地调用 from transformers import AutoModelForCausalLM,AutoTokenizer#将模型和分词工…

cnn中池化层作用

一、池化层概述 在卷积神经网络中&#xff0c;池化层是核心组件之一&#xff0c;主要作用是逐步降低特征图的空间尺寸即宽和高&#xff0c;从而减少计算量、控制过拟合并增强模型的鲁棒性。 核心作用 降维与减少计算量 压缩特征图的尺寸&#xff0c;显著减少后续层的参数数量和…

写一个音乐爬虫

今天我们写一个网易云音乐的爬虫&#xff0c;爬取网易云音乐热歌榜音乐链接并下载&#xff0c;这里用到了之前引用的BeautifulSoup和requests。 BeautifulSoup是一个Python库&#xff0c;用于从HTML和XML文件中提取数据。它提供了一种简单的方式来遍历文档树和搜索文档树中的元…

战斗公式和伤害走配置文件

故事背景&#xff0c;上次属性计算用的配置&#xff0c;这次伤害计算也走配置&#xff0c;下面是测试代码和测试数据local formulas {[100001]{id 100001,name "基础伤害",formula "function (self,tag,ishit,iscritial,counterratio)\n if ishit1 then\n …

线性代数 上

文章目录线性代数知识整理一、求行列式1、 套公式2、利用性质&#xff0c;化为可套公式3、抽象行列式4、抽象向量二、代数余子式的线性组合三、求AnA^nAn四、证明A可逆五、求A的逆1、定义法2、初等变换3、公式六、求秩七、线性表示的判定八、线性无关九、求极大线性无关组十、等…

红帽AI推理服务器三大特点

生成式人工智能&#xff08;Gen AI&#xff09;的迅猛发展&#xff0c;对大型语言模型&#xff08;LLM&#xff09;的部署提出了更高的性能、灵活性和效率要求。无论部署在何种环境中&#xff0c;红帽AI推理服务器都为用户提供经过强化并获得官方支持的vLLM发行版&#xff0c;配…

开始记录一步步学习pcl

安装参考&#xff0c;大神写的非常详细&#xff0c;一步到位 https://blog.csdn.net/qq_36812406/article/details/144307648?ops_request_misc%257B%2522request%255Fid%2522%253A%25220e215e6ac266b90ded12ed6b2eab1257%2522%252C%2522scm%2522%253A%252220140713.13010233…

Linux系统Centos7 安装mysql5.7教程 和mysql的简单指令

目录 一. 安装 MySQL 官方 Yum 仓库 二. 安装 MySQL 5.7 1.查看可用的mysql版本仓库 2.启用MySql5.7仓库 3.禁用更高版本的仓库&#xff08;可选&#xff09; 4.导入 MySQL GPG 公钥 5.安装MySql5.7 三. 启动 MySQL 服务 1.启动 MySQL 服务 2. 设置开机自启 3.查看服…

嵌入式——C语言:指针③

一、函数指针和指针函数&#xff08;一&#xff09;指针函数&#xff1a;是函数&#xff0c;函数的返回值是指针1.不能返回局部变量的值2.指针函数返回的地址可以作为下一个函数调用的参数&#xff08;二&#xff09;函数指针&#xff1a;是指针&#xff0c;指针指向一个函数in…