2016-06-25 3 views
2

Предположим, у нас есть протокол, где запрос req указан с req_id и соответствующий rsp будет указан с rsp_id. Они могут быть не в порядке. Я хочу покрыть количество clks или латентность между 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 
+0

** Не работает ** означает что? Ошибка компилятора? нет покрытия? Пожалуйста, предоставьте тестовый файл. –

+0

Извините. Я хочу знать, правильно ли это было? Будет ли это покрывать мою латентность? – user1978273

ответ

1

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

Если 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 отделить запрос от ответа.

0

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

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

Ниже приведен пример рабочего примера. Вы можете изменить [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); 
+0

@RahulMnenon Ваш код будет пропустить случай, когда ответ приходит сразу после запроса (т. Е. Существует нулевая латентность), потому что вам требуется хотя бы один цикл, в котором вы увеличиваете. –

0

В качестве альтернативы ...

недвижимости/последовательности, хотя они кажутся небольшим кодом, в этом случае для каждого REQ (который до сих пор не получил 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 видно и только один поток активен ищет его. При необходимости в функцию могут быть добавлены дополнительные проверки, но для подсчета латентности это должно быть хорошо.

Анекдот:

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

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