2016-09-18 4 views
0

Ich habe die folgende Transaktion:SystemVerilog- Wie schreibe ich einen Konstruktor mit Initialisierung?

typedef enum {READ = 0, WRITE = 1} direction_enum; 

//Transaction 

class axi_transaction extends uvm_sequence_item(); 
    bit id = 0; //const 
    bit [31:0] addr; 
    bit [2:0] size = 0'b100;//const 
    direction_enum rw; 
    bit [31:0] transfers [$]; 



    //factory registration 
    `uvm_object_utils_begin(axi_transaction) 
    `uvm_field_int(id, UVM_ALL_ON) 
    `uvm_field_int(addr, UVM_ALL_ON) 
    `uvm_field_int(size, UVM_ALL_ON) 
    `uvm_field_enum(rw, UVM_ALL_ON) 
    `uvm_field_int(transfers, UVM_ALL_ON)  
    `uvm_object_utils_end 

    //constructor 
    function new(string name = "axi_transaction"); 
     super.new(name); 
    endfunction: new 

endclass: axi_transaction 

Ich mag die neue Funktion erweitern, so kann ich die Transaktion in der Folge mit Argumenten initialisiert, die von einigen der Transaktionselemente (wie Adr, Transfer) initialisieren:

ax_trx = axi_transaction::type_id::create(); 

Wie schreibe ich den Konstruktor der Transaktion und wie initialisiere ich die Transaktion aus dem Sequenzer?

Antwort

2

Sie können dem Klassenkonstruktor keine Argumente hinzufügen, wenn Sie die UVM-Factory verwenden. Im Allgemeinen ist dies keine gute OOP-Programmierpraxis für die Wiederverwendung, da, wenn Sie der Basisklasse oder der erweiterten Klasse Argumente hinzufügen, Sie jeden Platz ändern müssen, an dem die Klasse konstruiert wird.

Eine bessere Option ist, die uvm_config_db zu verwenden oder die einzelnen Felder festzulegen, die Sie nach dem Erstellen des Objekts benötigen.

ax_trx = axi_transaction::type_id::create(); 
ax_trx.addr = some_address 
ax_trx.transfers = '{word1,word2,word3}; 
+1

@ dave_59- Können Sie mir ein Beispiel geben? – sara8d

+1

Ich verstehe nicht, dass Konstruktorargumente nicht gut sind OOP-Programmierpraxis. Natürlich wird das Hinzufügen neuer Argumente den Benutzercode brechen, aber das Gleiche gilt für das Übergeben von Daten über die Konfigurations-DB oder das direkte Setzen von Variablen. Es gibt keine Problemumgehung zum Ändern des Client-Codes, wenn sich die Abhängigkeiten einer Klasse ändern. –

+1

Der Punkt der Vererbung und Polymorphie ist in der Lage, die Funktionalität von Objekten zu erweitern, ohne den Code mit diesen erweiterten Objekten zu stören. Das Gleiche gilt für das Erstellen von Transaktionen. Anstatt Methoden mit langen Argumentlisten zu verwenden, fügen wir diese Argumente in eine Transaktion ein und erweitern die Transaktion nach Bedarf. –

1

Sie können die Klasse uvm_config_db für die Initialisierung verwenden.

Sie können den Wert mithilfe der folgenden Syntax festlegen. Und dann können Sie diesen Wert innerhalb des Konstruktors dieser Klasse erhalten.

uvm_config_db#(int)::set(this,“my_subblock_a”,“max_cycles”,max_cycles) 
uvm_config_db#(int)::get(this,“”, “max_cycles”,max_cycles) 

Weitere Informationen von „uvm_config_db“ können Sie auf die folgende Papier beziehen. https://www.synopsys.com/Services/Documents/hierarchical-testbench-configuration-using-uvm.pdf

+1

nach dem Papier sollte das "bekommen" sein. Ich habe im Konstruktor kein "bekommen" gesehen. – sara8d

+1

Methoden "get" und "set" sind statische Methoden der Klasse uvm_config_db. Und Sie können die "get" -Methode überall verwenden, solange die require-Variable mit der "set" -Methode gesetzt wird –

Verwandte Themen