-
=
阻塞串行
<=
非阻塞并行
1
)时序逻辑
----
使用非阻塞
赋值
2
)锁存器
----
使用非阻塞赋值
3
p>
)用
always
块生成的组合逻辑
----
用阻塞赋值
4
)在同一个
always
块中既有
时序逻辑又有组合逻辑
---
用非阻塞赋值
5
)在同一个
always
块中不
要既用阻塞赋值又用非阻塞赋值
6
)
不要在一个以上的
always
块中对同一个变量赋值
7
)用
$$strob
e
显示用非阻塞赋值指定的变量值
8
)不要用
#
0
过程性赋值
Modport
将信号分组并指明方向
函数不能消耗时间,不能有
#100@(posedge
clk)wait
之类的阻塞语句
Interface
arb_if(input bit clk);
Logic [1:0]
a,b;
Logic rst;
Modport
test(output a,rst,
Input
b,clk);
Endinterface
Module arb(arb_ arbif);
…………
Endmodule
数组定位
Int
tq[$$],d[]=
’
{9,1,8,3,4,4};
Tq=_index(x) with (item>3);
//{0,2,4,5}
得到的是脚标
Tq= with (item>3);
//{9,8,4,4}
数组求和
Int
count,total;
Count=
with
(
item>7
)
;
//2:{9,8}
返回结果为元
素与
7
比
较表达式返回
1
为真或者零这里面返回
,
{1,0,1,0,0,0}
求和得
2
Total=
with
((item>7)*item)
;
//{1,0,1,0,0,0}
和
对应元素相乘求
和得
17=9
加
8
数组排序
e();
//
逆序
();
//
从小到大
();
//
从大到小
e();
时钟块
指定同步信号相对于时钟的时序
Interface
arb_if(input bit clk);
Logic [1:0]
a,b;
Logic rst;
Clocking cb @(posedge clk);
Output a;
Input b;
Modport
test(output rst,
Clocking
cb);
Endinterface
Module arb(arb_ arbif);
Initial begin
.a<=0;
@;
$$dispiay(
………
..)
Endmodule
断言
A1
:
assert(.a==2
’
b01)
Else
$$error(
“
grant not
asserted
”
);
四种有输出消息的函数可在断言内部使用
$$info
$$waring
$$error
$$fatal
要验证
这样一个属性:
“当信号
a
在某一个时
钟周期为高电平时,那
么在接下来的
2
~
4
个时钟周期内,
信号
b
应该为高电平”
。
用
p>
Verilog
语言描述这样一个属性需要一大段代码,
而用
SVA
描述就只需要几行
代码。下面的代码为
SVA
。
例
1
:
property
a2b_p;
@(posedge
sclk)
$$rose(a)
|->
[2:4]
$$rose(b);
endproperty
a2b_a: assert
property(a2b_p); a2b_c: cover property(a2b_p);
并发断言
并发断言的计算基于时钟周
期,
在时钟边沿根据变量的采样值计算表
达式。它可以放在过程
块(
procedural block
)
、模块(
module
)
、接口<
/p>
(
interface
)或一个程序块(
program
)的定义中。并发断言可以在静
态(形式化)验证工具和动态(仿真)验证工具中使用。上面的例子
就是并发断
言
SVA
提供了
3
个内嵌函数,用于检查信号的边沿变化。
$$rose(
布尔表达式或信号名
)
当信号
/
表
达式的最低位由
0
或
x
变为
1
时返回真值。
$$fell(
布尔表达式或信号名
)
当信号
/
表
达式的最低位由
1
变为
0
或
x
时返回真值。
$$stable(
布尔表达式或信号名
)
当
信号
/
表达式的最低位不发生变化时返回真值。
断言的建立过程
“编写布尔表达式
—
>
编写序列
(
sequence
)
-
>
编写属性
(
prop
erty
)
—
>
编写断言(
assert
property
)和覆盖语句(
cover
property
)
”
唯一性和优先级决定语句
在
Verilog
< br>中,如果没有遵循严格的编码风格,它的
if-else
和
case
语
句会在
< br>RTL
仿真和
RTL
综合间具有
不一致的结果。
如果没有正确使用
full_case
和
parallel_case
综合指令还会引
起一些其它的错误。
System
Verilog
能够显式地指明什么时候一条决定语句的分支是唯一
的,或者什么时候需要计算优先级。我们可以在
if
或
p>
case
关键字之
前使用
< br>unique
或
requires
关键字。这些关键字可以向仿真器、综合
编译器、
以及其它工
具指示我们期望的硬件类型。
工具使用这些信息
来检查
if
或
case
语句是
否正确建模了期望的逻辑。例如,如果使用
unique
限定了
一个决定语句,那么在不希望的
case
值出现的时候仿
真器就能够发布一个警告信息
bit
[2:0] a;
unique if ((a==0)
|| (a==1)) y = in1;
else if
(a==2) y = in2;
else if
(a==4) y = in3; //
值
3
、
5
、
6
、
7
会引起一个警告
priority if
(a[2:1]==0) y = in1; //
a
是
0
或
1
else if (a[2]==0) y = in2;
//
a
是
2
或
3
else y = in3; //
如果
a
为其他的值
unique case (a)
0, 1: y = in1;
2: y = in2;
4: y = in3;
endcase //
值
3
、
5
、
6
、
7
会引起一个警告
类
Class trans
;
…………
Endclass
trans
a;
声明一个句柄(指针)
a=new();//
为一个
trans
对象分配空间
用户定义的
< br>new()
函数
Class
trans
;
Logic
[31:0] addr,crc,data[8];
Function new;
Addr=3;
Foreach (data[i])
Data[i]=5;
Endfunction
Endclass
随机化
Class packet
Rand bit [31:0]
a,b,c[8];
Randc bit[7:0] k;
Constraint d{a>10;
a<15;}
endclass
packet p;
initial begin
p=new();
assert (ize());
transmit(p);
end
指示通过引用传递的参数,参数声明需要以
ref
关键字开始
线程
always_comb
过程来建模组合逻辑行为
在
0
时刻结束时自动触发一
次
always_latch
过程来建模锁存逻辑行为
always_ff
过程可以用来建模可综合的时序逻辑行为
它仅能包含一个事件控制过程并且没有阻塞定时控制
always_comb
过程提供了不同于正常
always
过程的功能:
?
?
?
具有一个推断的敏感列表
赋值语句左侧的变量不应该被任何其它进程写入。
在所有的
initial
和
always
块被启动以后,过程在时间
0
处被自
动地触发一次,因此过程的输出与输
入一致。
SystemVeril
og
的
always_comb
过
p>
程
在
下
述
几
个
方
面
上
不
同
于
< br>Verilog-2001
的
always
@*
:
?
always_comb
在时间
0
p>
处自动执行,
而
always @*
直到推断的敏
感列表中的一个信号发生变化的时候才会执行。
?
always_comb
敏感于一个函数内容内部的改变,
< br>而
always
@*
仅
敏感于一个函数自变量的改变。
?
在
p>
always_comb
内部赋值左侧的变量(包括来自被调用函数
内
容中的变量)
不应该被其它进程写入,
而
always
@*
则允许多个
进程写入相同的变量。
?
alw
ays_comb
中的语句不应该包含阻塞语句、具有阻塞定时或
事件控制的语句,或者
fork...join
语句。
如果
alway
s_comb
过程内的行为没有代表组合逻辑,
例如推断出了锁
存器,软件工具执行额外的检查来发布警告信息。
Fork
……
join
所有并行语句执行完毕才执行后续
Fork
……
.join_none
执行块儿内语句的同时父线程后面的程序继续进
行
Fork
…
..join
_any
当块内第一个语句完成后,父线程才继续执行。
停止单个线程
Parameter
timeout=1000
;
Task check(trans
tr);
Fork
begin
Fork: check_stop
Begin
Wait(==);
$$display(
“………
.
”
);
End
#timeout
$$display(
“………
.
”
);
Join_any
Disable check_stop;
End
Join_none