Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Posts posted by ljepson74

  1. *,

    How can I randomize with a dist and specify a weight for values not being inside a range?

     class randclass;
        rand logic [3:0] randvalue;
        function void post_randomize();
          $display("value: %0d",randvalue);
       constraint inside_practice {
         randvalue dist {
           [3:4] :/ 50,
           !(inside {[3:4]}) :/ 50    //<---  I try to have a sort of 'others' category here
    module top;
      randclass randclass;
      initial begin
        randclass = new();
        repeat (10) begin 


    Reference:  https://www.edaplayground.com/x/cV5 


    shaking off the rust after a SystemVerilog hiatus,



  2. I recently encountered SVA code which results in different results on different simulators.  I've shrunk it to a simple example here.

    I believe this code should cause an error, but it does not on all tools.   Can someone comment on how the 2017 LRM should be interpreted (and perhaps on the code).
    (I sense someone will comment on the driving signals in the code.)


    module top;
       bit   clk;
       logic sig1;
       logic disable_assert;
       always begin
          #5 clk=0;
          #5 clk=1;
       initial begin
         sig1          =1'b0;
         $display("Hello World");
         $monitor($time," **** sig1:%0b  disable_assert:%0b",sig1, disable_assert);
         repeat (3) @(posedge clk);
         @(posedge clk); sig1=0; disable_assert=1;
         @(posedge clk); sig1=1; disable_assert=1;  //2a. assertion would fail, but it is disabled
         @(posedge clk); sig1=0; disable_assert=0;  //2b. now assertion is enabled and should fail** 
         @(posedge clk); sig1=0; disable_assert=1;
       property as_disable_testing;
          @(posedge clk) disable iff (disable_assert)
       assert property (as_disable_testing);
    endmodule : top


    Question: Should there be a timing error at comment 2b, or not?


    Code is here to play around with: https://www.edaplayground.com/x/njR 
    Picture: https://docs.google.com/drawings/d/1qQB4dB5w8_1jx73xta46RbmLzkparaNcxHNdLgi8YNY/edit?usp=sharing 


    These are my thoughts:
    // It seems this small code snippet should cause an error, but tool results differ.
    // NOTE: Yes, I realize that I am using tools from BEFORE 2017, but comparing results to the 2017 LRM.
    // What is the correct LRM interpretation?  What comments do gurus have about this code?
    //1) Run the code with Aldec Riviera Pro 2015.06, Synopsys VCS 2014.10, and with Cadence Incisive 15.20.
    //   RIVIERA PRO and IRUN show assertion failures.
    //     VCS does not show assertion failure.
    //2a) This is time when sig1=1 assertion 'would' fail, but it is disabled (disable_assert==1)
    //2b) **On next clock cycle the assertion set to be enabled (i.e. disable_assert==0).
    //    The SystemVerilog 2017 LRM (1800.1-2017.pdf) describes the behaviour.
    //    At the start of the 2b time slot (see page 64 of SystemVerilog LRM 1800.1-2017),
    //      PREPONED REGION: the values of the assertion are sampled (sig1==1)
    //      ACTIVE/INACTIVE/NBA regions: the values are updated (sig1,disable_assert)
    //                                   (so you can use either blocking "="
    //                                    or you can use non-blocking "<="
    //                                    and you will get the same result)
    //                                    So for this time slot: sig1==0, disable_assert=0
    //      OBSERVED REGION: this is where the assertion is evaluated, using values sampled from 
    //                                    the preponed region (so sig1==1).
    //                                    However, the value of disable_assert is not from the 
    //                                    preponed region, but simply whatever the value is, 
    //                                    as assigned in the active/inactive/nba region. 
    // Section 16.6 of the SystemVerilog LRM (1800.1-2017 states: "The expressions in a disable condition are evaluated using the current values of variables (not sampled) ..."  I believe this means from whatever is set in the Active/NBA region of current time slot.
    // Section 16.12 of the same document states: "If the disable condition is true at anytime between the start of the attempt in the Observed region, inclusive, and the end of the evaluation attempt, inclusive, then the overall //evaluation of the property results in disabled."
    // My conclusion: The sig1 value from 2a will be used in 2b when disable_assert=0;  ***Assertion should fail.***
    // Picture: https://docs.google.com/drawings/d/1qQB4dB5w8_1jx73xta46RbmLzkparaNcxHNdLgi8YNY/edit?usp=sharing






  3. Both the 2005 and 2017 LRMs contain this statement:


    "The step time unit is equal to the global time precision."

    The 2017 LRM also states:


    "The global time precision, also called the simulation time unit, is the minimum of all the timeprecision
    statements, all the time precision arguments to timeunit declarations, and the smallest time precision
    argument of all the `timescale compiler directives in the design."


    So, in searching for the definition of "time step", as used in the 2017 LRM, I should have been searching for just "step".

    In response to my question above, I offer the following definition of the relationship between "time slot" and "time step".

    A "time step" is the distance between two adjacent "time slot"s, or is simply used to refer to a successive "time slot".   i.e. When you advance a "time step", you simply move to the next time slot.

  4. As used in the SystemVerilog LRM, 1800.1-2017.pdf, what is the difference between these two terms? 

    The first seems well defined.  The second, not so much.

    * time slot

    * time step




    Cliff Cummings/Sunburst Design wrote the following in CummingsSNUG2006Boston_SystemVerilog_Events.pdf:


    "The IEEE Std 1800-2005 standard sometimes referred to a time slot as a timestep, but the term timestep has been removed from the P1800-2008 Draft Standard."

    If that is correct, then it seems the term 'time step' has returned.

  5. Regarding:

    'Is it really required?'


    I would not say that a phase is required and I would not say it is not required.

    The uvm phases will be passed through in succession, as a simulation runs.

    I would simply say "they will happen".   In a normal UVM flow, there is no way to make a phase not happen**.


    I think the question you want to ask is whether you, a user, or a test/testbench, needs to use the end_of_elaboration_phase (or any phase).   The answer to that, is no.  If you do not specify a function or task for the specific phase (and raise an objection if necessary), it will simply pass through.


    italiya listed some things that might be done in that phase, but as pointed out, could be done in other phases as well.***


    uvm phases, for the most part, are artificial sections of time, to help developers organize code more consistently.

    Silly, off-the-cuff analogy:
    Everyone on this forum decides to run their lives a certain way, on a certain schedule.
    6am-7am:    wake, eat_breakfast, empty_garbage
    10am-11am:  go_to_work
    2pm-4pm:    cigar_break
    9pm-10pm:   go_home, eat_dinner, sleep
    When you visit italiya, you'll know that you can expect breakfast in the time "6am-7am".  You'll know the rules of his home.
    Italiya could decide to eat_breakfast in the time "11am-2pm" instead, or to not eat_breakfast at all (like not using the end_of_elaboration_phase), and things will be fine, but it might cause confusion for his guests who expect the above schedule.
    In verification the uvm phase guidelines should help us all more quickly understand each others' tests and testbenches.
    Just as Italiya cannot go_to_work before wake, there are certain things in our testbenches that must happen in a certain order.  For example, we must build/instantiate our testbench parts, before we generate stimulus or do anything else.  The structuring of phases help us to keep that order. 

    **Well, certainly one could choose to end a test in any phase, before all phases are completed, or to phase jump.  But, in a typical flow, all phases will happen.


    ***Besides time-consuming items being required to happen in the run_phase (or it's sub phases), and besides building of components before the run_phase (?), I am not sure what else is restricted to a certain phase or group of phases.   An important distinction that was never so clear to me when I started is that the run_phase and it's sub phases are tasks (which can consume time), the other phases are functions (which cannot consume time).


    I'm prepared for clarifications/corrections from others, but that's my understanding.



    //This forum tool seems to be adding interesting colors to this post based on my use of ' and formatting buttons.

  6. Yes, thanks Dave.  (I shouldn't assume everyone I've seen on here monitors all the threads.)

    Feedback from Victor (the creator of edaplayground) on the edaplayground forum:

    I've seen this before. The server uses "\r\n" DOS line endings, and some simulators don't grok these. The fix for EDA Playground would be to use "\n" line endings instead of "\r\n"
    You can see this by using "Download files after run"

  7. Thanks, Tudor and Dave.

    *) I updated the urls, per Tudor comment.

    *) Aldec and Mentor simulators were the two that I did not use.  I now tried Aldec on edaplayground and see that it works.  Unfortunately, with regards to this SV feature, I'm not using either of these simulators.  Can anyone confirm that neither Cadence nor Synopsys support this?  (Well, I guess I've figured out that they don't, now that I have witnessed at least one simulator support it.  Aldec's.)




  8. A backslash can be used to extend a string literal onto the next line if "the new line is immediately preceded by a \ (backslash)."

        Section 5.9 of 1800-2012.pdf, the SystemVerilog LRM


    I don't think I have ever been able to get this work and w/o looking I seem to recall it has been in Verilog/SystemVerilog for a while.


    Can someone tell me if vendors support this and perhaps correct the code below on edaplayground?


    example from LRM:

    $display("Humpty Dumpty sat on a wall. \
    Humpty Dumpty had a great fall.");

    See example here (on Sept 29, urls below are updated in response to Tudor comment below.  thx.):


    https://www.edaplayground.com/x/4Tyw    //if the above does not work, try this one, with https://

  9. Thanks, Dave.


    To be clear, as I understand, "synchronize that process to the clocking block event" in this case means a call to 



    Good.  I'm moving to use such calls for the advancement of time (mostly in drivers and monitors/collectors), instead of calls like 

    @(posedge my_play_if.clock);  or  @(posedge clk);.



    Can you provide a pseudo-code example of "interacting with clocking block inputs ##0 delays"?


    As I understand**, if there is a default clocking_block (and only if), we can use cycle delays (i.e. ## integral_number) and that will cause a wait for the specified number of clocking events (even if the first is in the current time step).  

    But as long as the input clocking_skew specifies some time before the clocking event, I don't see where a problem would arise by using ##0;.



    Note: Outside of assertions, I don't think I've ever used cycle delays.  Also, I don't use default clocking_blocks, for better or worse.


    ** 1800-2012.pdf  Section "14.11 Cycle delay: ##"

    Note: I've updated the original post to highlight the querys with "Q1)" and "Q2)".

  10. Q1) I'd like confirmation that the following waits for a posedge of clk are identical.  (The code it refers to is far below.)

      1) @(posedge my_play_if.clock);  or  @(posedge clk);
      2) @(my_play_if.cb1);

    Q2) I'd also like to confirm that input and output clocking_skew of a clocking block have no effect on the inputs of the interface.  They only affect the inputs and outputs of that clocking block.



    I'm pretty confident about both of these and the SystemVerilog LRM seems clear, but I want to confirm while I am cleaning up some inherited code which is not currently working.


    Reference: SystemVerilog Standard 1800-2012.pdf, Section "14. Clocking blocks"


    Below is some sample code I was hacking around with.

    //Interface, clocking blocks, and waiting for clock edge
    interface play_if(input bit clock);
       clocking cb1 @(posedge clock);
          default input #2 output #2; //clocking_skew is irrelevant to interface inputs, right?
    module top;
       bit      clk;
       play_if  my_play_if(.clock(clk));
       always #5 clk=~clk;
       initial begin
          $monitor($time," clk=%1b",clk);
          #100 $finish;
       task tclk();
          $display($time,"     pre-clk");
          @(posedge my_play_if.clock);
          $display($time,"     post-clk");
       task tcb1();
          $display($time,"     pre-cb1");
          $display($time,"     post-cb1");
       initial begin
          $display($time," --------------START");
          @(posedge my_play_if.clock);
          @(posedge my_play_if.clock);
          @(posedge my_play_if.clock);
          $display($time," --------------FINISH");
    endmodule : top

  11. How can I check which VCS version I am using, from a Linux command line?



    I don't want to run a sim to find this information.

    I am looking for smthg like "irun -version", but for VCS.




    Pre-post discovery:  It looks like "vcs -help", among other things, shows the compiler version.  


    Afaik, the compiler version and simulator version are the same.  Right?  Normally, I wouldn't ask that, but I see/know that some tools (or subsections of tools) don't move in lock-step for versions (like simulators and waveform viewers).




    (Posting here because I didn't easily find this in VCS documentation and had SolvNet problems, and I find it better not to ask non-proprietary questions where the answer is available to the public.)


  12. How can I use "randomize() with" along with "inside", on the same line?


    Below is some code that solves the problem using >= and <=, but I'd like to use "inside".

    module top;
    class aclass;
       int index;
       function void get_latency;
          //assert (randomize(index) with {index inside {[1:5]}}) else begin  //WHAT IS THE PROPER SYNTAX?
          //assert (randomize(index) inside {[1:5]}) else begin               //WHAT IS THE PROPER SYNTAX?
          assert (randomize(index) with {index<=5;  index>=1;}) else begin    //WORKS
             $display("ERROR:  We failed!");
          $display("RESULT: index=%0d",index);
       initial begin
          aclass a_class=new();

    I often grapple with the "randomize with" syntax, getting confused with squiggly brackets and semicolons, and refer to the LRM.  (Any tips that will stick in my head are welcome.)


  13. Tudor/Tinku,

     Thank you very much.


     I had considered these following variations (and will now make doubly sure they're clear in my mind):

      disable iff (write_valid) !$isunknown(write_data) //use disable iff for asynchronous disabling

      write_valid |-> !$isunknown(write_data) //Recommended

      !(write_valid && $isunknown(write_data)) //***See below

     I had not thought about synchronicity with regards to disable iff, so thanks a lot for enlightening me, Tudor.  (***And in another post we discussed implication versus logical AND.  http://forums.accellera.org/topic/5407-overlapped-implication-vs-logical-and-vs/ )


     , ... but the focus of the topic, which I may not have presented clearly enough was what Tinku showed.   I was hoping there was some way to avoid using a generate, but that solution seems very clear.


     Thank you for shedding light on parts of the example I hadn't even thought much about yet.

  14. Consider the following code and the assertion to check for unknown data.


    If the code will change so that there will now be an array of valids and datas, what is the best way to change the assertion, so that for each valid, the corresponding data is checked.?

    Can I do it one line?   (I had been considering using a generate statement around it.)

    module top;
       bit   clk;
       logic write_valid;
       logic write_data;
       always clk = #5 !clk;
       initial begin
       as_showme : assert property (@(posedge clk) disable iff (!write_valid) (!$isunknown(write_data)) ) else begin
          $display("*** ERROR. write_data was unknown. ***");

  15.  Yesterday, I learned that when randomize is called, all active constraints in the scope must be met ... even if you are passing a specific member as an argument to the randomize call.
     i.e. If you try to randomize a specific class member by passing it to the randomize call, like this: randomize(var2), all constraints in the scope of the randomize must still be met, even if they have nothing to do with the member being randomized.
     ***Someone please jump in if I phrased that poorly or am incorrect.
     In the below example there are two variables and a constraint on one.
     Uncommenting the line that causes the constraint on var1 to be violated will cause the later call to randomize to fail, even though it is passed an argument (var2) that has nothing to do with var1.
    class showit;
       rand int var1;
       rand int var2;
       constraint c_1 { var1<100; }
    module top;
       showit showit;
       initial begin
          //showit.var1=101;   UNCOMMENT ME, PLEASE FOR FAIL
          as_myassert : assert(showit.randomize(var2)) begin
             $display("\n********** Victory : var2=%0d var1=%0d \n",showit.var2, showit.var1);
          end else begin
             $display("\n********** Defeat  : var2=%0d var1=%0d \n",showit.var2, showit.var1);
    endmodule : top

    Pass result:

    ********** Victory : var2=-1424717967 var1=0

    Fail result:

    ********** Defeat  : var2=0 var1=101


     I now understand randomize better.  I had thought that only the constraints that pertained to the items being randomized were relevant.


  16. I needed to step thru an enum in a testbench today.  As it took me a while to figure out how to do it, I post a small example here.
    I want to do it without making any assumptions of the values of the enums (values are the default type of int, in this case).
    Reference: SystemVerilog doc "1800-2012.pdf" Section 6.19 Enumerations
    module top;
       //typedef enum {alpha=0, beta=1, gamma=2, delta=3, epsilon=4} greek;  //to show default assignments
       typedef enum {alpha, beta, gamma, delta, epsilon} greek;
       greek letters2;
       initial begin
          $display("****** Walk thru an enumeration example. ***********");
          for (greek letters=letters.first(), int walk=0;
               walk < letters.num();
               letters=letters.next(), walk++) begin
               $display(" %0d *** %0s", letters, letters.name);
    endmodule : top
    ****** Walk thru an enumeration example. ***********
     0 *** alpha
     1 *** beta
     2 *** gamma
     3 *** delta
     4 *** epsilon
    I'm also posting here, because when I am trying to remember how to do something, I find it often easier to find my postings online than an example in my own code.
    I thought I did this nicely with a foreach loop, but cannot find it, so may be imagining it.
    I was not keen on having to use variable walk.  If someone can show me how to do this with a foreach loop or without using an extra variable, like I did with "walk", please do.
    Noted failures:
          for (greek letters=letters.first(); letters!=letters.last();    letters=letters.next()) begin //shows only 0-3
          for (greek letters=letters.first(); letters<=(letters.num()-1); letters=letters.next()) begin //neverending loop


  • Create New...