2016-09-21 8 views
1

Мне нужно следить за состоянием регистра. Я создал последовательность UVM, чтобы прочитать регистр и хранить их локально. Теперь в моем тестовом коде мне нужно получить доступ к этим регистрам. Вот код Суд:Ссылка на последовательность UVM

typedef struct { 
    int a; 
} my_regs; 

class my_seq extends uvm_sequence; 
    // register to uvm db 
    reg_map  map; 
    my_regs  regs; 
    uvm_status_e status; 

    task build_phase(uvm_phase phase); 
    endtask 

    task run_phase(uvm_phase phase); 
     map.CORE.reg_a.read(status, regs.a, UVM_BACKDOOR) 
    endtask 
endclass 

class test_reg extends uvm_test; 
    // register to uvm db 
    my_seq seq; 
    my_regs regs; 

    task build_phase(uvm_phase phase); 
     seq = my_seq::type_id::create("reg_seq", this); 
     regs = seq.regs; 
    endtask 

    task run_phase(uvm_phase phase); 
     reg_seq.start(null); 
     // read reg values from seq?????? 
     if(rqgs.a>1) 
      //do some thing 

    endtask 
endclass 

Как вы можете видеть, я постоянно начинаю последовательность, так что я не пропустите ни одной новость. Я считаю, что задача start не создает новый объект , поэтому значения внутри объекта должны оставаться постоянными между начальными вызовами.

Предполагая, что я не читаю значения regs из seq каждый раз, журналы тестового класса не получат обновления из seq. Это означает, что regs = seq.regs; не создает фактическую ссылку на seq.regs. Я хочу знать, почему это так и как я могу создать абсолютную ссылку на этот объект? (так что я не трачу циклы моделирования при чтении и обновлении значений regs в тестовом классе). Также, пожалуйста, сообщите мне, есть ли лучший способ сделать это.

ответ

2

Во-первых, незначительное исправление. Последовательность не имеет фаз сборки или запуска. Они в отличие от других uvm_components не запускаются автоматически [с использованием системы фазировки]. Последовательность имеет задачу тела, которая переопределяется для реализации функциональности (в этом случае считывается регистр). Поэтому код из run_phase необходимо перенести в функцию body.

class my_seq extends uvm_sequence; 
    // register to uvm db 
    reg_map  map; 
    my_regs  regs; 
    uvm_status_e status; 
function new(string name="my_seq"); 
    super.new(name); 
    endfunction 

    task body(); 
     map.CORE.reg_a.read(status, regs.a, UVM_BACKDOOR); 
    endtask 
endclass 

После того, как последовательность вызова он будет считывать значение из RTL регистрации и обновления «в» поле в регуляров в классе my_seq.

regs = seq.regs; // 

regs (в тесте) предоставит постоянную ссылку на поле regs в последовательности. Поэтому в любой момент, когда последовательность считывает регистр и обновляет поле regs, переменная regs в test_reg увидит изменение, но это означает, что регистр должен быть прочитан из RTL. Тест_reg должен был бы реализовать цикл, чтобы периодически считывать регистр (вызывая последовательность my_seq). Это связано с тем, что переменная regs или карта поля регистра. CORE.reg_a не является прямой ссылкой на регистр в RTL.

Вам нужно будет провести симуляционные циклы, считывая регистр RTL, так как uvm_register - это только зеркало/копия, которая обновляется только при чтении.

Вопрос в том, как получить доступ к регистру через прошивку? Если доступ к регистру осуществляется через механизм полирования, лучше его подражать в тестовом примере.

task run_phase(uvm_phase phase); 
    task_done = 0; 
    while (!task_done) 
     begin 
     // wait for some delay as backdoor access takes 0 simulation time 
     reg_seq.start(null); // regs is updates 
     // read reg values from seq - done 
     if(regs.a>1) // check for bit to be set 
     begin 
      task_done = 1; 
      //do some thing 
     end 
     // else continue to poll register 
     end 
end task 

В качестве альтернативы можно было бы ждать сигнала RTL изменить, а затем выпустить на чтение (этот метод не желательно, так как мы доступа сигналы РТЛ от испытательного стенда.)

task run_phase(uvm_phase phase); 
      wait (RTL.module.reg.CORE.reg_a == 1) ; 
      reg_seq.start(null); // regs file is updates 
      // read reg values from seq - done 
      if(regs.a>1) // check for bit to be set 
       //do some thing 
    endtask 
+0

О, ты прав , поскольку я сказал, что это код sudo, и в исходном коде я реализовал тело так, как вы описали. Еще раз спасибо! – maskarih

+0

:) Получил это. Просто убедитесь, что все. Добро пожаловать . –