Jump to content

David Long

Members
  • Posts

    37
  • Joined

  • Last visited

  • Days Won

    8

Posts posted by David Long

  1. sc_fix is the base class for sc_fixed. The size of an object of type sc_fix is set when the object is created (i.e. by the constructor) as opposed to sc_fixed where the size is set by the compiler (using the template parameter).

     

    If you want to change the size, you will have to create a new object and copy the original value to it. ,e,g. using the copy constructor

     

     

    sc_fix var_11 = sc_fix(var_1,16, 4, SC_RND, SC_SAT); //decalre and create a new variable
     
    

     

     

    Regards,

    Dave

  2. If you want to add "missing" features into a SV testbench, it can be very easy using DPI, provided you know basic C/C++ syntax.

     

    For example, here is a version of your double task that takes an open array (assumed here to be a packed bit vector of any length). I haven't included any checking/error handling but even so, this should still be OK for up to 32-bit vectors.

    #include "svdpi.h"
    
    extern "C" {
    
    int double_vec (svOpenArrayHandle h) {
      svBitVecVal *ptr;
      int size;
      int value;
      size = svSize(h,0);
    
      //get bit vector ptr from handle
      ptr = (svBitVecVal*)svGetArrayPtr(h);
      //convert to int
      value = bv_to_int(ptr,size);
      value *= 2;
      //write int back to bv
      int_to_bv(value,ptr,size);
      return 0;
    }
    } 
    

     

    The functions to convert to/from int/bit vector could be something like:

     

    int bv_to_int(const svBitVecVal* bv, int size) {
      int val = 0;
      int mask = 1;
      for (int i=0; i<size; i++){
          if (svGetBitselBit(bv,i) == sv_1)
              val |= mask;
          mask <<= 1;
      }
      return val;
    }
    
    void int_to_bv (int val, svBitVecVal* bv, int size) {
      int mask = 1;
      svBit b;
      for (int i=0; i<size; i++){
          b = (val & mask) ? sv_1 : sv_0;
          svPutBitselBit(bv,i,;
          mask <<= 1;
      }
    }
    

     

    You could declare and use the DPI function in SV as follows:

     

    module top();
      import "DPI-C" task double_vec(inout bit[] vec);
     
      bit [7:0] vec8 = 8'd15;
      bit [15:0] vec16 = 16'd1234;
     
      initial begin
        $display ("vec8 = %0d, vec16 = %0d", vec8, vec16);  
        double_vec(vec8);
        double_vec(vec16);
        $display ("vec8 = %0d, vec16 = %0d", vec8, vec16);  
      end
    
    endmodule: top
     

    With simple uses of DPI such as this, most current SV simulators will automatically compile and link the SV and C/C++ code for you, e.g.

    qverilog top.sv double.cpp 
    

     

    Hope that gives you some ideas, even if it is a somewhat more complicated solution than you were hoping for!

     

    Regards,

    Dave

     

     


     


     

  3. Hi Adam,

     

    Setting the use_metadata bit in the packer will add an extra 32 bits to the payload. I gather from the original question that the driver is using the UVM packer to generate the payload that is being sent to the DUT. This must reflect what the DUT is actually expecting to see.  Adding extra bytes just to enable the monitor to automatically unpack it would not be acceptable here! That is why I suggested using a for loop with `uvm_unpack_int once the dynamic array size was known.

     

    Regards,

    Dave

  4. Hi,

     

    Some suggestions for possible problems in your driver and how to detect them::

     

    virtual task run_phase(uvm_phase phase);
    my_item req;
    
    @(negedge duv_vif.rst);
     

     

     

    Do you see the reset?

     

     

    forever begin
    @(this.duv_vif.wfifo_if.fifo_wr);
     

     

    Do you see the fifo_wr change?

     

    seq_item_port.get_next_item(req);
     

    Try writing out a message to test if you get to this line

     

    $cast(sub_item, req.clone());
     

     

     

    Are any of the following methods blocking?

     

    port2rm.write(sub_item);
    write_mem(sub_item);
    drive_desc_pkt(sub_item);
     

     

    Try writing out a message to test if you get to this line

     

    seq_item_port.item_done();
    end
    endtask : run_phase
     

     

    Hope that helps.

     

    Regards,

    Dave

  5. Hi,

     

    When you start a sequence item, either by calling the macro `uvm_do/`uvm_do_with or the tasks start_item/finish_item, it will block until it gets a response from the driver. How are you getting the sequence items in your driver? You should be calling either

     

     

    seq_item_port.get(req);  //fetches sequence item then sends acknowledgement
     

     

     

    or

     

     

    seq_item_port.get_item(req);  //fetches sequence item
    ..
    seq_item_port.item_done();  //sends acknowledgement
     

     

     

    Regards,

    Dave

  6. Hi,

     

    In SystemC 2.3 you can create an object of type sc_event_or_list - it is not necessary to use the "work-around" from SystemC 2.2 that creates a reference to an event or list (and in fact, this no longer works, as you have found).

     

    You could re-write your code along the following lines:

    struct M: sc_module
    {
      sc_port<if,0> p; // Multiport
    
      void end_of_elaboration() {  
        //create event list once all ports are bound
        for (int i = 0; i < p.size(); i++)
          all_p_events |= p[i]->value_changed_event();
      }
    
    ...
            wait(all_p_events);
    ...
    
    private:
        sc_event_or_list all_p_events;
    };
     

     

     

    Regards,

    Dave


     

  7. The critical point that you must remember is that it is not possible to automatically unpack a stream of bits/bytes into a dynamic array since the unpack operation does not know how big the dynamic array should be (assigning to a dynamic array overwrites the existing contents and can therefore change its size). In your case, and using the example above, you would need something like this in your do_unpack function

     

    virtual function void do_unpack(uvm_packer packer);
      ...  //unpack preceeding bytes
      payload = new [payload_size_in_bytes];
      foreach (payload[i]) `uvm_unpack_int(payload[i])
     ...  //unpack remaining fields
    endfunction
    
     

     

    Regards,

    Dave

  8. Hi,

     

    You need to use a type that is compatible with your sequencers for the config_db parameter.

     

    If you have created a custom sequencer class, e.g. class my_sequencer extends uvm_sequencer#(my_seq_item_type) you cannot assign a reference to it to a plain uvm_sequencer variable (remember the uvm_sequencer class is parameterised - by default, the parameter type is uvm_sequence_item).

     

    I suggest that you create a typedef for each sequencer specialization and use that as the parameter for the config_db

     

     

     

    typedef uvm_sequencer #(my_str_sequence_item) str_sequencer;
    ...
    
    uvm_config_db#(str_sequencer)::set(this, "v_sqr", "cfg_sqr", this.cfg_agt.cfg_sqr);
     

     

     

     

    Regards,

    Dave

     

    ===========

    David Long

    Doulos

    http://www.doulos.com

     

     

  9. Hi Cliff,

    UVM 1.0 requires some DPI code - you need to include it in your compiler options file, e.g.

    +incdir+${UVM_HOME}/src
    
    ${UVM_HOME}/src/dpi/uvm_dpi.cc
    

    Your UVM-EA examples should then build OK with Questa version 10. Note that you will also need to update the phase semantics in your UVM-EA examples to match UVM 1.0 (or you are likely to see your simulation exit at time 0). If you do not want to modify your OVM/UVM-EA code, the other alternative is to add the +UVM_OVM_RUN_SEMANTIC command line option to qverilog.

    Additional Note: You do not need to set the incdir if you are using the version of UVM included with Questa (as opposed to a version from the Accellera web site) - it is set implicitly to path_to_uvm_pkg/../verilog_src/uvm-1.0/src

    Regards,

    Dave

  10. Hi Jonathan,

    We fixed this problem by adding

    item = new;
    to the uvm_simple_sequence constructor in the UVM library that we use. My personal opinion is that it can be a good idea to create sequence items in sequence constructors rather than by calling `uvm_do in the sequence body (which would use the other sequence macros to re-randomize and send the sequence item). However, in this case, I think that your proposal is a better fix.

    Best Regards,

    Dave

×
×
  • Create New...