观前提示
本文为本人自学SystemVerilog时记的笔记,可能有疏漏和错误,欢迎指出。
其中,表格内有- xxx
的表示为前一个项的子项,可能是后缀,或是应该写在xxxxx…endxxxxx内的内容;而xxx -
则表示xxx是某个项的前缀,用于加在某项前的;而同时包含两者则代表其既是子项目又是某项的前缀。
其实本文主要用于记忆对应关键词的含义,适合已经了解过一遍SV的初学者用于快速回忆起xxx是用来干什么的之类的,并不适用于0基础学习,对大佬也没有帮助。
如果有英语好的想自学,可以查看这个网站chipverify.com
Verilog中有的关键词
模块及端口定义
| |
---|
module | 模块开始定义 |
endmodule | 模块结束定义 |
input | 输入端口定义 |
output | 输出端口定义 |
inout | 双向端口定义 |
数据类型
| |
---|
parameter | 信号的参数定义 |
wire | wire信号定义 |
reg | reg信号定义 |
integers | 整数 |
real | 实数 |
语句内容
| |
---|
initial | 开始执行一次 |
always | 永远执行 |
posedge/negedge | 时序电路的标志 |
assign | 连续赋值语句(常用于wire) |
begin | 语句的起始标志 |
end | 语句的结束标志 |
分支
| |
---|
case | case语句起始标记 |
default | case语句的默认分支标志 |
endcase | case语句结束标记 |
用于if-else if或case前:
| |
---|
unique - | 如果同时满足多个条件或无一条件满足,则报错 |
unique0 - | 如果同时满足多个条件,则报错 |
priority - | 如果无一条件满足且无else,则报错,否则在第一个满足条件时结束判断 |
循环
函数和任务
| |
---|
function | 函数(只能写非阻塞内容) |
endfunction | 函数结束 |
task | 任务 |
endtext | 任务结束 |
automatic | 非静态(静态内变量共用,非静态变量不共用) |
SystemVerilog特有关键词
数据类型
4值类型(0,1,x,z)
| |
---|
logic | 类似于可自动判断是wire还是reg的数据类型 |
2值类型(0 or 1)
| |
---|
bit | 一位 |
byte | 八位 |
shortint | 短整型 |
int | 整型 |
longint | 长整型 |
unsigned | 无符号 |
string | 字符串 |
enum | 枚举 |
struct | 结构体 |
type | 类型 |
typedef | 类型定义 |
[$] | 队列([$:max]为最大容量max的队列) |
事件
| |
---|
event | 事件,等待触发方法:@(name)或wait(name.triggered) |
-> name | 触发名为name的事件 |
wait_order(a,b,c) | 等待事件按顺序触发,否则触发else块内容 |
线程
| |
---|
fork | 并行块开始 |
join | 并行块结束(等待块内所有线程结束时继续) |
join_any | 并行块结束(等待块内任意线程结束时继续) |
join_none | 并行块结束(不等待,直接继续运行) |
disable fork | 结束当前块区及子块的所有线程 |
wait fork | 等待当前块区及子块的所有线程结束 |
线程同步和通信
semaphores | 信号量 |
---|
- new(n) | 创建含有n个键的信号量 |
- .put(n) | 放入n个键 |
- .get(n) | 拿出n个键,无法满足则等待(try_则不阻塞,失败返回0) |
mailbox | 信箱 |
---|
- new(n) | 创建最大容量为n的信箱(0为无限大) |
- .put(xxx) | 放入信息xxx(try_则不阻塞,邮箱满放入失败返回0) |
- .get(xxx) | 拿取信息并存入xxx中(try_则不阻塞,邮箱空拿取失败返回0) |
- .peek(xxx) | 读取信息并存入xxx中,不删除该信息(try_则不阻塞,邮箱空拿取失败返回0) |
接口
interface | 接口(常用logic类型变量) |
---|
- modport | 接口端口(用于定义哪些部分为输入,哪些为输出,以用于不同用途) |
- clocking | 接口时钟(用于管理延迟之类的) |
endinterface | 接口结束 |
类
| |
---|
virtual - | 虚类(抽象类) |
class | 类 |
- extend | 继承 |
- #(parameter) | 参数 |
type T | 参数为type类型时,相当于泛型 |
function new() | 构造函数 |
pure - | 纯虚方法,基类无需写函数内容 |
virtual - | 虚方法(子类可以修改内容,基类引用调用其时会调用子类的方法) |
extern - | 外部的,说明此函数在类外实现(实现格式:将一般的函数名称换成name::fun();) |
static - | 静态,所有对象共享一个 |
name::fun() | 直接通过类名name调用静态函数fun |
local - | 本地的,相当于私有 |
this | 自引用 |
super | 父类 |
endclass | 类结束 |
typedef name; | 提前声明名为name的类 |
new() | 创建新对象 |
a = new b | 通过b浅拷贝一个对象至a,类中的引用类型不会创建新的值 |
a.copy(b) | 自己实现copy函数来进行深拷贝,需要先创建一个新的a对象 |
C c = D::new | (D继承自C时)创建一个D对象,但赋值给C类型的变量(多态) |
$cast(s,b) | 将保存对象是子类的基类型引用b赋值给子类s(即转化回子类) |
约束
| |
---|
extern - | 外部的,说明此约束在外部实现(实现格式:约束名称换成name::name{xxx};) |
static - | 静态的,即禁用时会禁用所有对象的约束,而不是仅当前对象 |
constraint n {xxx;} | 约束,名称为n,条件是xxx |
- inside{xxx} | 取值在特定范围内,xxx可为[low:hight],或直接列举1,2,3… |
- dist{xxx} | 权重约束,xxx可选a:=n为a每个元素都有n权重,b:/n为b所有元素权重总和为n |
- xxx -> xx | 条件约束,当xxx为真时,才加xx约束(相当于if) |
- soft xxx | 软约束,尽量满足,不满足不报错 |
- foreach | 约束中可使用遍历 |
- solve a before b | 先随机a,再随机b(只能用于整数) |
- ! - | 取反 |
.constraint_mode() | 约束开启状态,传入1为开启,0为关闭,空则返回当前约束状态 |
断言
| |
---|
sequence | 序列,即测试表达式的组合 |
- @(e) xxx | 表明希望触发e事件时xxx为真 |
- @(e) $rose(xxx) | 表明两次触发e时,第一次xxx为假,第二次为真,第一次检测总是失败 |
- @(e) $fell(xxx) | 表明两次触发e时,第一次xxx为真,第二次为假,第一次检测总是失败 |
- @(e) $stable(xxx) | 表明两次触发e时,xxx的值应该不变,第一次检测总是失败 |
- @(e) a ##n b | 表明触发e时a为真,且再触发n次e的时候,b也要为真 |
endsequence | 序列结束 |
property | 属性,内可含序列或测试表达式 |
endproperty | 属性结束 |
assert | 断言 |
- property | 并发型断言 |
- - (@(e) xxx) | 当触发e事件时,xxx表达式在前一刻必需为真 |
- - (name) | 后面可直接加序列或属性名 |
- (xxx) {} else {} | 即时型,断言xxx为真,否则执行else中的内容且报错 |
$error(“xxx”) | 提示报错信息xxx |
随机
| |
---|
rand | 随机类型前缀 |
randc | 随机类型前缀(取完所有值前不重复的随机值) |
.rand_mode() | 随机开启状态,传入1为开启,0为关闭,空则返回当前随机状态 |
pre_randomize() | 自定义函数,在调用randomize()前自动调用 |
post_randomize() | 自定义函数,在调用randomize()成功后自动调用 |
randomize() | 对象随机化方法,可对类成员变量执行专有的随机化操作 |
std::randomize(a··) | 范围随机函数,能够随机化当前范围内的数据(传入) |
- with{xxxx;} | 上面两个随机方法可在后面加随机时需满足约束条件xxx |
randcase | 随机分支,用于随机执行语句 |
- n:xxx | 执行xxx语句的权重为n |
endcase | 分支结束 |
$random | 系统随机化调用函数,返回32bit有符号数; |
$urandom() | 系统随机化调用函数,返回32bit无符号数; |
$urandom_range(a,b) | 系统随机化调用函数,返回指定范围[a,b]内的无符号随机整数 |
功能覆盖
| |
---|
covergroup | 功能覆盖组 |
- @ (xxx) | 在xxx事件时自动采样 |
name : - | 功能点名称 |
- coverpoint n {} | 变量n的功能点 |
- - mode iff (xxx) | 在xxx为真是才采样该功能点 |
- - bins x = {xxx} | 箱子,当n在xxx范围时,称命中箱子x |
endgroup | 功能覆盖组结束 |
.sample() | 对功能覆盖组进行覆盖采样 |
.start() | 打开采样 |
.stop() | 停止采样 |
.get_inst_coverage() | 返回当前覆盖组的覆盖率(百分值),有bin时则是bin的覆盖率 |
程序块,包,类型转换,编译时选项,文件操作
| |
---|
program | 程序块 |
endprogram | 程序块结束 |
package | 包用于typedef一系列变量,定义函数,任务之类的,相当于头文件 |
endpackage | 包结束 |
import pkg:: * | 导入名为pkg的所有内容 |
pkg::name | 直接使用导入的包中的name定义 |
$cast(s,b) | 强制类型转换,将b赋值给a,当不接收返回值时,失败即会报错 |
$test$plusargs(“xxx”) | 查找编译时有没有+以xxx开头的参数,如果有返回真 |
$value$plusargs(“xxx=vv”,v) | 查找编译时有没有+以xxx=开头的参数,如果有则将vv赋值给v |
- vv的类型可选择: | %d,%o,%h/x,%b,%e(科学实数),%f(直接实数),%g(任意实数),%s |
$fopen(“xxx”,“x”) | 打开xxx文件,权限为x,返回文件句柄 |
- x权限有: | r只读,w创建且复写,a创建或续写,r+读+写,w+截断,a+追加,EOF更新 |
$fdisplay(v,“xxx”,…) | 向文件v中写入格式化字符串xxx |
$fwrite(v,“xxx”) | 向文件v中写入格式化字符串xxx |
$fgets(l,v) | 读v文件中的一行到l变量中 |
$fscanf(v,“xxx”,…) | 格式化读入文件 |
$feof(v) | v文件没到结尾时为假,结尾时为真 |
$fclose(v) | 关闭v指向的文件 |
其他用法
| |
---|
$bits(n) | 返回n的位数 |
$countones(n) | 统计n中为1的位的个数,返回统计值 |
$countbits(n, b) | 统计n中为b(可取0/1/x/z)的位的数量,返回统计值 |
$isunknown (n) | 判断变量n中是否含有x态或者z态,如果有,则返回真,否者返回假 |
$time | 仿真时间 |
$sformatf(“xxxx”,a) | 格式化字符串,%0d整数,%0t时间,%s字符串 |
$display(“xxxx”,a) | 格式打印字符串 |
$write(“xxxx”,a) | 格式打印字符串,最后不带换行 |
$strobe(“xxxx”,a) | 在当前时间步处理结束后,格式打印字符串 |
$monitor(“xxxx”,a) | 在参数列表发生变化时,格式化打印字符串 |
$monitoroff | 关闭monitor语句执行 |
$monitoron | 开启monitor语句执行,并立即执行一次 |
$dumpvars(n,name) | 记录模型name下的n层信号,0为所有层级,不加参数为 |
$dumpfile(“xxx.vcd”) | 输出波形文件到指定路径 |
参考资料
[1]chipverify.com