Как покрыть задержку между запросом и ответом

Допустим, у нас есть протокол, где запрос req утверждается с req_id и соответствующий rsp будет утверждено с rsp_id, Они могут быть не в порядке. Я хочу покрыть количество кликов или задержку между req с особым req_id а также rsp с тем же идентификатором. Я попробовал что-то подобное. Это правильный способ сделать? Есть ли другой эффективный способ?

covergroup cg with function sample(int a);
  coverpoint a {
  a1: bins short_latency = {[0:10]};
  a2: bins med_latency = {[11:100]};
  a3: bins long_latency = {[101:1000]};
  }
endgroup
// Somewhere in code
cg cg_inst = new();

sequence s;
  int lat;
  int id;
  @(posedge clk) disable iff (~rst)
    (req, id = req_id, lat = 0) |-> ##[1:$] ((1'b1, lat++) and (rsp && rsp_id == id, cg_inst.sample(lat)));
endsequence

3 ответа

Решение

Вы пытаетесь использовать |-> оператор внутри последовательности, который разрешен только внутри свойства.

Если rsp может прийти только один цикл после req, тогда этот код должен работать:

property trans;
    int lat, id;

    (req, id = req_id, lat = 0) |=> (1, lat++) [*0:$] ##1 rsp && rsp_id == id
      ##0 (1, $display("lat = %0d", lat));
endproperty

Элемент после ##0 там для отладки. Вы можете опустить его в производственном коде.

Я бы не стал смешивать утверждения и покрытие таким образом, поскольку я видел, что операторы импликации могут вызывать проблемы с переменным потоком (т.е. lat не будет обновляться должным образом). У вас должно быть свойство, которое просто покрывает то, что вы видели соответствующий ответ после запроса:

property cov_trans;
    int lat, id;

    (req, id = req_id, lat = 0) ##1 (1, lat++) [*0:$] ##1 rsp && rsp_id == id
      ##0 (1, $display("cov_lat = %0d", lat));
endproperty

cover property (cov_trans);

Обратите внимание, что я использовал ##1 отделить запрос от ответа.

По сути, ваша идея верна, но похоже, что правая часть последовательности будет оценена один раз, когда условие выполнено, и, следовательно, значение lat будет увеличено только один раз.

Вам понадобится петлевой механизм для подсчета времени ожидания.

Ниже приведен пример рабочего примера. Вы можете изменить [1:$], ##1 и т. Д. В зависимости от того, насколько близко генерируются сигналы.

property ps;
  int lat;
  int id;
  @(posedge clk)
     disable iff (~rst)
        (req, id = req_id, lat = 0) |=> (1'b1, lat++)[*1:$] ##1 (rsp && rsp_id == id, cg_inst.sample(lat));
endproperty

assert property (ps);

С другой стороны...

свойство / последовательность, хотя они кажутся небольшим кодом, в этом случае для каждого запроса (который еще не получил rsp) отдельный процесс со своим собственным счетчиком разветвляется. Это приводит к тому, что многие счетчики выполняют очень похожую работу. Если в полете есть много требований (и / или много экземпляров свойства или последовательности), он начнет добавляться во время выполнения симуляции [хотя это всего лишь небольшой блок кода]

поэтому другой подход заключается в том, чтобы упростить триггер, и мы пытаемся сделать обработку линейной.

int counter=0; // you can use a larger variablesize to avoid the roll-over issue
int arr1[int] ;  // can use array[MAX_SIZE] if you know the max request id is small
always @( posedge clk ) counter <= counter + 1 ; // simple counter 


function int latency (int type_set_get , int a ) ;
    if ( type_set_get == 0 ) arr1[a] = counter; // set
                                 //DEBUG $display(" req id %d latency %d",a,counter-arr1[a]);
                                 // for roll-over - if ( arr1[a] > counter ) return ( MAX_VAL_SIZE  - arr1[a] + counter ) ; 
   return (counter - arr1[a]);  //return the difference between captured clock and current clock .
endfunction

property ps();
  @(posedge clk) 
     disable iff (~rst) 
         ##[0:$]( (req,latency(0,req_id) ) or  (rsp,cg_inst.sample(latency(1,rsp_id))) );
endproperty

assert property (ps);

Вышеупомянутое свойство срабатывает только тогда, когда req/rsp замечен, и только 1 поток активен, ищет его. При необходимости в функцию могут быть добавлены дополнительные проверки, но для подсчета задержки это должно быть хорошо.

Анекдот:

Ментор А.Е. - Дэн обнаружил утверждение, которое замедляло наше моделирование на целых 40 % . Плохо написанное утверждение было частью нашего блока tb, и его последствия остались незамеченными, так как в нашем тесте на уровне блоков время выполнения было ограничено. Затем он проник в наш tb верхнего уровня, что привело к неописуемым потерям во время выполнения, пока его не обнаружили год спустя:) . [думаю, мы должны были профилировать наши симуляции раньше]

Скажем, к примеру, если вышеупомянутый протокол реализовал прерывание позднее, тогда поток req-rsp продолжит обрабатывать и ждать (до завершения моделирования) прерванной транзакции, хотя это не повлияет на функциональность, он будет незаметно продолжаться тратить ресурсы процессора, ничего не делая взамен. До тех пор, пока, наконец, не выйдет продавец АЕ, чтобы спасти день:)

Другие вопросы по тегам