Последовательное тестирование и утверждения с помощью System-Verilog

У меня есть последовательный вывод модуля Verilog, который я хотел бы протестировать с помощью system-verilog.

Результат, названный 'SO', будет выводить что-то вроде 8'hC6 при правильном последовательном входе 'SI' со значением, скажем, 8'h9A.

Есть ли простой способ кодировать / декодировать последовательные операции ввода-вывода без явного описания каждого сигнала?

Например:

assert property @(posedge clk) $rose(EN) |-> ##[1:3] SI ##1 !SI[*2] ##1 SI[*2] ##1 !SI ##1 SI ##1 !SI
                                             ##[1:3] SO[*2] ##1 !SO[*3] ##1 SO[*2] ##1 !SO;

Это похоже на беспорядок и плохо читается. Я бы очень хотел просто написать

8'h9A ##[1:3] 8'hC6

но, очевидно, это не работает. Любые советы или примеры будут более чем приветствоваться. Заранее спасибо.


person N8TRO    schedule 11.06.2013    source источник


Ответы (2)


Попробуйте выполнить последовательность и обратитесь к разделу 16.10 IEEE Std 1800-2012 ( Локальные переменные):

sequence seq_serial(logic signal, local logic [7:0] expected);
    byte idx = 7;
    (signal == expected[idx], idx--)[*8];
endsequence : seq_serial

asrt_si0x9A_so0xC6 : assert property ( @(posedge clk)
    $rose(EN) |-> ##[1:3] seq_serial(SI, 8'h9A) ##[1:3] seq_serial(SO, 8'hC6) );

Это эквивалентно предоставленному утверждению и более читабельно.

Обратите внимание на ключевое слово local, которое будет рассматривать expected как переменную, а не ссылку, и позволяет вам передавать константу (например, 8'h9A, 8'hC6) и по-прежнему позволяет передавать сетевые ссылки. См. IEEE Std 1800-2012 раздел 16.8.2 (формальная локальная переменная). аргументы в объявлениях последовательности) для получения дополнительных сведений.

Вот простой тестовый стенд, чтобы доказать это утверждение. Я за рулем SO, потому что у меня нет настоящего тестируемого устройства, и я хочу продемонстрировать сценарий «годен и не годен».

bit EN, clk;
logic SI,SO;
logic [7:0] si_var, so_var;
initial forever #10ns clk++; // clock generator
default clocking cb @(posedge clk); output #1ns EN,SI,SO; endclocking : cb
initial begin : test_vector
    si_var = 8'h9A;
    so_var = 8'hC6;
    ##1 cb.EN <= 1;
    ##($urandom_range(2,0)); // rand delay
    foreach(si_var[i]) ##1 cb.SI <= si_var[i];
    ##($urandom_range(2,0)); // rand delay
    foreach(so_var[i]) ##1 cb.SO <= so_var[i];
    ##1 cb.EN <= 0;

    /* Now make the assertion fail */
    so_var = 8'hC7; // make fail
    ##3 cb.EN <= 1;
    ##($urandom_range(2,0)); // rand delay
    foreach(si_var[i]) ##1 cb.SI <= si_var[i];
    ##($urandom_range(2,0)); // rand delay
    foreach(so_var[i]) ##1 cb.SO <= so_var[i];
    ##1 cb.EN <= 0;

    #10ns; // little delay before finish
    $finish(2);
end : test_vector
person Greg    schedule 11.06.2013
comment
Именно то, что я искал. Блестящий ответ. Спасибо огромное. - person N8TRO; 12.06.2013
comment
Одна вещь, однако, T получал ошибки каждый раз, когда я пытался использовать тип данных local. - person N8TRO; 17.06.2013
comment
Возможно, ваш поставщик еще не реализовал local в качестве поста последовательности. Это был IEEE Std 1800-2005, который явно ничего не говорит, но есть примеры в -2009 и -2012. Два обходных пути (потрудитесь поработать на моем симуляторе): 1) отбросить local, присвоить значения переменным (например, si_var и so_var) и передать переменные в последовательность (например, seq_serial3(SI, si_var) ##[1:3] seq_serial3(SO, so_var)). 2) отбросьте local, ниже byte idx=7; добавьте logic [7:0] sampled = expected; и поменяйте местами expected[idx] на sampled[idx]. - person Greg; 17.06.2013
comment
Ага .. Без local работал отлично. Я знаю, что каждый поставщик реализует рекомендации по-своему. Я просто счастлив, что это работает. - person N8TRO; 18.06.2013

Обычно утверждения используются не для описания проверок элементов данных, а для сигналов управления. В этом случае вам нужно собрать весь входной поток в 16-битный вектор, собрать весь выходной поток и проверить, что то, что вы получили в строке SO, совпадает с тем, что вы должны получить (некоторое преобразование того, что было в SI линия).

Мой SystemVerilog устарел, но я дам вам быстрый пример того, что я имею в виду. Имейте в виду, что он не компилируется.

// collect input
always @(posedge clk) begin
  if en == 1 begin
    collect_input();
  end
end

logic[7:0] si;

task collect_input();
  for i from 0 to 7 begin
    si[i] = SI;  // take care of endianness here, might be si[7-i];
  end
endtask


// collect output
...

logic[7:0] so;

...

collect_output();
  for ...

  // after collecting so, check that it's correct
  if so != transform(si) begin
    $error("wrong output data");
  end
endtask

Надеюсь, это даст вам представление.

person Tudor Timi    schedule 11.06.2013
comment
Вы можете использовать эту концепцию даже с утверждениями. Секрет SVA в том, что вы можете написать обычный код для преобразования того, что вы хотите проверить, в удобную форму, а затем инициировать утверждение для выполнения проверки. Для этого я бы использовал что-нибудь более гибкое. - person Paul S; 11.06.2013