SystemVerilog的constrain的理解


我們知道virtual來修飾子函數,可以讓基類的指針指向擴展類,從而利用基類中的virtual函數可以復用擴展類中的同名函數。但是constrain呢?本小結就來詳細說明一下constrain。

我們通過一個例子來簡單聲明一下:

情況一:

    class bird;
    rand bit [1:0] src;
    rand bit [1:0] drc;
    constraint src_stim{src ==3;}
    constraint drc_stim{drc ==1;};
    endclass

    class parrot extends bird;
    constraint drc_stim{drc ==2;};
    endclass

     program ex6_14_tb;
      bird A;
      parrot B;
     
       initial begin
          A = new();
          B = new();
          assert(A.randomize());
          $display("A:src=%0d,drc=%0d",A.src,A.drc);
          assert(B.randomize());
          $display("A:src=%0d,drc=%0d",A.src,A.drc);
       end
      endprogram

打印結果是:
A:src=3,drc=1
B:src=3,drc=2

  • 如果B extends A的話,那么約束其實是可以重寫和繼承的。

情況二:

    class bird;
    rand bit [1:0] src;
    rand bit [1:0] drc;
    constraint src_stim{src ==3;}
    constraint drc_stim{drc ==1;};
    endclass

    class parrot extends bird;
    constraint drc_stim{drc ==2;};
    endclass

     program ex6_14_tb;
      bird A;
      parrot B;
     
       initial begin
          A = new();
          B = new();
          A = B;
          assert(A.randomize());
          $display("A:src=%0d,drc=%0d",A.src,A.drc);
          assert(B.randomize());
          $display("A:src=%0d,drc=%0d",A.src,A.drc);
       end
      endprogram

打印結果:
A:src=3,drc=2
B:src=3,drc=2

  • constrain,類似於virtual task,基類=擴展類;
  • 如果改成B = A,即擴展類=基類,那么編譯就會報錯!!

情況三:

    class bird;
    rand bit [1:0] src;
    rand bit [1:0] drc;
    constraint src_stim{src ==3;}
    constraint drc_stim{drc > 1;
                        drc < 6;};
    endclass

    class parrot extends bird;
    constraint drc_stim{drc ==2;};
    endclass

     program ex6_14_tb;
      bird A;
      parrot B;
     
       initial begin
          A = new();
          B = new();
    
          assert(A.randomize() with {drc ==3;});
          $display("A:src=%0d,drc=%0d",A.src,A.drc);
          assert(B.randomize());
          $display("A:src=%0d,drc=%0d",A.src,A.drc);
       end
      endprogram

打印結果:
A:src=3,drc=3
B:src=3,drc=2

  • randomize() with {} 是求解drc>1;drc<6;以及drc == 3的交集;

  • 如果with里面的東西與原來的約束沒有交集的話,那么會顯示約束求解錯誤。
    那么比如說我就有這樣的需求呢?有兩種解決方案:
    方案一:

     class bird;
      rand bit [5:0] src;
      rand bit [5:0] drc;
      constraint src_stim{src ==3;}
      constraint drc_stim{
                          drc > 1;
                          soft drc < 6;}; //******************
      endclass
    
      class parrot extends bird;
      constraint drc_stim{drc ==2;};
      endclass
    
       program ex6_14_tb;
        bird A;
        parrot B;
       
         initial begin
            A = new();
            B = new();
      
            assert(A.randomize() with {drc ==7;});
            $display("A:src=%0d,drc=%0d",A.src,A.drc);
            assert(B.randomize());
            $display("A:src=%0d,drc=%0d",A.src,A.drc);
         end
        endprogram
    

打印結果:
A:src=3,drc=7
B:src=3,drc=2

  • 用soft來修飾約束,這樣當with的約束和內部約束有沖突的時候,我們是以with里面的約束為准。

方案二:

   class bird;
    rand bit [5:0] src;
    rand bit [5:0] drc;
    constraint src_stim{src ==3;}
    constraint drc_stim{
                        drc > 1;
                        drc < 6;};
    endclass

    class parrot extends bird;
    constraint drc_stim{drc ==2;};
    endclass

     program ex6_14_tb;
      bird A;
      parrot B;
     
       initial begin
          A = new();
          B = new();
          A.drc_stim.constraint_mode(0); //*****************//
          assert(A.randomize() with {drc ==7;});
          $display("A:src=%0d,drc=%0d",A.src,A.drc);
          assert(B.randomize());
          $display("A:src=%0d,drc=%0d",A.src,A.drc);
       end
      endprogram

打印結果:
A:src=3,drc=7
B:src=3,drc=2

  • constraint_mode來關閉對應的約束,然后with里面的約束是最終的約束。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM