日常记录(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结束的地方,有一个成功的案例。
image

断言

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的覆盖率会被列出,否则只能看到一个综合的结果。

https://blog.csdn.net/seabeam/article/details/46369995

posted @ 2022-01-02 12:08  大浪淘沙、  阅读(80)  评论(0编辑  收藏  举报