Последовательности
Последовательности описывают поведение проекта во времени и строятся на основе логических выражений. Выражение «(CMD != `IDLE)» – это простая последовательность, состоящая из одного логического выражения. Сложные последовательности строятся с использованием временных задержек, которые задаются с помощью оператора «##». Рассмотрим построение сложных последовательностей на примере взаимодействия сигналов «a» и «b»:
Рис. 5. 1) Сигнал «b» установится в ‘1’ в том же такте, что и сигнал «a». 2) Сигнал «b» установится в ‘1’ на следующем такте после «a». 3) Сигнал «b» установится в ‘1’ через 2 такта после «a». 4) Сигнал «b» установится в ‘1’ в промежутке 0-2 тактов после «a» (данной последовательности удовлетворяет любая из последовательностей 1)-3)).
Для промежутка тактов можно указать безграничный верхний предел с помощью оператора «$». Последовательность «a ##[2:$] b» означает, что сигнал «b» появится не менее чем через 2 такта после «a». Если сигнал «b» не появится до конца симуляции, то выдастся сообщение об ошибке. Во всех рассмотренных выше примерах последовательностей можно использовать вместо сигналов «a» и «b» последовательности логических выражений. Последовательное повторение сигнала или последовательности в SystemVerilog реализуется с помощью оператора «*». Например, последовательность «a ##1 a» можно записать в виде «a[*2]». Примеры:
Рис. 6. 1) Сигнал «b» установится в ‘1’ после двух повторений сигнала «a». 2) Сигнал «b» установится в ‘1’ после 1-го или 2-х повторений «a». 3) Последовательность «a ##1 b» повторится 2 раза.
Если повторения сигнала происходит непоследовательно, то используется оператор «->» (goto) или «=» (непоследовательное повторение). С последовательностями эти операторы не используются. Примеры:
Рис. 7. 1) Сигнал «b» установится в ‘1’ на следующем такте после 2-го повторения «a». 2) Сигнал «b» установится в ‘1’ не раньше, чем сигнал «a» повторится 2 раза и примет значение ‘0’.
Операторы «->» и «=» ведут себя по-разному только после последнего повторения сигнала. Конструкции «a[->2]» и «a[=2]» – это краткие записи последовательностей:
- «a[->2]» = ~a[*0:$] ##1 a ##1 ~a[*0:$] ##1 a
- «a[=2]» = ~a[*0:$] ##1 a ##1 ~a[*0:$] ##1 a ##1 ~a[*0:$]
Многократное использование одних и тех же последовательностей осуществляется с помощью ключевых слов sequence, endsequence:
- sequence seq;
- (a ##1 b);
- endsequence
Использование одной и той же последовательности для разного набора сигналов реализуется с помощью параметров:
- sequence seq;
- (a ##1 b);
- endsequence
В SystemVerilog поддерживается ряд операций над последовательностями, которые позволяют строить на основе существующих последовательностей новые более сложные последовательности. Если необходимо, чтобы выполнились 2 последовательности, которые начинаются в одно время, используется оператор and. При этом завершится эта сложная последовательность тогда, когда завершится самая длинная из 2-х последовательностей. Рассмотрим пример:
- sequence s1;
- (a ##[1:2] b);
- endsequence
- sequence s2;
- (c ##[2:3] d);
- endsequence
Операции «s1 and s2» будут удовлетворять последовательности:
Рис. 8. Операция and для двух последовательностей
Для случая, когда необходимо, чтобы 2 последовательности начинались и заканчивались в одно время, используется оператор intersect. Для приведенных выше последовательностей операции «s1 intersect s2» будет удовлетворять только последовательность:
Рис. 9. Операция intersect для двух последовательностей
Выполнение любой из 2-х последовательностей описывается с помощью оператора or. Операция «s1 or s2» будет считаться выполненной при возникновении любой из последовательностей:
Рис. 10. Операция or для двух последовательностей
Если необходимо, чтобы из нескольких возможных последовательностей проверялась только самая короткая, используется оператор first_match. Для последовательности s2 операция «first_match(s2)» будет означать выполнение из 2-х возможных последовательностей только одной:
Рис. 11. Операция first_match для последовательности s2
Оператор throughout используется в случае, когда в ходе выполнения последовательности необходимо выполнение логического выражения. Пример:
Рис. 12. Операция throughout для сигнала «с» и последовательности s1
Если одна последовательность должна выполниться в промежутке выполнения другой последовательности, используется оператор within. Операция «s1 within s2» означает, что начало и конец последовательности s1 должны быть между началом и концом последовательности s2:
Рис. 13. Операция within для двух последовательностей
В качестве синхронизирующей точки при объединении нескольких последовательностей используется точка начала выполнения последовательности. В SystemVerilog есть способ объединения последовательностей, где в качестве синхронизирующей точки выступает конечная точки выполнения последовательности. Для этого используется ключевое слово ended. Для последовательностей s1 и s2 выражение вида «s1 ##1 s2.ended» будет означать, что после выполнения последовательности s1 на следующем такте должна закончить свое выполнение последовательность s2:
Рис. 14. Применение оператора ended
Рассмотрим еще одну последовательность «s1 ##2 s2.ended». Ей будут удовлетворять последовательности:
- a ##1 (b & c) ##2 d
- a ##2 (b & c) ##2 d
- (a & c) ##1 b ##2 d
- a ##1 c ##1 b ##2 d