2013年8月14日 星期三

UVM model notes 3


  • using callback func to handle the trx that's much more beautiful than using the trx handler in the same block  

    • this.trans_executed(tr); `uvm_do_callbacks(apb_master,apb_master_cbs,trans_executed(this,tr))   

  • using get_parent() to fetch the parent's pp and populate it to sub blocks

    • apb_agent agent;
      if ($cast(agent, get_parent()) && agent != null) begin
      sigs = agent.vif;
      end

  • using sequencer handler to sort/resort the sequence items by it's priority set, such as sorted([seq(0)->p(1), seq(1)->p(0)]) => [seq(1)->p(0), seq(0)->p(1)]  
    • register sub sequence to sequencer manager  

    • class dut_reset_seq extends uvm_sequence;

      function new(string name = "dut_reset_seq");
          super.new(name);
      endfunction

      `uvm_object_utils(dut_reset_seq)

      virtual task body();
          dut_top.rst = 1;
          repeat (5) @(negedge dut_top.clk);
          dut_top.rst = 0;
          endtask
      endclass

                ....
         dut_reset_seq rst_seq;                                                                                                  rst_seq = dut_reset_seq::type_id::create("rst_seq", this);
         rst_seq.start(null);

         ....
         my_tx tx;
         start_item(tx);
          ...// do something here
         finish_item(tx);

    • TLM interface (socket/package) it use like in "fifo" struct
      • pull_port (slave side)
        • querying the valuable trx from trx queue when the trx queue is not empty.

          uvm_seq_item_pull_port #(reg_rw) seqr_port;
          seqr_port.peek(rw); // aka 'get_next_rw
          ... // do trx handle
          seqr_port.get(rw); // aka 'item_done''
      • put_port(master side)
        • push the valuable trx to trx queue when the trx queue is not full
    • port/export TLM1
      • A component can send out a transaction out through a port, or receive an incoming transaction through an export.

      • function void connect;
            sqr2.seq_item_port.connect(sqr1.seq_item_export );
            ...
        endfunction

    • blocking/non-blocking trx in TLM2
      • non-blocking (return immediately) or blocking (suspend and wait for some event before returning)

      • non-blocking // no delay
        uvm_tlm_nb_target_socket#(device, usb_xfer, usb_tlm_phase) sock; // slave
        function uvm_tlm_sync_e nb_transport_fw(usb_xfer xfer, ref usb_tlm_phase ph...)

        uvm_tlm_nb_initiator_socket#(host, usb_xfer, usb_tlm_phase) sock; // master
        function uvm_tlm_sync_e nb_transport_bw(usb_xfer xfer,                        ref usb_tlm_phase ph, ...)
      • // connect sub sockets in uvm_env connect phase
        // master.sock.connect(slave.sock); 

      • blocking // support delay
      • uvm_tlm_b_target_socket #(target, apb_rw) sock; //slaveuvm_tlm_b_initiator_socket#(apb_rw) sock; // master
      • // connect sub sockets in uvm_env connect phase
        // master.sock.connect(slave.sock);
    • uvm_reg_field call back and sample
    class input_value_c extends uvm_reg;

      rand uvm_reg_field data;                                                                                                                                                        
      virtual function void build();
        data = uvm_reg_field::type_id::create("data");
        data.configure(this, 32, 0, "RO", 0, `UVM_REG_DATA_WIDTH'h0>>0, 1, 1, 1);
      endfunction

      covergroup value_cg;
        option.per_instance=1;
        coverpoint data.value[31:0];
      endgroup
     
      virtual function void sample_values();
        super.sample_values();
        value_cg.sample();
      endfunction

      `uvm_register_cb(input_value_c, uvm_reg_cbs)
      `uvm_set_super_type(input_value_c, uvm_reg)
      `uvm_object_utils(input_value_c)
      function new(input string name="unnamed-input_value_c");
        super.new(name, 32, build_coverage(UVM_CVR_FIELD_VALS));
        if(has_coverage(UVM_CVR_FIELD_VALS)) value_cg=new;
      endfunction : new
    endclass : input_value_c
    • uvm_reg_block
      • add sub classes "uvm_reg" to block set
    class gpio_regfile extends uvm_reg_block;                                                                       rand bypass_mode_c bypass_mode;
     
        virtual function void build();

         // Now create all registers

         bypass_mode = bypass_mode_c::type_id::create("bypass_mode", , get_full_name());
       
        // Now build the registers. Set parent and hdl_paths
         bypass_mode.configure(this, null, "bypass_mode_reg");
         bypass_mode.build();
         // Now define address mappings
        default_map = create_map("default_map", 0, 4, UVM_LITTLE_ENDIAN);
        default_map.add_reg(bypass_mode, `UVM_REG_ADDR_WIDTH'h0, "RW");

    endclass
    • uvm_report_server
      •    uvm_report_server svr;
           svr = _global_reporter.get_report_server();
           svr.set_max_quit_count(10);   

                                                          沒有留言:

                                                          張貼留言