2016-06-23 3 views
0

Mein uvm_driver (Produzent) teilt Daten mit einer uvm_component (Verbraucher) über einen Put-Port. Das freigegebene Element ist eine uvm_transaction-Klasse xfer_data mit zwei Datenmembern und einer Methode getdata. Der Treiber ruft getdata dann sofort den .put-Aufruf, aber durch $ Display-Anweisungen Ich sehe die Consumer-Put-Aufgabe wird kurz nach getdata aufgerufen, aber vor .put und ich bekomme den gefürchteten Null-Zeiger dereferenziert.Was würde dazu führen, dass die Aufgabe "put" von uvm consumer aufgerufen wird, bevor der Produzent den myport.put ausführt

Wenn ich Beispiele von uvm_users_guide sehe, sieht es so einfach und elegant aus. Ich habe versucht, meinen Consumer zu einem uvm_subscriber mit demselben Ergebnis zu ändern. Wie üblich kompiliert der Code ohne Fehler und funktioniert, wenn ich den Portcode entferne. Jede Hilfe wird geschätzt!

--Ross

Ich habe Code hinzugefügt: CONSUMER, Produzent, Klasse OBJECT PORT, AGENT Aussagen verbinden.

////////////////// CONSUMER ///////////////////// 
//class test_rcvr extends uvm_component; //RLHS 
class test_rcvr extends uvm_subscriber #(xfer_data); 
    `uvm_component_utils(test_rcvr) 
    local int xfer_count; //RLHS 
    local logic [31:0] last_data; 
    local logic [3:0] last_datamask; 
    bit in_progress [$]; //RLHS indicate transaction in progress 

    uvm_blocking_put_imp #(xfer_data, test_rcvr) driver_dataport; 

    function new(string name = "test_rcvr", uvm_component parent = null); 
    super.new(name, parent); 
    xfer_count=0; 
    driver_dataport = new("driver_dataport",this); 
    endfunction 

    virtual task put(xfer_data test_data); 
    forever begin 
//  driver_dataport.get(test_data); 
     last_data = test_data.data1; 
     last_datamask = test_data.datamask; 
     xfer_count++; 
    end 
    endtask: put 
endclass: test_rcvr  

//////////////////////// PRODUCER ////////////////////////// 
class apb_driver extends uvm_driver #(apb_seq_item); 
    `uvm_component_utils(apb_driver) 
    apb_seq_item   req; 
    virtual interface if_apb IF_APB; 

    uvm_blocking_put_port #(xfer_data) driver_dataport; //RLHS define port name 
//1 uvm_analysis_port #(xfer_data) driver_dataport;//RLHS 

function new(string name = "apb_driver", uvm_component parent = null); 
    super.new(name, parent); 
    driver_dataport = new("driver_dataport", this); //RLHS 
endfunction: new 

function void build_phase(uvm_phase phase); 
    super.build_phase(phase); 
    if(!uvm_config_db#(virtual if_apb)::get(null ,"uvm_test_top","field_apb_if", IF_APB)) begin 
    `uvm_fatal("NOVIF", {"You fool! Virtual interface must be set for field name: field_apb_if "}); 
    end 
// driver_dataport = new("driver_dataport", this); //RLHS 
endfunction: build_phase 

task run_phase(uvm_phase phase); 
logic [31:0] data1; 
logic [3:0] datamask; 

    xfer_data x_data; // create object of data to xfer //RLHS 
// x_data = xfer_data::type_id::create("x_data"); // RLHS 

    forever begin    // logic rstnapb, psel, pwrt, pen, perr clk_apb 
    IF_APB.psel <= 1'b0;  // logic [31:0] pwdata; 
    IF_APB.pen  <= 1'b0;  // wire [31:0] prdata; 
    IF_APB.paddr <= 7'b0;  // logic [6:0] paddr; 
    IF_APB.pwdata <= 32'b0; 
    IF_APB.pwrt <= 1'b0; 

    seq_item_port.get_next_item(req); // blocks until xfer occurs 

    x_data.get_test_data(3, 1, data1, datamask); // RLHS get data 
    $display("7.1. apb_pkg driver post call getdata = %5d", data1); 
    driver_dataport.put(x_data); // RLHS send DDR data 
//1  driver_dataport.write(x_data); // RLHS 
snip.... 
endclass:apb_driver 

//////////////////////// object sent on PORT /////////////// 
class xfer_data extends uvm_transaction;//RLHS 
    rand int data1; 
    rand bit [3:0] datamask; 
    bit wrtreadb; 
task get_test_data(input int i, input bit [3:0] what, 
    output logic [31:0] data1, output logic [3:0] datamask); 
// legend: 
// i: item number in block 
// what: which type of data being xfered 
// 
    case (what) 
    default: begin 
    data1 = $random; datamask = $random; 
    end 
    1: begin 
    case (i[2:0]) 
    0:begin data1 = 32'h0123_4567; datamask = 4'h0; end 
    1:begin data1 = 32'h89ab_cdef; datamask = 4'h1; end 
snip.... 

///////////////////// AGENT /////////////////////////// 
class apb_agent extends uvm_agent; 
    `uvm_component_utils(apb_agent) 

    uvm_analysis_port #(apb_seq_item) apbport; // this connects sequence 
//1 uvm_analysis_port #(xfer_data) driver_dataport; //RLHS 

    apb_sequencer  m_apb_sequencer; 
    apb_driver  m_apb_driver; 
    apb_monitor  m_apb_monitor; 
    apb_coverage_monitor m_fcov_monitor; 
    test_rcvr  m_test_rcvr;//RLHS 

    function new(string name, uvm_component parent); 
    super.new(name, parent); 
    endfunction: new 

    function void build_phase(uvm_phase phase); 
    super.build_phase(phase); 

    m_apb_sequencer = apb_sequencer::type_id::create("m_apb_sequencer", this); 
    m_apb_driver = apb_driver::type_id::create("m_apb_driver", this); 
    m_apb_monitor = apb_monitor::type_id::create("m_apb_monitor", this); 
    m_fcov_monitor = apb_coverage_monitor::type_id::create("m_fcov_monitor", this); 
    m_test_rcvr  = test_rcvr::type_id::create("m_test_rcvr", this); 

    apbport = new("apbport", this); 
//1 driver_dataport = new("driver_dataport", this); //RLHS 
    endfunction: build_phase 

    function void connect_phase(uvm_phase phase); 
    super.connect_phase(phase); 
    m_apb_driver.seq_item_port.connect(m_apb_sequencer.seq_item_export); 
//?? m_apb_monitor.apbport.connect(apbport); 
    m_apb_monitor.apbport.connect(m_fcov_monitor.analysis_export); 
    apbport = m_apb_monitor.apbport;  

//1 driver_dataport = m_apb_driver.driver_dataport; // RLHS 
//1 m_apb_driver.xfer_data.connect(driver_dataport);// RLHS 
//1 m_apb_driver.xfer_data.connect(m_test_rcvr.analysis_export);// RLHS 
    m_apb_driver.driver_dataport.connect(m_test_rcvr.driver_dataport); 
// m_test_rcvr.driver_dataport.connect(m_apb_driver.driver_dataport); 

    endfunction: connect_phase 
endclass: apb_agent 

Antwort

0

Leider ist dies keine Antwort ... Ich habe keine Erlaubnis zu kommentieren haben ......

Eine Möglichkeit besteht darin, dass es eine Ordnung Problem. Das Put-IMP kann möglicherweise einen vorherigen Put-Aufruf und somit den Nullzeiger ausführen. Aber Sie müssen etwas Code [die Funktionsaufrufe und die Konnektivität] und die Ausgabe/Display-Nachrichten bereitstellen. das wird helfen .

+0

// x_data = xfer_data :: type_id :: create ("x_data"); - In run_phase von apb_driver - Ich gehe davon aus, dass es nicht auskommentiert wurde, wenn Sie in früheren Läufen verwendet haben. Wenn keine x_data-Instanz vorhanden ist, kann der Nullzeiger –

+0

möglicherweise dazu führen, dass x_data eine globale Variable in der Klasse ist. –

+0

Sie können uvm_object_utils zu Ihrem xfer_data –

0

Rahul sagte:

uncomment xfer_data

Add erstellen, dieses Argument Liste

Register xfer_data Klasse mit Fabrik

remove für immer Schleife in Put Aufgabe Implementierung

Dank zu erstellen Rahul

Verwandte Themen