日常记录(28)杂项、断言
fork join的label(tag)
https://bbs.eetop.cn/thread-883536-1-1.html
其中只要有任何一个线程结束,都退出并行运行块,并打印DONE。要求分别用fork-join、fork-join_any,fork-join_none来实现.
实现基于label的方法会非常容易。由于label本身范围更广,比disable fork控制的更容易(在线程里写disable fork就没有意义),所以直接实现了。
至于使用process类,简单好用,不会误伤到同名的线程,但是实际测试过程中,如果是同一个time-solt,那可能会都执行了,我代码的问题?。
module taa ();
initial begin
fork:thread_label
begin
#2 $display("a thread1");
disable thread_label;
end
begin
#3 $display("a thread2");
disable thread_label;
end
begin
#4 $display("a thread3");
disable thread_label;
end
join
$display("this is the end of fork join");
#10 ;
end
initial begin
fork
begin
#1 $display("a fork any thread1");
end
begin
$display("a fork any thread2");
end
begin
$display("a fork any thread3");
end
join_any
$display("this is the end of fork any");
disable fork;
#10 ;
end
initial begin
event e1;
fork:thread_label3
begin
#1 $display("a fork none thread_label3 thread1");
disable thread_label3;
end
begin
$display("a fork none thread_label3 thread2");
disable thread_label3;
end
begin
$display("a fork none thread_label3 thread3");
disable thread_label3;
end
join_none
wait fork;
$display("this is the end of fork none");
#10 ;
end
initial begin
process jobs[]=new[3];
fork
begin
jobs[0]=process::self;
#13 $display("a fork in thread1");
end
begin
jobs[1]=process::self;
#12 $display("a fork in thread2");
end
begin
jobs[2]=process::self;
#12 $display("a fork in thread3");
end
join_none
foreach(jobs[i]) begin
wait(jobs[i]!=null);
end
fork
jobs[0].await();
jobs[1].await();
jobs[2].await();
join_any
foreach (jobs[j]) begin
if(jobs[j].status != process::FINISHED )
jobs[j].kill();
end
$display("the end of process");
#10;
end
endmodule
输出
a fork any thread2
this is the end of fork any
a fork none thread_label3 thread2
this is the end of fork none
a thread1
this is the end of fork join
a fork in thread2
a fork in thread3
the end of process
断言的一个demo.
module tbb ();
reg clk, req, gnt;
sequence s1;
@(posedge clk) req ##1 gnt ##1 !req;
endsequence
initial begin
clk=0;
forever #5 clk=~clk;
end
initial begin
req=0;
gnt=0;
#5 req=1;
#11 req=0;
#5 gnt=1;
#12 gnt=0;
#30 $finish;
end
ass1:assert property(s1);
endmodule
输出
时间15开始,35结束的地方,有一个成功的案例。
断言
https://www.cnblogs.com/xh13dream/p/9134294.html
module tcc ();
reg a,b,c,d,e,f,g,h,i,j,k;
reg clk;
sequence s1;
@(posedge clk) a ##1 b ##1 c;
endsequence
ass1: assert property(s1);
sequence s2;
@(negedge clk) g ##1 h ##1 i;
endsequence
ass2: assert property(s2);
sequence s3;
@(posedge clk) a ##1 b ##[0:3] c;
endsequence
ass3: assert property(s3);
sequence s4;
a ##1 b ##[0:$] c;
endsequence
//ass4: assert property(s4); // can't pass compile
sequence s5;
@(posedge clk) d ##1 e ##1 s4 ##1 f;
endsequence
ass5: assert property(s5);
sequence s6;
@(posedge clk) a ##1 b ##1 b ##1 b ##1 c;
endsequence
sequence s7;
@(posedge clk) a ##1 b[*3] ##1 c;
endsequence
ass6: assert property(s6);
ass7: assert property(s7);
sequence s8;
@(posedge clk) a ##1 b[*3:5] ##1 c;
endsequence
ass8: assert property(s8);
sequence s9;
@(posedge clk) a ##1 b[->3:5] ##1 c;
endsequence
ass9: assert property(s9);
sequence s10;
@(posedge clk) a ##1 b[=3:5] ##1 c;
endsequence
ass10: assert property(s10);
sequence s11;
@(posedge clk) a ##[1:3] $rose(b);
endsequence
ass11: assert property(s11);
sequence s12;
@(posedge clk) a ##[1:3] $sampled(b);
endsequence
ass12: assert property(s12);
sequence s13;
@(posedge clk) a ##[1:3] $fell(b);
endsequence
ass13: assert property(s13);
sequence s14;
@(posedge clk) a ##[1:3] $stable(b);
endsequence
ass14: assert property(s14);
sequence s15;
@(posedge clk) a ##[1:3] $past(b);
endsequence
ass15: assert property(s15);
sequence s16;
@(posedge clk) (a ##1 b ##1 c ) and (c ##1 d ##1 e);
endsequence
ass16: assert property(s16);
sequence s17;
@(posedge clk) (a ##1 b ##1 c ) intersect (c ##1 d ##1 e);
endsequence
ass17: assert property(s17);
sequence s18;
@(posedge clk) first_match((a ##1 b ##1 c ) or (c ##1 d ##1 e));
endsequence
ass18: assert property(s18);
property s19;
@(posedge clk)
((!f))
throughout (##1 b ##1 c);
endproperty
ass19: assert property(s19);
sequence s20;
@(posedge clk) a ##1 b ##1 s18.ended ##1 d;
endsequence
ass20: assert property(s20);
initial begin
clk=0;
forever #5 clk=~clk;
end
always #1
begin
{a,b,c,d,e,f,g,h,i,j,k}=$random;
end
initial begin
#10000 $finish;
end
endmodule
在 10000个时间单位上测试,然后vcs观察结果。
s5: [0:$]
对于s5,嵌套后进行展开,s4中的[0:$]表示的0到无穷个时间单位内,出现c的变化。
sequence s5;
@(posedge clk) d ##1 e ##1 s4 ##1 f;
endsequence
ass5: assert property(s5);
s7: ##1 b[*3]
对于s7,##1 b[*3],表示3个时间单位上,b都为1。
sequence s6;
@(posedge clk) a ##1 b ##1 b ##1 b ##1 c;
endsequence
sequence s7;
@(posedge clk) a ##1 b[*3] ##1 c;
endsequence
ass6: assert property(s6);
ass7: assert property(s7);
s8: b[*3:5]
对于s8,b[*3:5]表示3到5个时间单位上,b都为1。
sequence s8;
@(posedge clk) a ##1 b[*3:5] ##1 c;
endsequence
ass8: assert property(s8);
s9:b[->3:5]
对于s9,b[->3:5]表示出现3到5个,时间单位上的b为1,且最后一个时间单位的上一个时间单位上b为1。
sequence s9;
@(posedge clk) a ##1 b[->3:5] ##1 c;
endsequence
ass9: assert property(s9);
s10:b[=3:5]
对于s10,##1 b[=3:5]表示出现3到5个,时间单位上的b为1,最后一个时间单位的上一个时间单位可以为0。
sequence s10;
@(posedge clk) a ##1 b[=3:5] ##1 c;
endsequence
ass10: assert property(s10);
s11: ##[1:3] $rose(b)
对于s11,##[1:3] $rose(b)表示1到3个时钟周期后,出现采样值,由原来的采样值从0变为现在的采样值1。
sequence s11;
@(posedge clk) a ##[1:3] $rose(b);
endsequence
ass11: assert property(s11);
s12: ##[1:3] $sampled(b)
对于s12,##[1:3] \(sampled(b)表示就是b,1到3个时间单位上出现b为1。(尽管在断言中使用\)sampled函数是被允许的,但它确实多余的,因为函数的结果与在断言中使用的表达式本身的采样值是相同的。IEEE17.7.3)
sequence s12;
@(posedge clk) a ##[1:3] $sampled(b);
endsequence
ass12: assert property(s12);
s13: ##[1:3] $fell(b)
对于s13,##[1:3] $fell(b),表示1到3个时间单位上出现采样值为下降沿。
sequence s13;
@(posedge clk) a ##[1:3] $fell(b);
endsequence
ass13: assert property(s13);
s14:$stable(b)
对于s14,表示1到3个时间单位上出现了保持相同值。如a=1,b=1----------------##1 b=0 ------------------##1 b=1 --------------------##1 b=1
sequence s14;
@(posedge clk) a ##[1:3] $stable(b);
endsequence
ass14: assert property(s14);
s15:##[1:3] $past(b)
对于s15,##[1:3] $past(b),采样上一个周期的值,表示0到2个时间单位上出现了b为1,但是在延后一个周期内才进行断言。
sequence s15;
@(posedge clk) a ##[1:3] $past(b);
endsequence
ass15: assert property(s15);
s16: and
对于s16,and表示都为真则为真,其中结束时间可以不同。断言的开始时间相同。
sequence s16;
@(posedge clk) (a ##1 b ##1 c ) and (c ##1 d ##1 e);
endsequence
ass16: assert property(s16);
s17:intersect
对于s17,intersect表示都为真则为真,其中结束时间需要相同。断言的开始时间相同。
sequence s17;
@(posedge clk) (a ##1 b ##1 c ) intersect (c ##1 d ##1 e);
endsequence
ass17: assert property(s17);
s18:or
对于s18,or进行的或判断。但是多个匹配条件成立后,first_match操作保留第一个匹配。(first_match操作符仅仅匹配其中的第一个。这就使得所有后续的匹配都不会被考虑。IEEE17.7.7)
sequence s18;
@(posedge clk) first_match((a ##1 b ##1 c ) or (c ##1 d ##1 e));
endsequence
ass18: assert property(s18);
s20: ended
对于s20,ended检查是否到达结束点。就是在d的前一个周期,s18断言结尾。
sequence s20;
@(posedge clk) a ##1 b ##1 s18.ended ##1 d;
endsequence
ass20: assert property(s20);
s19: throughout
对于s19, 在一个时间单位后b为真,然后过一个时间单位后c为真,期间f为假。(exp1 throughout seq2, means exp1 must be true when seq2 is matched.)
property s19;
@(posedge clk)
((!f))
throughout (##1 b ##1 c);
endproperty
ass19: assert property(s19);
事件触发值变化
module tdd ();
event a;
initial begin
$display("before event a is %d",a.triggered);
->a;
$display("after event a is %d",a.triggered);
#0
->a;
#1
$display("before event a is %d",a.triggered);
->a;
$display("after event a is %d",a.triggered);
->a;
->a;
end
always @(a) $display(" trigger event a is always %d", a.triggered);
endmodule
输出
before event a is 0
after event a is 1
trigger event a is always 1
trigger event a is always 1
before event a is 0
after event a is 1
trigger event a is always 1
低功耗细节
iff的那部分
module tee ();
reg clk, d, q, rst;
always @(posedge clk iff(rst==0), negedge rst)
begin
if(rst)
q<=0;
else
q<=d;
end
initial begin
$monitor("@%0t d %0d, q %0d , clk %0d rst %0d", $time, d, q, clk, rst);
end
initial begin
#0 rst=1;
d=1;
#10 rst=0;
#5 d=0;
#5 d=1;
#10 q=0;
#100 $finish;
end
initial begin
clk=0;
forever #1.1 clk=~clk;
end
endmodule
覆盖率的选项
module tff ();
class CovT;
// data or class properties
rand bit [4:0] a;
constraint c1 {a>1 ;a<6; };
endclass : CovT
CovT ct1=new;
covergroup Cov;
option.name="cover_name";
option.comment="this a comment";
option.per_instance=0;
option.goal=80;
c1: coverpoint ct1.a;
c2: coverpoint ct1.a;
c3: coverpoint ct1.a;
endgroup
initial begin
Cov cv=new;
$set_coverage_db_name("name132");
repeat(100) begin
//ct1.randomize();
ct1.a=$random;
cv.sample();
end
$display("the final %d", cv.get_coverage);
end
endmodule
per_instance默认的时候这个选项是0,是关闭的。instance,指covergroup的instance, 如果这个开关打开,那么每一个instance的覆盖率会被列出,否则只能看到一个综合的结果。
Le vent se lève! . . . il faut tenter de vivre!
Le vent se lève! . . . il faut tenter de vivre!