Я новичок в UVM, и я пытаюсь проверить структуру памяти, в которой я пытаюсь запустить последовательность записи несколько раз, за которой следует последовательность чтения такое же количество раз, чтобы я мог читать те же адреса, на которые я пишу, и сравнивать. Для этого я попытался создать новый класс, расширенный из uvm_object, с очередью для хранения адресов, в которые я пишу, чтобы я мог использовать их в последовательности чтения, и я создаю экземпляр этого класса в табло, а затем отправляю дескриптор класса в последовательность чтения через uvm_config_db, теперь проблема в том, что я могу хранить адреса в очереди, но не могу получить дескриптор класса в последовательности чтения ...... Это правильный способ проверки или есть лучший способ проверить писать и читать по памяти, пожалуйста, помогите мне!
вся ссылка на код (еще не завершена): https://www.edaplayground.com/x/3iTr Соответствующие фрагменты кода: Это класс, который я создал для хранения адресов
class address_list extends uvm_object;
reg[7:0]addr_q[$];
function new(string name);
super.new(name);
endfunction
endclass;
В моем табло я передаю дескриптор класса с очередью адресов в последовательность чтения, вот фрагмент из табло
virtual function void write(mem_seq_item pkt);
if (pkt.wr_en==1)
begin
pkt_qu_write.push_back(pkt);
addr.addr_q.push_back(pkt.addr);
uvm_config_db#(address_list)::set(uvm_root::get(),"*","address",addr);
end
if (pkt.rd_en==1)
pkt_qu_read.push_back(pkt);
`uvm_info(get_type_name(),$sformatf("Adder list is
%p",addr.addr_q),UVM_LOW)
endfunction : write
В моей последовательности чтения я пытаюсь получить дескриптор
virtual task body();
repeat(3)
`uvm_do(wr_seq)
if (!uvm_config_db#(address_list)::get(this, " ", "address", addr_))
`uvm_fatal("NO_VIF",{"virtual interface must be set for:",get_full_name(),".addr_"});
`uvm_info(get_type_name(),$sformatf("ADDR IS %p",addr_),UVM_LOW)
repeat(3)
`uvm_do(rd_seq)
endtask
Error-[ICTTFC] Incompatible complex type usage
mem_sequence.sv, 137 {line where i try to get from uvm_config_db}
Incompatible complex type usage in task or function call.
The following expression is incompatible with the formal parameter of the
function. The type of the actual is 'class $unit::wr_rd_sequence', while
the
type of the formal is 'class uvm_pkg::uvm_component'. Expression: this
Source info: uvm_config_db#
(_vcs_unit__3308544630::address_list)::get(this,
" ", "address", this.addr_)
В этой строке есть две проблемы:
if (!uvm_config_db#(address_list)::get(this, " ", "address", addr_))
Одна из них вызывает вашу ошибку. Один из них может привести к тому, что вы не сможете найти то, что ищете в базе данных.
Это (буквально this
) вызывает вашу ошибку. Вы вызываете get
из класса, производного от uvm_sequence
. Первый аргумент get
ожидает класс, производный от uvm_component
. Ваша проблема в том, что последовательность не является частью иерархии тестового стенда, поэтому вы не можете использовать последовательность в качестве первого аргумента для вызова get
(или set
) в uvm_config_db
. Вместо этого принято использовать секвенсор, на котором выполняется последовательность, который возвращается вызовом метода последовательности get_sequencer()
. Это решает вашу проблему:
if (!uvm_config_db#(address_list)::get(get_sequencer(), "", "address", addr_))
Это работает, потому что вы использовали подстановочный знак, когда вызывали set
.
Обратите внимание, что я также удалил пробел между кавычками. Это может не вызвать у вас проблем, потому что вы использовали подстановочный знак при вызове set
, но в целом эта строка должна быть либо пустой, либо представлять собой реальный иерархический путь. (Ввод иерархии для вызовов set
и get
разделен между первым аргументом — иерархическим путем SystemVerilog — и вторым — строкой, представляющей иерархический путь).
uvm_config_db
в основном для передачи конфигурации между компонентами.
Для передачи данных из табло в последовательность вы можете использовать uvm_event
.
event.trigger(address_list)
event.wait_for_trigger_data(address_list)