Предположим, у нас есть протокол, в котором говорится следующее. После того, как мастер устанавливает req
к fill
, ведомый сигнал 4 передачи с помощью rsp
:Избегайте кода поддержки для последовательности SVA для обработки конвейерной транзакции
Последовательность СВА для всей этой операции будет (при условии, что ведомый может вставить idle
циклов между trans
циклов):
req == fill ##1 (trans [->1]) [*4];
Теперь предположим, что хозяину разрешено запрашивать конвейер. Это означало бы, что следующий fill
разрешено начинать до того, как 4 trans
циклы выполняются:
Последовательность SVA сверху не поможет, потому что для второго fill
это будет неправильно соответствовать 4 trans
циклов, оставив последний trans
«плавающий». Необходимо было бы начать сопоставление trans
циклов только после того, как совпадают предыдущие fill
.
Последовательность требует глобальной информации, недоступной в рамках одной оценки. В основном, он должен знать, что другой экземпляр его запущен. Единственный способ, которым я могу думать о реализации этого использует некоторый RTL код поддержки:
int num_trans_seen;
bit trans_ongoing;
bit trans_done;
bit trans_queued;
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
num_trans_seen;
trans_ongoing <= 0;
trans_done <= 0;
trans_queued <= 0;
end
else begin
if (trans_ongoing)
if (num_trans_seen == 3 && req == trans) begin
trans_done <= 1;
if (req == fill || trans_queued)
trans_queued <= 0;
else
trans_ongoing <= 0;
num_trans_seen == 0;
end
else
if (trans_queued) begin
trans_queued <= 0;
trans_ongoing <= 1;
end
if (trans_done)
trans_done <= 0;
end
выше код должен поднять trans_ongoing
немного, пока транзакция продолжается и пульс trans_done
в такте, когда последний trans
для fill
отправлено. (. Я говорю должно, потому что я не проверял, но это не точка Давайте предположим, что он работает.)
Имея что-то вроде этого, можно было бы переписать последовательность быть:
req == fill ##0 (trans_ongoing ##0 trans_done [->1]) [*0:1]
##1 (trans [->1]) [*4];
Это должно сработать, но я не особо волнуюсь о том, что мне нужен код поддержки. В нем много избыточности, потому что я в основном переработал хороший кусок того, что такое транзакция и как работает конвейерная обработка. Это также не так легко повторно использовать. A sequence
можно поместить в пакет и импортировать в другое место. Код поддержки может быть помещен только в некоторый модуль и повторно использован, но это другой логический объект, чем пакет, который сохранит последовательность.
Вопрос здесь: есть ли способ написать конвейерную версию последовательности, избегая при этом необходимости поддержки кода?
Легко декодировать разницу между холостым RSP и трансом? – Greg
Что я понял, что если между циклами «заполнять» и «4» транса будет добавлено другое «заполнение», тогда более поздняя «заполняющая» будет простейшим игнорироваться (на изображении будет проигнорировано второе «заполнение»). Прошу прокомментировать мое понимание. –
@ KaranShah Nope, второе заполнение имеет 4 цикла «транс», начинающиеся после завершения текущих. –