Jump to content


  • Content Count

  • Joined

  • Last visited

Reputation Activity

  1. Like
    gaurav_brcm reacted to bhunter1972 in Randomization of dynamic arrays   
    The data array will be created implicitly based on the .size(), if it isn't already created, whenever you randomize the class.
    However, if you allow the simulator to do this implicitly, then you lose the ability to constrain any of the array's variables, which may or may not be something you care about.
    If you do, then here's how I do this.
    First, in my class's new function, I new the array to whatever the largest possible size will be. This is important, and perhaps a little wasteful.
    Second, I constrain the data.size() as you have above.
    Third, I can then constrain the data bytes, usually using a foreach constraint.
    When the class is randomized, the data will automatically re-size itself and constrain the data appropriately.
    So, like this:
    class pushk_c extends uvm_object; rand int unsigned data_len; constraint data_len_cnstr { data_len < MAX_DATA_LEN; // some parameter or constant } rand byte data[]; constraint data_cnstr { data.size() == data_len; foreach(data[idx]) { data[idx] == idx; } } function new(string name="pushk"); super.new(name); data = new[MAX_DATALEN]; endfunction : new endclass : pushk_c I would prefer not to self-promote, but I will anyway.  
    I demonstrate this a few times in my book: http://tinyurl.com/AdvancedUVM, or for the e-book: http://tinyurl.com/AdvancedUVM-ebook
  2. Like
    gaurav_brcm reacted to dave_59 in walk thru an enumeration   
    You can use a do-while loop:
    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 letters;        initial begin       $display("****** Walk thru an enumeration example. ***********");       letters = letters.first;       do begin          $display(" %0d *** %0s", letters, letters.name);      letters = letters.next;       end       while (letters != letters.first);   end endmodule : top
  3. Like
    gaurav_brcm reacted to imajeeth in SVA for fairness of Round-Robin Arbiter   
    This is my solution. Not necessarily the best one. Suggestions for improvements are welcome. If any of you find any shortcomings with this method, please let me know. Open to constructive criticism!
    Assume there are 3 requestors namely: A,B and C with reqA, reqB and reqC being the requests
    and gntA, gntB and gntC being the grants. 
    Assumes the request and grant are on the same cycle
    Similar sequence and assertions need to be replicated for each requestor. Can concatenate the requests and grants 
    into a bit vector, in order to save some redundant code
    //Denotes there is request and grant for the requestor A. Does not care about other requestors 
    logic requestorA_req_and_gnt;
    //Denotes there is request and grant for requestor A and there is atleast one other requestor active
    logic requestorA_req_and_gnt_with_other_requestors_active;
    //There are requests other than requestor A
    logic other_req_except_requestorA;
    //There are grants other than requestor A
    logic other_gnt_except_requestorA;
    assign other_req_except_requestorA = reqB | reqC; //High when any one of the other requestor's are active
    assign other_gnt_except_requestorA = gntB | gntC;
    assign requestorA_req_and_gnt = reqA & gntA;
    assign requestorA_req_and_gnt_with_other_requestors_active = reqA && other_req_except_requestorA && gntA;
    // Covers the case where there is request and grant on one cycle for requestorA, followed by no other requests. And then few cycles later there 
    // are multiple requests(reqA and atleast one other request). In this case, requestorA should NOT be granted again
    sequence requestorA_req_and_gnt_followed_by_other_req_seq;
    requestorA_req_and_gnt ##0 (!other_req_except_requestorA)[*1:$] ##1 reqA && other_req_except_requestorA;
    //Covers the case where there are more than one requestor active(reqA and any one of the other requests) followed by cycles of no other request at all
    // and again followed by more than one requestor active. First time during multiple requests, reqA is granted, so, the second time when multiple
    // requests are active, gntA should not be asserted again, and one of the other requests should be granted
    sequence multiple_requests_with_requestorA_req_and_gnt_followed_by_other_req_seq;
    requestorA_req_and_gnt_with_other_requestors_active ##1 (!other_req_except_requestorA)[*0:$] ##1 reqA && other_req_except_requestorA;

    //Covers the case where there are multiple requestors active in one cycle and next cycle may or may not have reqA, but will have other requests. 
    // If reqA is granted in the previous cycle, it should not be granted again in the next cycle, rather other requestor should be granted
    sequence back_to_back_multiple_requests_active_with_requestorA_gnted_followed_by_other_req_seq;
    requestorA_req_and_gnt_with_other_requestors_active ##1 other_req_except_requestorA;
    //Assertion to check if reqA do not hog the round robin arbiter
    assert_fairness_wrt_requestorA: assert property( @(posedge clk) disable iff(!resetn) 
    (requestorA_req_and_gnt_followed_by_other_req_and_no_bts_seq or
    multiple_requests_with_requestorA_req_and_gnt_followed_by_other_req_and_no_bts_seq or
    ) |-> other_gnt_except_requestorA && !gntA
    `uvm_info("ARB_ASSERT",$sformatf("Requestor A was previously granted, and not granted again, round robin scheme followed!"),UVM_LOW) 
    `uvm_error("ARB_ASSERT_ERR",$sformatf("Requestor A was previously granted, and gets granted again, round robin scheme not followed"))
  4. Like
    gaurav_brcm reacted to lisakb1963 in How to change the print format used by UVM?   
    I updated your code.  
    This is the quickest way of using the default printers classes:
    `uvm_info("REPORT", $sformatf("my_q[%0d]:\n%s",         i, my_q[i].sprint(uvm_default_line_printer)), UVM_LOW) // the uvm_default_printer is the uvm_default_table_printer, you can change it globally or pass one these declared printer classes: uvm_default_table_printer uvm_default_line_printer uvm_default_tree_printer I updated your code with the uvm_default_line_printer call and it works.