- 第一章 SystemVerilog导论
- 第二章 文本值
- 第三章 数据类型
- 第四章 数组
- 第五章 数据声明
- 第六章 属性
- 第七章 操作符与表达式
- 第八章 过程语句和控制流
- 第九章 进程
- 第十章 任务与函数
- 第十一章 类
- 第十二章 随机约束
- 第十三章 进程间的同步与通信
- 第十四章 调度语义
- 第十五章 时钟控制块
- 第十六章 程序块
- 第十七章 断言
- 第十八章 层次
- 第十九章 接口
- 第二十章 覆盖
- 第二十一章 参数
- 第二十二章 配置库
- 第二十三章 系统任务与系统函数
- 23.1 简介(一般信息)
- 23.2 确立时的typeof函数
- 23.3 typename函数
- 23.4 表达式尺寸系统函数
- 23.5 范围系统函数
- 23.6 Shortreal转换
- 23.7 数组查询系统函数
- 23.8 断言严重性系统任务
- 23.9 断言控制系统任务
- 23.10 断言系统函数
- 23.11 随机数系统函数
- 23.12 程序控制
- 23.13 覆盖系统函数
- 23.14 对Verilog-2001系统任务的增强
- 23.15 $readmemb与$readmemh
- 23.16 $writememb and $writememh
- 23.17 File format considerations for multi-dimensional unpacked arrays
- 23.18 System task arguments for multi-dimensional unpacked arrays
- 第二十四章 VCD数据
- 第二十五章 编译器指令
- 第二十六章 考虑从SystemVerilog中删除的功能
- 第二十七章 直接编程接口(DPI)
- 27.1 概述
- 27.2 Two layers of the DPI
- 27.3 Global name space of imported and exported functions
- 27.4 导入的任务和函数
- 27.5 Calling imported functions
- 27.6 Exported functions
- 27.7 Exported tasks
- 27.8 Disabling DPI tasks and functions
- 第二十八章 SystemVerilog断言API
- 第二十九章 SystemVerilog覆盖API
- 29.1 需求
- 29.2 SystemVerilog real-time coverage access
- 29.3 FSM recognition
- 29.3.1 Specifying the signal that holds the current state
- 29.3.2 Specifying the part-select that holds the current state
- 29.3.3 Specifying the concatenation that holds the current state
- 29.3.4 Specifying the signal that holds the next state
- 29.3.5 Specifying the current and next state signals in the same declaration
- 29.3.6 Specifying the possible states of the FSM
- 29.3.7 Pragmas in one-line comments
- 29.3.8 Example
- 29.4 VPI coverage extensions
- 第三十章 SystemVerilog数据读API
- 30.1 简介(一般信息)
- 30.2 需求
- 30.3 Extensions to VPI enumerations
- 30.4 VPI object type additions
- 30.5 Object model diagrams
- 30.6 Usage extensions to VPI routines
- 30.7 VPI routines added in SystemVerilog
- 30.8 Reading data
- 30.9 Optionally unloading the data
- 30.10 Reading data from multiple databases and/or different read library providers
- 30.11 VPI routines extended in SystemVerilog
- 30.12 VPI routines added in SystemVerilog
- 30.12.1 VPI reader routines
- 第三十一章 SystemVerilog VPI Object Model
- 31.1 简介(一般信息)
- 31.2 Instance
- 31.3 Interface
- 31.4 Program
- 31.5 Module (supersedes IEEE 1364-2001 26.6.1)
- 31.6 Modport
- 31.7 Interface tf decl
- 31.8 Ports (supersedes IEEE 1364-2001 26.6.5)
- 31.9 Ref Obj
- 31.9.1 Examples
- 31.10 Variables (supersedes IEEE 1364-2001 section 26.6.8)
- 31.11 Var Select (supersedes IEEE 1364-2001 26.6.8)
- 31.12 Typespec
- 31.13 Variable Drivers and Loads (supersedes IEEE 1364-2001 26.6.23)
- 31.14 Instance Arrays (supersedes IEEE 1364-2001 26.6.2)
- 31.15 Scope (supersedes IEEE 1364-2001 26.6.3)
- 31.16 IO Declaration (supersedes IEEE 1364-2001 26.6.4)
- 31.17 Clocking Block
- 31.18 Class Object Definition
- 31.19 Constraint, constraint ordering, distribution,
- 31.20 Constraint expression
- 31.21 Class Variables
- 31.22 Structure/Union
- 31.23 Named Events (supersedes IEEE 1364-2001 26.6.11)
- 31.24 Task, Function Declaration (supersedes IEEE 1364-2001 26.6.18)
- 31.25 Alias Statement
- 31.25.1 Examples
- 31.26 Frames (supersedes IEEE 1364-2001 26.6.20)
- 31.27 Threads
- 31.28 tf call (supersedes IEEE 1364-2001 26.6.19)
- 31.29 Module path, path term (supersedes IEEE 1364-2001 26.6.15)
- 31.30 Concurrent assertions
- 31.31 Property Decl
- 31.32 Property Specification
- 31.33 Multiclock Sequence Expression
- 31.34 Sequence Declaration
- 31.35 Sequence Expression
- 31.36 Attribute (supersedes IEEE 1364-2001 26.6.42)
- 31.37 Atomic Statement (supersedes IEEE 1364-2001 26.6.27)
- 31.38 If, if else, return, case, do while (supersedes IEEE 1364-2001 26.6.35, 26.6.36)
- 31.39 waits, disables, expect, foreach (supersedes IEEE 1364 26.6.38)
- 31.40 Simple expressions (supersedes IEEE 1364-2001 26.6.25)
- 31.41 Expressions (supersedes IEEE 1364-2001 26.6.26)
- 31.42 Event control (supersedes IEEE 1364-2001 26.6.30)
- 31.43 Event stmt (supersedes IEEE 1364-2001 26.6.27)
- 31.44 Process (supersedes IEEE 1364-2001 26.6.27)
- 31.45 Assignment (supersedes IEEE 1364-2001 26.6.28)
- 附录A 形式语法
- A.1 源文本
- A.2 声明
- A.3 Primitive instances
- A.4 Module, interface and generated instantiation
- A.5 UDP declaration and instantiation
- A.6 Behavioral statements
- A.6.1 Continuous assignment and net alias statements
- A.6.2 Procedural blocks and assignments
- A.6.3 Parallel and sequential blocks
- A.6.4 Statements
- A.6.5 Timing control statements
- A.6.6 Conditional statements
- A.6.7 Case statements
- A.6.8 Looping statements
- A.6.9 Subroutine call statements
- A.6.10 Assertion statements
- A.6.11 Clocking block
- A.6.12 Randsequence
- A.7 Specify section
- A.8 Expressions
- A.9 General
- A.10 Footnotes (normative)
- 附录B 关键字
- 附录C 标准包
- 附录D 链表
- 附录E DPI C-layer
- E.1 概述
- E.2 Naming conventions
- E.3 Portability
- E.4 Include files
- E.5 Semantic constraints
- E.6 Data types
- E.7 Argument passing modes
- E.8 Context tasks and functions
- E.9 Include files
- E.10 Arrays
- E.11 Open arrays
- E.11.1 Actual ranges
- E.11.2 Array querying functions
- E.11.3 Access functions
- E.11.4 Access to the actual representation
- E.11.5 Access to elements via canonical representation
- E.11.6 Access to scalar elements (bit and logic)
- E.11.7 Access to array elements of other types
- E.11.8 Example 4— two-dimensional open array
- E.11.9 Example 5 — open array
- E.11.10 Example 6 — access to packed arrays
- E.11.11 Example 7 — binary compatible calls of exported functions
- 附录F 包含文件
- 附录G 包含外部语言代码
- 附录H 并发断言的形式语义
- 附录I svvpiuser.h
- 附录J 术语表
- 附录K 参考书目
- 其他
12.16.7 生成式间的值传递
数据可以传递到将要产生的生成式,并且产生的生成式可以将数据返回到触发的非端接生成式。向生成式传递数据类似于一个任务调用,并且使用相同的语法。从一个生成式返回数据要求为生成式声明一个类型,这与函数声明使用相似的语法。
接收数据的生成式包含一个形式参数列表。为生成式声明参数的语法类似于一个任务原型;向生成式传递数据的语法与一个任务调用相同。
production ::= [function_data_type] production_name[(tf_port_list)]:rs_rule{| rs_rule}; production_item ::= production_identifier[(list_of_arguments)]
例如,前面的第一个例子可以按如下方式重写:
randsequence(main) main : first second gen; first : add | dec; second : pop | push; add : gen("add"); dec : gen("dec"); pop : gen("pop"); push : gen("push"); gen(string s = "done"):{$display(s);}; endsequence
在这个例子中,生成式gen接受一个字符串参数,其缺省值为"done"。五个其它的生成式产生这个生成式,每一个都具有一个不同的参数(main中的一个使用缺省知)。
一个生成式产生了一个范围,这个范围包含了这个生成式的所有规则和代码块。因此,传递给一个生成式的参数在整个生成式中有效。
返回数据的生成式要求一个类型声明。可选的返回类型位于生成式的前面。没有说明一个返回类型的生成式被假定为具有void类型。
我们使用带有一个表达式的return语句从一个生成式中返回一个值。当return语句被用于一个具有返回值的生成式中的时候,它必须说明一个具有正确类型的表达式,这就像一个非void函数一样。return语句将指定的表达式赋值到对应的生成式。返回值可以在触发返回一个值得生成式的产生的生成式的代码块中读取。在这些代码块中,返回值使用生成式名字加上一个可选的索引表达式来访问。在每一个生成式中,一个具有相同名字的变量会被隐含地为每一个返回一个值的生成式声明。
如果相同的生成式出现了多次,那么一个起始于1的一维数组会被隐含地声明。例如:
randsequence(bin_op) void bin_op : value operator value // void类型是可选的 {$display("%s %b %b", operator, value[1], value[2]);} ; bit [7:0] value : {return $urandom}; string operator : add := 5 {return "+";} | dec := 2 {return "-";} | mult := 1 {return "*";} ; endsequence
在上面的例子中,operator和value生成式分别返回一个字符串和一个8位的值。生成式bin_op包含了这两个具有返回值的生成式。因此,与生成式bin_op相关联的代码块具有下列隐含的变量声明访问:
bit [7:0] value [1:2]; string operator;
访问这些隐含变量产生从对应的生成式返回的值。当执行的时候,上面的例子显示一个简单的三条目的随机序列:一个操作符跟着两个8位的值。操作符+、-、和*分别以5/8、2/8、和1/8的分布被选择。
只有已经被产生的生成式的返回值(也就是访问它们的代码块的左侧)可以被重新获取。试图读取一个还没有产生的生成式的返回值会导致一个为定义的值。例如:
X : A {int y = B;} B; // 对B的无效的访问 X : A {int y = A[2];} B A; // 对A[2]的无效的访问 X : A {int y = A;} B {int j = A + B;}; // 有效
randsequence产生的序列可以作为生成式产生的边带效应被直接驱动到一个系统当中,或者这个序列可以被产生以便进行后续的处理。例如,下列的函数产生并返回一个位于其参数给定范围内的随机数队列。第一个和最后一个队列条目分别对应于下边界和上边界。而且,队列的尺寸根据生成式的权重被随机地选择。
function int[$] GenQueue(int low, int high); int[$] q; randsequence() TOP : BOUND(low) LIST BOUND(high); LIST : LIST ITEM := 8{q = {q, ITEM};} | ITEM := 2{q = {q, ITEM};} ; int ITEM : {return $urandom_range(low, high);}; BOUND(int b) : {q = {q, b};}; endsequence GenQueue = q; endfunction
当函数GenQueue中的randsequence执行的时候,它产生TOP生成式,TOP生成式会产生三个生成式:具有参数low的BOUND、LIST和具有参数high的BOUND。BOUND生成式简单地将它的参数附加到队列当中。LIST生成式包含了一个加权的LIST ITEM生成式和一个ITEM生成式。产生LIST ITEM生成式的概率为80%,它会引起LIST生成式被递归地产生,因此延缓了ITEM生成式的产生。LIST ITEM和ITEM的选择会被重复直到选择ITEM(它会中止LIST生成式)。每次产生ITEM生成式的时候,它会在指定的范围内产生一个随机数,这个随机数会在以后附加到队列。
下面的例子使用一个randsequence块为一个DSL包网络产生随机流量。
class DSL; ... endclass // 产生有效DSL包的类 randsequence (STREAM) STREAM : GAP DATA := 80 | DATA := 20; DATA : PACKET(0) := 94{transmit(PACKET);} | PACKET(1) := 6{transmit(PACKET);}; DSL PACKET (bit bad) : { DSL d = new; if (bad) d.crc ^= 23; // 损坏的crc return d; }; GAP : {##{$urandom_range(1, 20)};}; endsequence
在这个例子中,流量包含了一个数据包(好的和坏的)和及其间隙的流。第一个生成式STREAM指出:在80%的时间里流量包含了一个GAP然后跟着一些DATA,在20%的时间里流量仅仅包含了DATA(没有GAP)。第二个生成式DATA指出:所有的数据包中有94%是好的数据包,另外余下的6%是坏的数据包。PACKET生成式实现了DSL包的产生;如果生成式参数是1,那么会通过损坏一个有效的DSL包的crc来产生一个坏包。最后,GAP生成式通过在1到20之间等待一个随机的周期数目来实现发送间隔。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论