Quantcast
Channel: UVM SystemVerilog Discussions Forum RSS Feed
Viewing all 410 articles
Browse latest View live

Register read via register model.

$
0
0

I am reading a register with using uvm_reg method read_reg.

so while doing this read transaction is happening on to the actual bus through agent  ,but the I am not getting read value in read_reg task in to a register sequence.

so I want to know what could be the issue for not getting read value on to the read_reg task.

 

Regards

sega 


VCS problem with SystemVerilog

$
0
0

Hi,experts,

I am now running into one problem about VCS. Now give a simple descripton about it, I use VCS201209 to compile pieces of verification code, there is no any compiling error,but run time error appears. The code is as follows:
            1868 //pcie_item.first_be = {{(length % `DW_BYTE_COUNT){1'b1}}, {(`FDW_BE_WIDTH - (length % `DW_BYTE_COUNT)){1'b0}}}; // change because of the run time error
            1869 if ((`FDW_BE_WIDTH - (length % `DW_BYTE_COUNT)) == 0) begin
            1870   pcie_item.first_be = {(length % `DW_BYTE_COUNT){1'b1}};
            1871 end     
            1872 else begin
            1873   pcie_item.first_be = {{(length % `DW_BYTE_COUNT){1'b1}}, {(`FDW_BE_WIDTH - (length % `DW_BYTE_COUNT)){1'b0}}};
            1874 end

`DW_BYTE_COUNT=4; `FDW_BE_WIDTH=4, length is one bit_stream type variable. line 1868 has been commented, changed to line 1869-1874. The reason why i change it is that there is such a run time error:
../sv/04_ref_model/ref_model.sv, line 1868: ** OTENF: S QOP_CONCAT (S,S) /* {} */
Note: OTENF is an internal error meaning Op_Table Entry Not Found
Assertion failed " Note: Set environment variable VCS_REPORT_ALL_OTENF to get all the OPTENF errors." at line 711 in file fun.c

An unexpected termination has occurred in /EDA_Tools/synopsys/vcs1209/linux/bin/vcs1

at ../sv/04_ref_model/ref_model.sv, 1730
During Codegen 
During Pass2 Module vcs_paramclassrepository Module vcs_paramclassrepository



--- Stack trace follows:
[Thread debugging using libthread_db enabled]
[New Thread 0xf7be9bb0 (LWP 24498)]
0xffffe405 in __kernel_vsyscall ()

Thread 2 (Thread 0xf7be9bb0 (LWP 24498)):
#0  0xffffe405 in __kernel_vsyscall ()
#1  0x00aebb26 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/tls/libpthread.so.0
#2  0x0aee7e64 in ?? ()
#3  0x00ae9371 in start_thread () from /lib/tls/libpthread.so.0
#4  0x00a41ffe in clone () from /lib/tls/libc.so.6
Backtrace stopped: Not enough registers or memory available to unwind further

Thread 1 (Thread 0xf7fd2700 (LWP 24497)):
#0  0xffffe405 in __kernel_vsyscall ()
#1  0x00a0447b in waitpid () from /lib/tls/libc.so.6
#2  0x009ae349 in do_system () from /lib/tls/libc.so.6
#3  0x009ae6c1 in system () from /lib/tls/libc.so.6
#4  0x00aef78d in system () from /lib/tls/libpthread.so.0
#5  0x0b3bc389 in tracker::StackAnnotator::getGdbOutput(char const*, char const*, char const*) ()
#6  0x0b3bd677 in tracker::StackAnnotator::dumpProcessStack(unsigned int, char const*, char const*) ()
#7  0x0b3b29c6 in dumpStackTrace ()
#8  0x0b3b74e7 in vcsAssertNoReturn ()
#9  0x08fbbf0d in ?? ()
#10 0x08fbc1c8 in BuildFUNsForRout ()
#11 0x0907ff8c in BuildMOPsForRout ()
#12 0x08f4e069 in ?? ()
#13 0x08f4f12e in ?? ()
#14 0x08f52423 in CodeGenC ()
#15 0x09187f31 in Phase234 ()
#16 0x08806fba in ?? ()
#17 0x088214ab in ?? ()
#18 0x088238ee in DoPass2 ()
#19 0x0876b5ab in doGAToPass2 ()
#20 0x0876be7a in c_main ()
#21 0x09293842 in main ()
Completed context dump phase location* 'Module' 'Module'
CPU time: 33.817 seconds to compile
make: *** [comp] Error 255

I have done the error analysis, my concept is that maybe the reason is that the value of `FDW_BE_WIDTH - (length % `DW_BYTE_COUNT) has the possibility of zero. So I add the judge condition about the value of `FDW_BE_WIDTH - (length % `DW_BYTE_COUNT), but it still reports the same error about line 1873. If I comment line 1873, the error disappears. It seems like that the problem has something to do with the action of compiler's analyzing the code.

 

Could any expert give me some information?

Thanks in advance.

How to use a variable defined in one class into another class?

$
0
0

Hello all,
Can A variable defined and used in one task, in one class, be used as it is in another class?But these two classes are completely independent of each other,in other words, they are not inherited from one another. So with this situation, can a variable defined in class Driver, be utilized in class monitor? For eg, I need to use a variable pkt_length (defined and used in driver class) in monitor class also so that I can use it in order to get the packets unpacked in monitor class.

Please help me with this querry. Thanks,

Help in resolving this error?

$
0
0
Hello all UVM geeks,
 
I am getting the following error.
 
 Error: monitor71.sv(69): The actual (dataout) and formal (bytestream) for a ref must be equivalent types.
 
Can someone please help me in resolving this error? I want to decode 10bits data received from DUT into 8bits by using 10b8b decoder, which I have used but its giving error when I am trying to put each 10bits received (after collecting them into an array) and then putting each 10bits into decoder to get 8bits and then unpack bytes to create packets. Code is also given below. Its kinda urgent,
 
[code=auto:0]
`include "uvm_macros.svh"
 import uvm_pkg::*;
 
class monitor extends uvm_monitor; 
        //Registration of monitor with the factory.
       `uvm_component_utils(monitor)
 
        virtual dut_if dut_vi; 
         
        // uvm_analysis_port #(transaction) Montr2Sb_port;
       uvm_analysis_port #(transaction) Montr2Agnt_port;  
       
                         
          //constructor by using keyword new
       function new(string name, uvm_component parent);
            super.new(name, parent);
       endfunction: new
               
            
       function void build_phase(uvm_phase phase);
            super.build_phase(phase);  
            assert( uvm_config_db #(virtual dut_if)::get(this, "", "dut_vi", dut_vi) );
            Montr2Agnt_port = new("Montr2Ag", this);            
       endfunction : build_phase
       
       
      task run_phase(uvm_phase phase);
         transaction pkt; 
              fork
              
              forever
               begin
                bit [9:0] bq[$],bytestream[];
                bit [9:0] dataout[];
              
                int j;
                int pkt_len = 13; 
              //  bit [9:0] unsigned bq[$];
               // bit[9:0] unsigned bytestream[]; //keep it like this as the unpack_bytes take unsigned bytestream[].This works too.
             $display("san14- Display of the packet contents %h",dut_vi.data);
             
               
               repeat(3)@(dut_vi.clock); //keep repeat(3) at 3 only in order to match the first byte.Its needed
              
              for ( int j = 0; j < pkt_len ; j++) 
              
                begin
                       $display("san- Display of the packet contents %h",dut_vi.data);
                       
                       @(dut_vi.clock);  
                       $display("san12- Display of the packet contents %h",dut_vi.data);
                       bq.push_back(dut_vi.data);  //getting data from dut_if and putting in queue by pushing in it
                       
                       @( dut_vi.clock); 
                       $display("san11- Display of the queue contents %p",bq);
                       
                       uvm_report_info(get_full_name(),"Ready to Get out of the Foreach/For loop ...",UVM_LOW);
                end
                 
               uvm_report_info(get_full_name(),"Got out of the Foreach loop ...",UVM_LOW);
               
               $display("san31- Display of the queue contents %h",bq.size());
               bytestream = new[bq.size()] (bq);  //(bq)
               
               $display("san32- Display of the bytes array contents %h",bytestream);
               pkt = transaction::type_id::create("pkt1");
               uvm_report_info(get_full_name(),"Started unpacking of received bytes ...",UVM_LOW); 
               decode(bytestream);
               void'(pkt.unpack_bytes(dataout)); //ERROR IS POINTING AT THIS LINE.
               
               pkt.print();
               uvm_report_info(get_full_name(),"Completed unpacking of received bytes ...",UVM_LOW);
               //pkt.print();
               Montr2Agnt_port.write(pkt);
               
               $display("san34- Display of the bytes array contents %h",bytestream);          
                
                uvm_report_info(get_full_name(),"Sending received packet from monitor to the Scoreboard ...",UVM_LOW);
                
              end
             join
       endtask: run_phase 
         
      
             
   
    virtual function decode(bytestream);
        
        bit [9:0]bytestream[]; 
        
        uvm_report_info(get_full_name(),"Decoding Each 10bits into 8bits ...",UVM_LOW); 
             
        foreach (bytestream[k])       
          begin          
           
           bit dispin ;
           
           bit [9:0] dataout ;  //output bytes of decoder
        
            reg[9:0] datain = bytestream[k];
           logic code_err ;
           logic disp_err ;
 
           logic ai = datain[0] ;
           logic bi = datain[1] ;
           logic ci = datain[2] ;
           logic di = datain[3] ;
           logic ei = datain[4] ;
           logic ii = datain[5] ;
           logic fi = datain[6] ;
           logic gi = datain[7] ;
           logic hi = datain[8] ;
           logic ji = datain[9] ;
 
           logic aeqb = (ai & bi) | (!ai & !bi) ;
           logic ceqd = (ci & di) | (!ci & !di) ;
           logic p22 = (ai & bi & !ci & !di) |
              (ci & di & !ai & !bi) |
              ( !aeqb & !ceqd) ;
           logic p13 = ( !aeqb & !ci & !di) |
              ( !ceqd & !ai & !bi) ;
           logic p31 = ( !aeqb & ci & di) |
              ( !ceqd & ai & bi) ;
 
           //logic p40;
            //datain = pout;
           logic p40 = ai & bi & ci & di ;
           logic p04 = !ai & !bi & !ci & !di ;
 
           logic disp6a = p31 | (p22 & dispin) ; // pos disp if p22 and was pos, or p31.
           logic disp6a2 = p31 & dispin ;  // disp is ++ after 4 bits
           logic disp6a0 = p13 & ! dispin ; // -- disp after 4 bits
             
           logic disp6b = (((ei & ii & ! disp6a0) | (disp6a & (ei | ii)) | disp6a2 |
           (ei & ii & di)) & (ei | ii | di)) ;
 
              // The 5B/6B decoding special cases where ABCDE != abcde
 
           logic p22bceeqi = p22 & bi & ci & (ei == ii) ;
           logic p22bncneeqi = p22 & !bi & !ci & (ei == ii) ;
           logic p13in = p13 & !ii ;
           logic p31i = p31 & ii ;
           logic p13dei = p13 & di & ei & ii ;
           logic p22aceeqi = p22 & ai & ci & (ei == ii) ;
           logic p22ancneeqi = p22 & !ai & !ci & (ei == ii) ;
           logic p13en = p13 & !ei ;
           logic anbnenin = !ai & !bi & !ei & !ii ;
           logic abei = ai & bi & ei & ii ;
           logic cdei = ci & di & ei & ii ;
           logic cndnenin = !ci & !di & !ei & !ii ;
 
              //non-zero disparity cases:
           logic p22enin = p22 & !ei & !ii ;
           logic p22ei = p22 & ei & ii ;
                //logic p13in = p12 & !ii ;
                //logic p31i = p31 & ii ;
           logic p31dnenin = p31 & !di & !ei & !ii ;
                //logic p13dei = p13 & di & ei & ii ;
           logic p31e = p31 & ei ;
 
           logic compa = p22bncneeqi | p31i | p13dei | p22ancneeqi | 
          p13en | abei | cndnenin ;
           logic compb = p22bceeqi | p31i | p13dei | p22aceeqi | 
          p13en | abei | cndnenin ;
           logic compc = p22bceeqi | p31i | p13dei | p22ancneeqi | 
          p13en | anbnenin | cndnenin ;
           logic compd = p22bncneeqi | p31i | p13dei | p22aceeqi |
          p13en | abei | cndnenin ;
           logic compe = p22bncneeqi | p13in | p13dei | p22ancneeqi | 
          p13en | anbnenin | cndnenin ;
 
           logic ao = ai ^ compa ;
           logic bo = bi ^ compb ;
           logic co = ci ^ compc ;
           logic d0 = di ^ compd ;
           logic eo = ei ^ compe ;
 
           logic feqg = (fi & gi) | (!fi & !gi) ;
           logic heqj = (hi & ji) | (!hi & !ji) ;
           logic fghj22 = (fi & gi & !hi & !ji) |
          (!fi & !gi & hi & ji) |
          ( !feqg & !heqj) ;
           logic fghjp13 = ( !feqg & !hi & !ji) |
          ( !heqj & !fi & !gi) ;
           logic fghjp31 = ( (!feqg) & hi & ji) |
          ( !heqj & fi & gi) ;
 
           logic dispout = (fghjp31 | (disp6b & fghj22) | (hi & ji)) & (hi | ji) ;
 
           logic ko = ( (ci & di & ei & ii) | ( !ci & !di & !ei & !ii) |
          (p13 & !ei & ii & gi & hi & ji) |
          (p31 & ei & !ii & !gi & !hi & !ji)) ;
 
           logic alt7 =   (fi & !gi & !hi & // 1000 cases, where disp6b is 1
          ((dispin & ci & di & !ei & !ii) | ko |
           (dispin & !ci & di & !ei & !ii))) |
          (!fi & gi & hi & // 0111 cases, where disp6b is 0
          (( !dispin & !ci & !di & ei & ii) | ko |
           ( !dispin & ci & !di & ei & ii))) ;
 
           logic k28 = (ci & di & ei & ii) | ! (ci | di | ei | ii) ;
                  // k28 with positive disp into fghi - .1, .2, .5, and .6 special cases
           logic k28p = ! (ci | di | ei | ii) ;
           logic fo = (ji & !fi & (hi | !gi | k28p)) |
             (fi & !ji & (!hi | gi | !k28p)) |
             (k28p & gi & hi) |
             (!k28p & !gi & !hi) ;
           logic go = (ji & !fi & (hi | !gi | !k28p)) |
             (fi & !ji & (!hi | gi |k28p)) |
             (!k28p & gi & hi) |
             (k28p & !gi & !hi) ;
           logic ho = ((ji ^ hi) & ! ((!fi & gi & !hi & ji & !k28p) | (!fi & gi & hi & !ji & k28p) | 
             (fi & !gi & !hi & ji & !k28p) | (fi & !gi & hi & !ji & k28p))) |
             (!fi & gi & hi & ji) | (fi & !gi & !hi & !ji) ;
 
           logic disp6p = (p31 & (ei | ii)) | (p22 & ei & ii) ;
           logic disp6n = (p13 & ! (ei & ii)) | (p22 & !ei & !ii) ;
           logic disp4p = fghjp31 ;
           logic disp4n = fghjp13 ;
 
           //assign 
           code_err = p40 | p04 | (fi & gi & hi & ji) | (!fi & !gi & !hi & !ji) |
             (p13 & !ei & !ii) | (p31 & ei & ii) | 
             (ei & ii & fi & gi & hi) | (!ei & !ii & !fi & !gi & !hi) | 
             (ei & !ii & gi & hi & ji) | (!ei & ii & !gi & !hi & !ji) |
             (!p31 & ei & !ii & !gi & !hi & !ji) |
             (!p13 & !ei & ii & gi & hi & ji) |
             (((ei & ii & !gi & !hi & !ji) | 
               (!ei & !ii & gi & hi & ji)) &
              ! ((ci & di & ei) | (!ci & !di & !ei))) |
             (disp6p & disp4p) | (disp6n & disp4n) |
             (ai & bi & ci & !ei & !ii & ((!fi & !gi) | fghjp13)) |
             (!ai & !bi & !ci & ei & ii & ((fi & gi) | fghjp31)) |
             (fi & gi & !hi & !ji & disp6p) |
             (!fi & !gi & hi & ji & disp6n) |
             (ci & di & ei & ii & !fi & !gi & !hi) |
             (!ci & !di & !ei & !ii & fi & gi & hi) ;
 
           //assign 
            dataout = {ko, ho, go, fo, eo, d0, co, bo, ao} ;
 
              // my disp err fires for any legal codes that violate disparity, may fire for illegal codes
            //assign 
            disp_err = ((dispin & disp6p) | (disp6n & !dispin) |
               (dispin & !disp6n & fi & gi) |
               (dispin & ai & bi & ci) |
               (dispin & !disp6n & disp4p) |
               (!dispin & !disp6p & !fi & !gi) |
               (!dispin & !ai & !bi & !ci) |
               (!dispin & !disp6p & disp4n) |
               (disp6p & disp4p) | (disp6n & disp4n)) ;
               
             uvm_report_info(get_full_name(),"Decoded Each 10bits into 8bits ...",UVM_LOW);
             $display("SM02- Display of the Decoded data contents %h",dataout);
          end
      endfunction: decode 
 
 endclass: monitor
 
[\code]
 
Thanks,

Pipelined RAL access

$
0
0

I am using UVM RAL (version 1.1c) and with my bus agent which supports pipelined requests and out of order responses. In RAL adapter I have set provides_responses=1.  Now when I have two read requests active in same sequence under fork-join. Now response can come in any order. I see that once the response comes for any read requests, RAL unblocks both the read requests. I looked into source code and I found that in uvm_reg_map::do_bus_read() API, while calling get_base_response(), it does not pass the "transaction_id" as an argument. So it takes default = -1 which mean it waits for response and if any response comes, it returns that does not seem right. As I have initiated both read requests from same sequence,there will be only one parent sequence(rw.parent) and responses for both read request will land in same "response_queue".  Now while picking the response from parent sequence "response_queue", we should have use the "transaction_id". 

 

I would like to know if I am making any mistake to understand the behavior or it is indeed an issue.

 

 

uvm_reg_map::do_bus_read() implementation:

======================================

   if (adapter.provides_responses) begin
        uvm_sequence_item bus_rsp;
        uvm_access_e op;
        // TODO: need to test for right trans type, if not put back in q
        rw.parent.get_base_response(bus_rsp);
        adapter.bus2reg(bus_rsp,rw_access);
      end
 

======================================

 

 

uvm_sequence_base::get_base_response task implementation:

 

==========================================

virtual task get_base_response(output uvm_sequence_item response, input int transaction_id = -1);

    int queue_size, i;

    if (response_queue.size() == 0)
      wait (response_queue.size() != 0);

    if (transaction_id == -1) begin
      response = response_queue.pop_front();
      return;
    end

    forever begin
      queue_size = response_queue.size();
      for (i = 0; i < queue_size; i++) begin
        if (response_queue[i].get_transaction_id() == transaction_id)
          begin
            $cast(response,response_queue[i]);
            response_queue.delete(i);
            return;
          end
      end
      wait (response_queue.size() != queue_size);
    end
  endtask

=====================================
 

Return from function to pass into another function?

$
0
0

Hello all,

 

I want to pass the output of one function (10b8b decoder) into the input of another function viz. drive, where in drive function, I am creating the array out of each byte received from decoder. But when I am trying to Return that value from decoder, its not happening.

 

Can someone please tell me how to return the decoder output value and take it in as an input into the drive function? I would appreciate it.

 

Thanks

How to pass variable sized packed arguments to a task/function?

$
0
0

In SystemVerilog we can have dynamic unpacked arrays and they can be passed to a function/task. I was wondering if there is a way to pass dynamic packed arrays to a function/task. For example consider the following code:

 

module test;
  logic [3:0] A;
  logic [7:0] B;

  task automatic double(ref [3:0] val);
    val = val * 2;
    $display("%b",val);
  endtask

  initial begin
    A = 3;
    double(A);
    B = 5; 
    //double(B); ** Error because of size mismatch
  end

endmodule

here the task can only have a 4-bit input argument so if B is passed an error occurs. I am interested to know if there is any way to pass packed arrays of different size to a task/function. In previous example if the arrays were unpacked I could use:

 

  task automatic double(ref val []);

 

but I have no idea what I should use for packed arrays. In VHDL having variable size input arguments is very easy. For example the same code can be written like this:

 

use std.textio.all;

entity test is
end entity;

architecture arch of test is

  procedure double(val: bit_vector) is
    variable temp : bit_vector(val'left downto val'right);
    variable l : line;
  begin
    temp := val sll 1;
    write(l,temp);
    writeline(output,l);
  end procedure;

begin

  process
    variable A : bit_vector(3 downto 0);
    variable B : bit_vector(7 downto 0);
  begin
    A := "0011";
    double(A);
    B := "00001111";
    double(B);
    wait;
  end process;
  
end architecture;

I appreciate any idea on this.

 

Thanks

 

 

 

 

problem about variable part select in SystemVerilog

$
0
0

Hi all,

I have one problem about variable part select of Verilog. If you know the width, but the upper or lower range is a variable, you can use variable part select.

eg : 

addr[idx_bits-:8] = {8{1'b1}}; 

t's okay.

 

But if you know the upper or lower range, the width is a variable, how can you do? I adapt the similar way of variable part select.

eg: 

addr[8-:idx_bits] = {idx_bits{1'b1}};

 

VCS reports such an error:

 

Error-[NCE] Non-constant expression  The following expression should be a constant.
  Expression: idx_bits
  Source info:     addr[8-:idx_bits] = {idx_bits{1'b1}};
 
Could anybody help to have a look? Thanks in advance.

Any better way to serialize the data, please give suggestion?

$
0
0

Hello all,

I am working on piso(parallel in serial out). I am receiving the 10bits byte properly upto foreach loop, But after that data is not being shifted properly in shift register and its not getting serialized. Following is the code for the piso task.

 
task piso(encodrout1); 
        bit[9:0]encodrout1[]; 
        $display("san355- Display of the bytes array received inside the PISO %p",encodrout1); //%h
                uvm_report_info(get_full_name(),"Received All 10bits into the PISO...",UVM_LOW); 
              
      uvm_report_info(get_full_name(),"Driving 10bits and converting into serial bitstream.....",UVM_NONE);
     
      foreach (encodrout1[k]) 
         begin
          // automatic 
          reg [9:0] load;
          //automatic bit [9:0] load; // =0;
           reg [4:0] counter_d = 0;
           
           dut_vi.reset <= 0; 
    
       load = encodrout1[k];
     
                         $display("san340- Display of the load %b",load); 
                         $display("san340- Display of the load %h",load); 
                    
     @(posedge dut_vi.clock) 
     
     //for (int i = 0; i < 10 ; i++) //I guess this line is not needed
     begin
                  // repeat(10)@(posedge dut_vi.clock)
                 // @(posedge dut_vi.clock) 
                   counter_d = counter_d + 1;    
                  
                   load[9:0] <= {load[8:1] & load[0]} ; //THIS LINE DOESNT WORK, GIVES ERROR: Error: driver72.sv(269): LHS in non-blocking assignment may not be an automatic variable
    
     load[9] = load[8];
                   $display("san370- Display of the load %b",load); 
                   // @(posedge dut_vi.clock)
                   dut_vi.data <= load[9];
             load[8] = load[7];
             $display("san371- Display of the load %b",load); 
             // @(posedge dut_vi.clock)
             dut_vi.data <= load[8];
                   load[7] = load[6];
                   $display("san372- Display of the load %b",load); 
                   // @(posedge dut_vi.clock)
                   dut_vi.data <= load[7];
             load[6] = load[5];
             $display("san373- Display of the load %b",load); 
             //  @(posedge dut_vi.clock)
             dut_vi.data <= load[6];
             load[5] = load[4];
             $display("san374- Display of the load %b",load); 
             //  @(posedge dut_vi.clock)
             dut_vi.data <= load[5];
             load[4] = load[3];
             $display("san375- Display of the load %b",load); 
            // @(posedge dut_vi.clock)
             dut_vi.data <= load[4];
             load[3] = load[2];
             $display("san376- Display of the load %b",load); 
            // @(posedge dut_vi.clock)
             dut_vi.data <= load[3];
             load[2] = load[1];
             $display("san377- Display of the load %b",load); 
            // @(posedge dut_vi.clock)
             dut_vi.data <= load[2];
             load[1] = load[0];
             $display("san378- Display of the load %b",load); 
            // @(posedge dut_vi.clock)
             dut_vi.data <= load[1];
                   load[0] = load[9]; 
                   $display("san379- Display of the load %b",load); // */                   
                   dut_vi.data <= load[0];
            
      // repeat(10)@(posedge dut_vi.clock)
       counter_d = counter_d + 1;
       $display("san365- Display of the counter_d %d",counter_d); //%h
       $display("san369- Display of the load %h",load); //%h
       $display("san369- Display of the load %b",load); //%h
     
               uvm_report_info(get_full_name(),"Display of load inside PISO2222.....",UVM_NONE);
     end  
     //ser_OUTPUT=load[9]; // this needs to be connected to the serial line of DUT It works here
     /*@(posedge dut_vi.clock) 
     dut_vi.data <= load[9]; //serial data goes out
     @(posedge dut_vi.clock) 
     dut_vi.data <= load[8];
     @(posedge dut_vi.clock) 
     dut_vi.data <= load[7]; //*/
     $display("san384- Display of the load[9] %b",load[9]); //%h
     //dut_vi.data <= ser_OUTPUT; //
     $display("san385- Display of the dut_vi.data %b",dut_vi.data); //%h It works here
     //end
         end
                    
       endtask : piso 
 

 

Any help will be appreciated, thanks

How to deal with sipo task to form the bytes out of it, plz suggest?

$
0
0
Hello all UVM geeks,
I am working on SIPO(serial in parallel out) in monitor class. Its not working properly and data is not being shifted in the shift registers. Can someone please guide me how to correct this problem so that I can make 10 bits byte out of SIPO. Following is the code for sipo part.
 
  task sipo(serialin);
         // task sipo(dut_vi.data);
                       reg [9:0] pout;
                      // automatic logic [9:0] temp = 0; //reg replaced by logic
                       reg [9:0] temp;
                       reg [4:0] counter_m = 0;
                        //repeat(2) 
                       //always
                       @(posedge dut_vi.clock)  //removed posedge
                       // for (int i = 0; i < 10 ; i++)
                        begin
                         // temp[9:0] <= {temp[8:0], serialin}; //THIS LINE DOESNT WORK, GIVES ERROR:  Error: monitor.sv(167): LHS in non-blocking assignment may not be an automatic variable
                          //temp[9:0] <<<= {temp[8:0], serialin};  //compiles but dont give any result
                               //@(posedge dut_vi.clock)
                                temp[0] = serialin;      //temp[8];
       $display("san480- Display of the temp %b",temp); 
  
                           temp[1] = temp[0];
                           $display("san481- Display of the temp %b",temp); 
  
  temp[2] = temp[1];
  $display("san482- Display of the temp %b",temp); 
  // @(posedge dut_vi.clock)
       temp[3] = temp[2];
  $display("san483- Display of the temp %b",temp); 
//  @(posedge dut_vi.clock)
       temp[4] = temp[3];
       $display("san484- Display of the temp %b",temp); 
//  @(posedge dut_vi.clock)
  temp[5] = temp[4];
  $display("san485- Display of the temp %b",temp); 
  // @(posedge dut_vi.clock)
  temp[6] = temp[5];
  $display("san486- Display of the temp %b",temp); 
       // @(posedge dut_vi.clock)
  temp[7] = temp[6];
  $display("san487- Display of the temp %b",temp); 
  // @(posedge dut_vi.clock)
  temp[8] = temp[7];
  $display("san488- Display of the temp %b",temp); 
       // @(posedge dut_vi.clock)
       temp[9] = temp[8]; 
                     $display("san489- Display of the temp %b",temp); 
                    // repeat(10)@( dut_vi.clock)
                  //  $display("san489- Display of the temp %b",temp);
                     counter_m = counter_m + 1;
                     $display("san490- Display of the counter_m %d",counter_m); //%h
                       end
                          @(posedge dut_vi.clock)
                          //assign
                          pout = temp;
                          
                          $display("san466- Display of the Paralled data out of SIPO %b",pout); //%h
         uvm_report_info(get_full_name(),"Display of SIPO output parallel data.....",UVM_NONE);
         
                          bq.push_back(pout); 
 @( dut_vi.clock); 
 $display("san467- Display of the queue contents %h",bq.size()); 
 bytes = new[bq.size()] (bq);  
 
      $display("san453- Display of the bytes array contents %p",bytes); //%h
          endtask: sipo   
 
 
Any help is appreciated. Thanks

Test hang with all objections dropped

$
0
0
Hello,
 
I was wondering if anyone had any ideas on why my test is hanging at the end of the run phase and how to resolve it correctly. The last of the output is listed below.
The testbench has a series of agents, each including a monitor, producer driver, consumer driver, and scoreboard. At the end of the run phase when the test is hanging I'm able to step through code and see it's executing in a forever loop in the monitor and consumer driver. In both of these I'm never raising any objection. 
Tracing through the UVM code it seems it's waiting for all threads to exit before moving on. 
 
Some questions:
Why should it wait for threads to exit if they never raised any objection?
Do I need to kill these threads? What is the best practice?
 
thanks!

 

UVM_INFO uvm_objection.svh(1245) @ 31166250: reporter [TEST_DONE] All end-of-test objections have been dropped. Calling stop tasks
UVM_INFO uvm_objection.svh(1268) @ 31166250: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO uvm_phase.svh(1199) @ 31166250: reporter [PH/TRC/EXE/ALLDROP] Phase 'common.run' (id=255) PHASE EXIT ALL_DROPPED
 

 

 

Any generic method in UVM to find the packet length of incoming packets?

$
0
0
Hello all,
I am receiving serial bits in the monitor from DUT. This is RX path and independent from TX path i.e driver path. Then I have to make parallel data out of it using sipo(serial in parallel out) and then I have to decode the data to form the packet from the decoded bytes. In order to receive the all the bits of all the packets in RX path(monitor class), I have to give packet_length inside the for loop. Right now in order to check he functionality of monitor (in loop back mode), I am sending only one packet(8 bytes) so I know the number of bits, which I can use for packet_length parameter. But I want to make it generic because in real world I wont know how many packets might be coming.
 
So the issue is, Is there any generic way in UVM to calculate the number of bytes(OR serial bits) coming into monitor? Is there any uvm method by which I can find this packet_length in a generic way?
 
 
Packet structure is shown below:
 class transaction extends uvm_sequence_item; 
           rand bit [7:0] sync;
           rand bit [7:0] sof;  
           rand bit [15:0] header; 
           rand bit [7:0] payload[]; 
           rand bit [15:0] crc;
           rand bit [7:0] eof;
 
 
 constraint data_size_c { payload.size inside { [6 : 6]};}; 
                  .............
                  .............
endclass: transaction
 
 class monitor extends uvm_monitor;
         .....
      virtual task run_phase(uvm_phase phase);
          transaction pkt;         
            forever
               begin
               int pkt_len = 130; //This is in bits,HERE I NEED TO PASS THE CALCULATED LENGTH FROM SOME GENERIC UVM FUNCTION,TO START RECEIVING ALL THE SERIAL BITS.
              
           repeat(3)@(dut_vi.clock); 
           for (int j = 0; j < pkt_len; j++)  
             
              begin
                  serialin = dut_vi.data;                                     
                    $display("san14- Display of the serial line serialin %b",serialin); 
                    $display("san15- Display of the Serial Line dut_vi.data %b",dut_vi.data); 
                    
                    sipo(serialin); 
                    
              end  
                void'(decode(bytes));   
              
                pkt = transaction::type_id::create("pkt1");        
                $display("SM447- Display of the bytes array received after decoding %h",decdrout2);  
                void'(pkt.unpack_bytes(decdrout2));
                uvm_report_info(get_full_name(),"Decoded completely 10bits into 8bits ...",UVM_LOW);
                uvm_report_info(get_full_name(),"Started unpacking of received bytes ...",UVM_LOW); 
             
                pkt.print(); 
                uvm_report_info(get_full_name(),"Completed unpacking of received bytes ...",UVM_LOW);          
                        Montr2Agnt_port.write(pkt);
                
           end 
        
          uvm_report_info(get_full_name(),"Sending received packet from monitor to the Scoreboard ...",UVM_LOW);
        
     endtask: run_phase   
        
           ...........
           ..........
 
endclass: monitor
 
 
 
Any help is appreciated, thanks

How to use uvm_files to store the packets?

$
0
0
Dear all,
In scoreboard, I want to store the received and sent packets into files (byte wise) separately. Can someone suggest how to use uvm_file to do this task? Please give some idea,Thanks

Help on uvm_pw_scoreboard package.

$
0
0

I am using uvm_pw_scoreboard package available on accelera Contributions.I have following queries about it .

1. Why does this package uses uvm_analysis_export and analysis_fifo implementation instead of uvm_analysis_imp in pw_checker_predictor as well as pw_scoreboard.

 

2. I want to pass unique id to each transaction, to do this i have implemented as below:

 

my_local_predictor.sv file(not extended from pw_checker_predictor)

uvm_analysis_port #(item) predict_port;

predict_port = new ("predict_port",this);

 

item.set_transaction_item(unique_id);

$display("Predictor unique_id =%d",unique_id);

predict_port.write(item)

 

 

In extended pw_scoreboard

 

function int get_stream_id(uvm_transaction t )

     $display("Scoreboard unique_id =%d",t.get_transaction());

     get_stream_id = t.get_transaction_id();

endfunction

 

Output:

Predictor unique_id = 2;

Scoreboard unique_id= -1;

 

Any help is appreciated.

 

 

UVM_ACTIVE data type....bit or int ?

$
0
0

When agents are configured, I typically see something like this:

uvm_config_db#(int)::set(this,"testbenchA.masterA_hostB.agentpink","is_active",UVM_ACTIVE);

 

 

Isn't UVM_ACTIVE of type bit?  I see it 'described' here in an enum and given a default value.

src/base/uvm_object_globals.svh: typedef enum bit { UVM_PASSIVE=0, UVM_ACTIVE=1 } uvm_active_passive_enum;

 

So shouldn't the uvm_config_db line not be:

 

 uvm_config_db#(int)::set(this,"testbenchA.masterA_hostB.agentpink","is_active",UVM_ACTIVE);

but instead be:

 uvm_config_db#(bit)::set(this,"testbenchA.masterA_hostB.agentpink","is_active",UVM_ACTIVE);

?
 
 
thx,
 
(I sense that I probably don't have a solid enough understanding of enum and the relationship between bits and ints.)

issue regarding 32 bit crc implementation in transaction class of ethernet packets in uvm methodology

$
0
0
Hello Friends,

I am samrat Patel from ahmedabad
Currently i am working on a project of ethernet packet using uvm methodology.In project i have to implement a 32 bit crc logic in transaction class . i have seen some material on crc but for 32 bit crc i am not getting properly that how to do XOR calculation between 32 bit crc and 8 bit data.so any one can elaboreate it and help me for this that how can i do crc implemenation?

If u know reply me asap

email id:samrat150590@gmail.com
contact no: 09016464567

Thanks,

Regards,
Samrat Patel
 
->Following is my transaction class
 
//ethernet transaction class declaration 
class eth_transaction extends uvm_sequence_item;
 
//ethernet packet field ranomization 
  rand bit [55:0] preamble;
  rand bit [7:0] sfd;
  rand bit [47:0] dst_addr;
  rand bit [47:0] src_addr;
  rand bit [15:0] data_len; // this length can accomodate MAXIMUM length of 1500
  rand bit [7:0] payload [];
  rand bit [31:0] crc;    
 
  rand int unsigned transmit_delay;//transmit delay between transfers
  
  constraint c_delay {transmit_delay==10;}//constraint on transmit delay-constraint as per need
 
//constraint on specific field
 
constraint preamble_con{
                        preamble=={7{8'haa}};
                        }
  
constraint sfd_con{
                   sfd== 8'hab;
                   }
    
constraint data_len_con{
                        data_len inside {[46:1500]};
                        solve data_len before payload;
                       }
 
constraint payload_con{
                        payload.size==data_len;
                       }
 
 
 
//macro registraton
`uvm_object_utils_begin(eth_transaction)
  
  `uvm_field_int(preamble,UVM_ALL_ON|UVM_NOPACK)
  `uvm_field_int(sfd,UVM_ALL_ON|UVM_NOPACK)
  `uvm_field_int(dst_addr,UVM_ALL_ON|UVM_NOPACK)
  `uvm_field_int(src_addr,UVM_ALL_ON|UVM_NOPACK)
  `uvm_field_int(data_len,UVM_ALL_ON|UVM_NOPACK)
  `uvm_field_array_int(payload,UVM_ALL_ON|UVM_NOPACK)
  `uvm_field_int(crc,UVM_ALL_ON|UVM_NOPACK)
  `uvm_field_int(transmit_delay,UVM_DEFAULT|UVM_NOCOMPARE|UVM_NOPACK)
 
`uvm_object_utils_end
 
//constructor
function new(string name = "eth_transaction");
  super.new(name);
endfunction
  
//display method  
function void display(string strng);
 
  $display("\n@time=%0g\tpacket displaying from %s",$time,strng);
  $display("||==============||======||============||============||============||===============||========||");
  $display("|| preamble     || sfd  || dst_addr   || src_addr   ||   data_Len ||   payload_Len ||  crc   ||");
  $display("||--------------||------||------------||------------||------------||---------------||--------||");
  $display("||%h||  %h  ||%h||%h||    %4d    ||     %6d    ||%h||",preamble,
                                                                   sfd,
                                                                   dst_addr,
                                                                   src_addr,
                                                                   data_len,
                                                                   payload.size,
                                                                   crc);
  $display("||==============||======||============||============||============||===============||========||");
  $display("\n");
 
endfunction
 
//pack all bits of ethernet packet field
function void do_pack(uvm_packer packer);
  
  super.do_pack(packer); // pack super's properties
  
  packer.pack_field_int(preamble,$bits(preamble));
  packer.pack_field_int(sfd,$bits(sfd));
  packer.pack_field_int(dst_addr,$bits(dst_addr));
  packer.pack_field_int(src_addr,$bits(src_addr));
  packer.pack_field_int(data_len,$bits(data_len));
  foreach(payload[i])
  packer.pack_field_int(payload[i],8);
  packer.pack_field_int(crc,$bits(crc));
  
endfunction : do_pack
    
//unpack all bits of ethernet packet field
function void do_unpack(uvm_packer packer);
  
  super.do_unpack(packer); // unpack super's properties
    
  preamble = packer.unpack_field_int($bits(preamble));
  sfd = packer.unpack_field_int($bits(sfd));
  dst_addr = packer.unpack_field_int($bits(dst_addr));
  src_addr = packer.unpack_field_int($bits(src_addr));
  data_len = packer.unpack_field_int($bits(data_len));
  payload.delete();
  payload = new[data_len];
  foreach(payload[i])
  payload[i] = packer.unpack_field_int(8);
  crc = packer.unpack_field_int($bits(crc));
  
endfunction : do_unpack
 
//do_compare method -to compare specific field
function bit do_compare(uvm_object rhs,uvm_comparer comparer);
    eth_transaction rhs_;
    bit status=1;
    $cast(rhs_,rhs);
    status &= (preamble == rhs_.preamble);
    status &= (sfd == rhs_.sfd);
    status &= (dst_addr == rhs_.dst_addr);
    status &= (src_addr == rhs_.src_addr);
    status &= (data_len == rhs_.data_len);
    status &= (payload == rhs_.payload);
    status &= (crc == rhs_.crc);
    return status;
endfunction
 
endclass: eth_transaction

Sequences distribution

$
0
0

Hi ,

 

Is there any way to control the sequences distibution on UVM? 

For example when one would like to give higher probablily to some sequences over the other?

 

Can this be controlled from the test?

 

Thanks, 

Ilan

 

Purpose of include_coverage() API in uvm_reg.

$
0
0

I was wondering about the need for the API call include_coverage(...) in uvm_reg.  It appears that build_coverage (...) would be sufficient to build whatever coverage is required in the current scope.

Is there a recommended  use model that clearly distinguishes the use of these 2 calls?

 

As the include_coverage() call contains a scope parameter,  I realize we can specify coverage models for any register object from some other scope... But where would one call this routine ?   For build_coverage it is clear that it applies to the current scope.

 

Thanks for your help

 

Loganath

 

std::randomize( vs. randomize( vs. this.randomize( and scope

$
0
0

I had expected all 3 of these calls to randomize to return values using the constraint.  However, the first does not.  Can anyone tell me why?

 
(note: In the following code, there is no local randomize method defined.  So, I think that all randomize functions are the same...and perhaps only scope varies.)  
 
Code, followed by sim results:

class thursday_seq extends junk_seq_seq;  //which extends uvm_sequence

   rand int count;
   constraint c1 { count >= 2; count <= 9; }

   function new(string name="thursday_seq");
      super.new(name);
      if (std::randomize(count)) begin 
         `uvm_info("",$psprintf(" cnt=%0d .....",count),UVM_LOW) end
      else $finish;
      if (randomize(count)) begin 
         `uvm_info("",$psprintf(" cnt=%0d .....",count),UVM_LOW) end
      else $finish;
      if (this.randomize()) begin 
         `uvm_info("",$psprintf(" cnt=%0d .....",count),UVM_LOW) end
      else $finish;
      $finish;
   endfunction:new

   `uvm_object_utils(thursday_seq)
UVM_INFO @ 0: reporter@ []  cnt=415747889 .....
UVM_INFO @ 0: reporter@ []  cnt=9 .....
UVM_INFO @ 0: reporter@ []  cnt=2 .....

 

 

It seems what is happening is that while std::randomize and randomize are calling the same method in the standard package, the standard version is oblivious to local constraints.

I see in 1800-2012.pdf (SV spec), sec. 18.5.2 "The randomize() method is virtual and therefore honors constraints of the object on which it was called, ..." (highlighting mine)

 

 

Later in the spec, there is reference to the 'scope of the randomize('  which confuses me a bit, if the constraints are always to be honored.  (Although, I suppose in the first two cases above "of the object on which it was called" is not true, b/c I don't call it on the object, but on a property of the object.)  Is that correct?

 

After doing a bunch more reading, I am going to continue with this post for feedback.  Here is something more I learned.

 

This quote in section "18.12 Randomization of scope variables—std::randomize()" I think explains it all for me.

 

"The scope randomize function, std::randomize(), enables users to randomize data in the current
scope without the need to define a class or instantiate a class object."

 

 

I'm a bit unsure, but I think the answer to my question is this.

"without the need to define a class" and "in the current scope", from above, imply that std::randomize performs only on the scope that is passed to it.   i.e. if I pass it a class object, then it knows of that object's constraints.    If I pass it a data-member of a class, then the scope that data-member exists in is not seen (i.e. any constraints which are in the scope above that data-member are not seen).  Though they could be replicated as inline constraints.).   

The local randomize knows of all the constraints in the object from which it is called.

 

Do I understand this correctly?  I think I just walked myself through understanding this.  Comments welcome.

 

thx,

 

note: using Cadence's IUS12.1-s004

import statement location effects on random stability

$
0
0

Hi,

I'm trying to determine if "import" statements should be within package statements or not, when it comes to random stability.

Viewing all 410 articles
Browse latest View live