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?
@ dave_59- Können Sie mir ein Beispiel geben? – sara8d
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. –
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. –