UVM: создайте задачу, которая вызывается примерно каждые 100 циклов для всех компонентов.

Для всех моих компонентов (монитор, драйвер, секвенсор и т. д.) мне нужно создать задачу, которая вызывается каждые 100 или около того циклов. Я думаю, что есть способ сделать это с помощью пользовательских фаз, но не уверен, как это сделать. Любая помощь.


person Romeo    schedule 09.12.2016    source источник


Ответы (4)


Функция псевдомножественного наследования, представленная в 1800-2012 годах через «класс интерфейса» и «реализует», является лучшим решением. Чтобы удовлетворить ваши требования, вы можете применить шаблон проектирования Observer. Ниже приведен пример кода

interface class tick;
    pure virtual task trigger_tick(....);
end class

class observer extends uvm_components;
    ......
    tick tick_list[$];

    virtual function void register_tick(tick t);
        tick_list.push_back(t);
    endfunction 

    virtual task run_phase(uvm_phase phase);
        forever begin
            repeat(100) @(posedge top.clock);
            foreach (tick_list[i]) tick_list[i].trigger_tick();
        end
    endtask
end class

class my_component extends uvm_component implements tick;
......
    virtual task trigger_tick();
//do something
    endtask
end class

Затем вы можете создать экземпляр наблюдателя и зарегистрировать все компоненты в экземпляре.

person Mateo Huang    schedule 23.12.2016

Я не думаю, что вам нужно реализовывать пользовательские фазы для этого. Вот пример того, как вы можете это сделать.

task run_phase(uvm_phase phase);

  forever begin  
    // wait for reset ....

    fork 
       your_task1();
    join_none

    // do other things .....
  end

endtask : run_phase

task your_task1(); // this task will keep running forever..

  int count=1; 
  forever begin
    @(posedge vif.clk);

    if(count%100 == 0)  // will be true only when count becomes multiple of 100
       your_task2();

    count++;
  end

endtask : your_task1

task your_task2(); // one which you wanted to call every 100 clk cycles
   // add your logic
endtask : your_task2

Надеюсь это поможет.

person sundar    schedule 09.12.2016
comment
Это будет отлично работать для одного экземпляра. Мне нужно универсальное решение, которое можно применить ко всем компонентам. - person Romeo; 09.12.2016
comment
Вы можете создать базовый класс и позволить вашим компонентам драйвера, монитора, секвенсора наследовать его. Со стандартом SystemVerilog 2012 вы можете добиться множественного наследования, расширив класс из более чем одного класса с помощью ключевого слова «реализует» (аналогично java). Перейдите по этой ссылке cfs-vision.com/2016/03. /10/multiple-inheritance-in-systemverilog Но вам нужен симулятор, который это поддерживает. - person sundar; 09.12.2016

Вы можете добавить эту логику в run_phase каждого компонента следующим образом.

task run_phase (uvm_phase phase);
  fork
    begin
      forever
      begin
        repeat (100) @(posedge virtual_interface.clk);
        your_task();
      end   
    end
    // Other threads
  join_none
  wait_fork;
endtask
person Karan Shah    schedule 10.12.2016

Вы можете использовать uvm_events, например, из каждого компонента генерировать событие в 100-м цикле, а из вашего собственного класса перехватывать это событие и вызывать задачу.

Не могли бы вы объяснить, почему вам нужно запускать задачу для каждого из компонентов? Я предполагаю, что вы что-то отлаживаете, может быть, запись транзакций или uvm_printer были бы здесь более полезными.

person haykp    schedule 10.12.2016