DocsTech
/
VERILOG HDL
/

~ cd 14. specify блоки в verilog hdl

Два типа HDL-конструкций часто используются для описания задержек для структурных моделей, таких как ячейки ASIC. Они следующие:

Этот пункт описывает, как пути задаются в модуле и как задержки назначаются этим путям.

14.1 Объявление specify блока

Блочный оператор, называемый блоком specify, является средством описания путей между источником и пунктом назначения и назначения задержек для этих путей. Синтаксис для блоков specify показан в Синтаксисе 14-1.

...
Копировать
specify_block ::=
    specify { specify_item } endspecify
specify_item ::=
    specparam_declaration
    | pulsestyle_declaration
    | showcancelled_declaration
    | path_declaration
    | system_timing_check
Синтаксис 14-1-Синтаксис для блока specify

Блок specify должен быть ограничен ключевыми словами specify и endspecify и должен появляться внутри объявления модуля. Блок specify может быть использован для выполнения следующих задач:

Пути, описанные в блоке спецификации, называемые модульными путями, соединяют источник сигнала с местом назначения сигнала. Источник может быть однонаправленным (входной порт) или двунаправленным (выходной порт) и называется источником пути модуля. Аналогично, место назначения может быть однонаправленным (выходной порт) или двунаправленным (входной порт) и называется местом назначения пути модуля.

Например:
...
Копировать
specify
    specparam tRise_clk_q = 150, tFall_clk_q = 200;
    specparam tSetup = 70;
    (clk => q) = (tRise_clk_q, tFall_clk_q);
    $setup(d, posedge clk, tSetup);
endspecify

Первые две строки, следующие за ключевым словом specify, объявляют параметры specify, которые рассматриваются в разделе 4.10.3. Строка, следующая за объявлением параметров specify, описывает путь модуля и назначает задержки этому пути модуля. Параметры specify определяют задержку, назначенную пути модуля. Указание путей модулей представлено в разделе 14.2. Назначение задержек путям модулей рассматривается в разделе 14.3. Строка, предшествующая ключевому слову endspecify, объявляет одну из проверок синхронизации системы, которые рассматриваются далее в п. 15.

14.2 Объявление пути к модулю

Для настройки задержек пути модуля в specify блоке необходимо выполнить два шага:

1) Опишите пути модулей.

2) Назначьте задержки для этих путей (см. 14.3).

Синтаксис объявления пути модуля описан в Синтаксис 14-2.

...
Копировать
path_declaration ::=
    simple_path_declaration ;
    | edge_sensitive_path_declaration ;
    | state_dependent_path_declaration ;
Синтаксис 14-2-Синтаксис для объявления пути к модулю

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

Например:

На рисунке 14-1 показана схема с задержками на пути модуля. Более одного источника (A, B, C и D) могут иметь модульный путь к одному и тому же месту назначения (Q), и для каждого пути от входа к выходу могут быть заданы различные задержки.

На рисунке 14-1 показана схема с задержками на пути модуля Verilog HDL. Более одного источника (A, B, C и D) могут иметь модульный путь к одному и тому же месту назначения (Q), и для каждого пути от входа к выходу могут быть заданы различные задержки.
Рисунок 14-1 Модульные задержки на пути

14.2.1 Ограничения пути модуля

Пути модулей имеют следующие ограничения:

14.2.2 Простые пути модулей

Синтаксис для указания простого пути к модулю приведен в Синтаксисе 14-3.

...
Копировать
simple_path_declaration ::=
    parallel_path_description = path_delay_value
    | full_path_description = path_delay_value
parallel_path_description ::=
    ( specify_input_terminal_descriptor [ polarity_operator ] =>
    specify_output_terminal_descriptor )
full_path_description ::=
    ( list_of_path_inputs [ polarity_operator ] *> list_of_path_outputs )
list_of_path_inputs ::=
    specify_input_terminal_descriptor { , specify_input_terminal_descriptor }
list_of_path_outputs ::=
    specify_output_terminal_descriptor { , specify_output_terminal_descriptor }
specify_input_terminal_descriptor ::=
    input_identifier [ [ constant_range_expression ] ]
specify_output_terminal_descriptor ::=
    output_identifier [ [ constant_range_expression ] ]
input_identifier ::=
    input_port_identifier | inout_port_identifier
output_identifier ::=
    output_port_identifier | inout_port_identifier
polarity_operator ::=
+ | -
Синтаксис 14-3 Синтаксис для простого пути модуля

Простые пути могут быть объявлены в одной из двух форм:

Символы *> и => представляют собой различные виды соединения между источником пути модуля и пунктом назначения пути модуля. Оператор *> устанавливает полное соединение между источником и пунктом назначения. Оператор => устанавливает параллельное соединение между источником и пунктом назначения. Описание путей полного и параллельного соединения приведено в разделе 14.2.5.

Например:

Следующие три примера иллюстрируют допустимые простые объявления путей к модулю:
...
Копировать
(A => Q) = 10;
(B => Q) = (12);
(C, D *> Q) = 18;

14.2.3 Пути, чувствительные к фронтам

Когда путь модуля описывается с помощью перехода по фронту в источнике, он называется чувствительным к фронту путем. Конструкция пути, чувствительного к фронту, используется для моделирования временных задержек между входом и выходом, которые возникают только при наличии заданного фронта в исходном сигнале.

Синтаксис объявления пути, чувствительного к границам, показан в Синтаксисе 14-4.

...
Копировать
edge_sensitive_path_declaration ::=
    parallel_edge_sensitive_path_description = path_delay_value
    | full_edge_sensitive_path_description = path_delay_value
parallel_edge_sensitive_path_description ::=
    ( [ edge_identifier ] specify_input_terminal_descriptor =>
    ( specify_output_terminal_descriptor [ polarity_operator ] : data_source_expression ) )
full_edge_sensitive_path_description ::=
    ( [ edge_identifier ] list_of_path_inputs *>
    ( list_of_path_outputs [ polarity_operator ] : data_source_expression ) )
data_source_expression ::=
    expression
edge_identifier ::=
    posedge | negedge
Синтаксис 14-4 — Синтаксис для объявления пути, чувствительного к границам

Идентификатор фронта может быть одним из ключевых слов posedge или negedge, связанным с дескриптором входного порта, который может быть любым входным или двунаправленным портом. Если в качестве дескриптора входного терминала указан векторный порт, то переход фронта импульса должен быть обнаружен на младшем значащем бите. Если фронтальный переход не указан, то путь считается активным при любом переходе на входном порте.

Чувствительный к фронтам путь может быть задан с помощью полных соединений (*>) или параллельных соединений (=>). Для параллельных соединений (=>) пунктом назначения должен быть любой скалярный выход или двунаправленный порт или выборка битов векторного выхода или двунаправленного порта. Для полных соединений (*>) местом назначения должен быть список из одного или нескольких векторных или скалярных портов вывода и ввода, а также битовых выборок или частичных выборок векторных портов вывода и ввода. Описание параллельных путей и путей полного соединения см. в разделе 14.2.5.

Выражение источника данных — это произвольное выражение, которое служит описанием потока данных к месту назначения пути. Это произвольное описание пути данных не влияет на фактическое распространение данных или событий через модель. То, как событие в источнике пути данных распространяется к месту назначения, зависит от внутренней логики модуля. Оператор полярности описывает, является ли путь данных инвертирующим или неинвертирующим.

Например:

Пример 1 Следующий пример демонстрирует объявление пути, чувствительного к фронтам, с оператором положительной полярности:
...
Копировать
( posedge clock => ( out +: in ) ) = (10, 8);

В этом примере, при положительном фронте тактового сигнала, путь модуля простирается от тактового сигнала до out, используя задержку нарастания 10 и задержку спада 8. Путь данных идет от in к out, причем in не инвертируется при распространении к out.

Пример 2 — Следующий пример демонстрирует объявление пути, чувствительного к фронтам, с оператором отрицательной полярности:
...
Копировать
( negedge clock[0] => ( out -: in ) ) = (10, 8);

В этом примере при отрицательном фронте clock[0] путь модуля простирается от clock[0] до out с задержкой нарастания 10 и задержкой спада 8. Путь данных идет от in к out, причем in инвертируется при распространении к out.

Пример 3 Следующий пример демонстрирует объявление пути, чувствительного к фронтам, без идентификатора фронтов:
...
Копировать
( clock => ( out : in ) ) = (10, 8);

В этом примере при любом изменении clock путь модуля простирается от clock до out.

14.2.4 Пути, зависящие от состояния

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

Описание пути, зависящее от состояния, включает следующие элементы:

Синтаксис объявления пути, зависящего от состояния, показан в Синтаксисе 14-5.

...
Копировать
state_dependent_path_declaration ::=
    if ( module_path_expression ) simple_path_declaration
    | if ( module_path_expression ) edge_sensitive_path_declaration
    | ifnone simple_path_declaration
Синтаксис 14-5-Синтаксис для путей, зависящих от состояния

14.2.4.1 Условное выражение

Операнды в условном выражении должны быть построены из следующих элементов:

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

Условное выражение должно иметь значение true (1), чтобы пути, зависящему от состояния, было присвоено значение задержки. Если условное выражение оценивается как x или z, оно должно рассматриваться как true. Если условное выражение оценивается в несколько битов, то наименьший значащий бит должен представлять результат. Условное выражение может иметь любое количество операндов и операторов.

Таблица 14-1 Список допустимых операторов в выражении задержки пути в зависимости от состояния
ОператорОписаниеОператорОписание
~побитовое отрицание&сокращение и
&побитовый и|сокращение или
|побитовое или^сокращение xor
^побитовый ксор~&уменьшение n и
^~ ~^побитовый xnor~|сокращение ни
==логическое равенство^~ ~^сокращение кснора
!=логическое неравенство{}конкатенация
&&логичный и{ {} }репликация
||логический или?:условный
!логически не

14.2.4.2 Простые пути, зависящие от состояния

Если описание пути, зависящего от состояния, является простым путем, то он называется простым путем, зависящим от состояния. Описание простого пути рассматривается в разделе 14.2.2.

Например:

Пример 1 — В следующем примере используются пути, зависящие от состояния, для описания времени работы XOR вентиля.
...
Копировать
module XORgate (a, b, out);
    input a, b;
    output out;

    xor x1 (out, a, b);

    specify
        specparam noninvrise = 1, noninvfall = 2;
        specparam invertrise = 3, invertfall = 4;
        if (a) (b => out) = (invertrise, invertfall);
        if (b) (a => out) = (invertrise, invertfall);
        if (~a)(b => out) = (noninvrise, noninvfall);
        if (~b)(a => out) = (noninvrise, noninvfall);
    endspecify
endmodule

В этом примере первые два пути, зависящие от состояния, описывают пару времен задержки нарастания и спада выходного сигнала, когда XOR-вентиль (x1) инвертирует изменяющийся вход. Последние два пути, зависящие от состояния, описывают другую пару времен задержки нарастания и спада выходного сигнала, когда XOR-вентиль буферизирует изменяющийся вход.

Пример 2 — Следующий пример моделирует неполный АЛУ. Пути, зависящие от состояния, задают различные задержки для разных операций АЛУ.
...
Копировать
module ALU (o1, i1, i2, opcode);
    input [7:0] i1, i2;
    input [2:1] opcode;
    output [7:0] o1;

    //functional description omitted
    specify
                // операция добавления
        if (opcode == 2'b00) (i1,i2 *> o1) = (25.0, 25.0);
                // сквозная операция i1
        if (opcode == 2'b01) (i1 => o1) = (5.6, 8.0);
                // сквозная операция i2
        if (opcode == 2'b10) (i2 => o1) = (5.6, 8.0);
                // задержки при изменении opcode
        (opcode *> o1) = (6.1, 6.5);
    endspecify
endmodule

В предыдущем примере первые три объявления путей объявляют пути, простирающиеся от входов операндов i1 и i2 до выхода o1. Задержки на этих путях назначаются операциям на основе операции, указанной на входах opcode. Последнее объявление пути декларирует путь от входа opcode до выхода o1.

14.2.4.3 Чувствительные к фронтам пути, зависящие от состояния

Если описание пути, зависящего от состояния, описывает путь чувствительный к фронтам, то путь, зависящий от состояния, называется чувствительным к фронтам путем, зависящим от состояния. Чувствительные к фронтам пути обсуждаются в разделе 14.2.3.

Различные задержки могут быть назначены одному и тому же чувствительному к фронту пути при условии соблюдения следующих критериев:

Например:

Пример 1
...
Копировать
if ( !reset && !clear )
    ( posedge clock => ( out +: in ) ) = (10, 8) ;

В этом примере, если положительный фронт clock возникает, когда сброс и очистка находятся в низком уровне, путь модуля простирается от clock до out, используя задержку нарастания 10 и задержку спада 8.

Пример 2 — В следующем примере показаны 2 чувствительных к фронтам объявления пути, каждое из которых имеет уникальное ребро:
...
Копировать
specify
    ( posedge clk => ( q[0] : data ) ) = (10, 5);
    ( negedge clk => ( q[0] : data ) ) = (20, 12);
endspecify
Пример 3 — В следующем примере показаны 2 объявления путей чувствительных к фронтам, каждое из которых имеет уникальное условие:
...
Копировать
specify
    if (reset)
        ( posedge clk => ( q[0] : data ) ) = (15, 8);
    if (!reset && cntrl)
        ( posedge clk => ( q[0] : data ) ) = (6, 2);
endspecify
Пример 4 — Два объявления пути, зависящие от состояния, показанные ниже, являются неправильными, потому что, хотя они имеют разные условия, пункты назначения указаны по-разному: первый пункт назначения является частичной выборкой, второй — битовой выборкой.
...
Копировать
specify
    if (reset)
        (posedge clk => (q[3:0]:data)) = (10,5);
    if (!reset)
        (posedge clk => (q[0]:data)) = (15,8);
endspecif

14.2.4.4 Условие ifnone

Ключевое слово ifnone используется для указания задержки пути, зависящего от состояния, по умолчанию, когда все остальные условия для пути ложны. Условие ifnone должно указывать те же источник и пункт назначения пути модуля, что и зависимые от состояния пути модуля. Следующие правила применяются к модульным путям, указанным с условием ifnone:

Например:

Пример 1 Ниже приведены допустимые комбинации путей, зависящие от состояния:
...
Копировать
if (C1) (IN => OUT) = (1,1);
ifnone (IN => OUT) = (2,2);

        // операция добавления
if (opcode == 2'b00) (i1,i2 *> o1) = (25.0, 25.0);
        // сквозная операция i1
if (opcode == 2'b01) (i1 => o1) = (5.6, 8.0);
        // сквозная операция i2
if (opcode == 2'b10) (i2 => o1) = (5.6, 8.0);
        // для все других операция
ifnone (i2 => o1) = (15.0, 15.0);

(posedge CLK => (Q +: D)) = (1,1);
ifnone (CLK => Q) = (2,2);
Пример 2 — Следующая комбинация описания пути модуля является неправильной, поскольку она объединяет зависимый от состояния путь, использующий условие ifnone, и безусловный путь для того же пути модуля:
...
Копировать
if (a) (b => out) = (2,2);
if (b) (a => out) = (2,2);
ifnone (a => out) = (1,1);
(a => out) = (1,1)

14.2.5 Полное и параллельное подключения путей

Оператор *> используется для установления полного соединения между источником и получателем. При полном соединении каждый бит источника должен соединяться с каждым битом места назначения. Источник пути модуля не обязательно должен иметь то же количество битов, что и место назначения пути модуля.

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

Оператор => используется для установления параллельного соединения между источником и пунктом назначения. В параллельном соединении каждый бит в источнике должен соединяться с одним соответствующим битом в пункте назначения. Параллельные пути модуля могут быть созданы только между источниками и пунктами назначения, которые содержат одинаковое количество битов.

Параллельные соединения являются более ограничительными, чем полные соединения. Они соединяют только один источник с одним пунктом назначения, где каждый сигнал содержит одинаковое количество битов. Поэтому параллельное соединение может использоваться только для описания пути по модулю между двумя векторами одинакового размера. Поскольку скаляры имеют ширину 1 бит, для установки межбитовых соединений между двумя скалярами можно использовать *> или =>.

Например:

Пример 1Рисунок 14-2 иллюстрирует, чем параллельное соединение отличается от полного соединения между двумя 4-битными векторами.

Рисунок 14-2 иллюстрирует, чем параллельное соединение отличается от полного соединения между двумя 4-битными векторами Verilog HDL
Рисунок 14.2 — Разница между параллельным и полным соединительными путями
Пример 2 — В следующем примере показаны пути модулей для мультиплексора 2:1 с двумя 8-разрядными входами и одним 8-разрядным выходом:
...
Копировать
module mux8 (in1, in2, s, q) ;
    output [7:0] q;
    input [7:0] in1, in2;
    input s;

    // функциональное описание опущено...
    specify
        (in1 => q) = (3, 4) ;
        (in2 => q) = (2, 3) ;
        (s *> q) = 1;
    endspecify
endmodul

Путь модуля от s до q использует полное соединение (*>), потому что он соединяет скалярный источник — 1-битную линию выбора — с векторным получателем — 8-битной выходной шиной. Модульные пути от обеих входных линий in1 и in2 до q используют параллельное соединение (=>), поскольку устанавливают параллельные соединения между двумя 8-битными шинами.

14.2.6 Объявление нескольких путей к модулю в одном операторе

Несколько модульных путей могут быть описаны в одном операторе с помощью символа *> для соединения списка источников, разделенных запятыми, со списком пунктов назначения, разделенных запятыми. При описании нескольких путей по модулю в одном операторе списки источников и пунктов назначения могут содержать смесь скаляров и векторов любого размера.

Соединение в объявлении пути к нескольким модулям всегда является полным соединением. Например:
...
Копировать
(a, b, c *> q1, q2) = 10;
эквивалентна следующим шести индивидуальным назначениям путей модуля:
...
Копировать
(a *> q1) = 10 ;
(b *> q1) = 10 ;
(c *> q1) = 10 ;
(a *> q2) = 10 ;
(b *> q2) = 10 ;
(c *> q2) = 10 ;

14.2.7 Полярность пути модуля

Полярность пути модуля — это произвольная спецификация, указывающая, инвертируется ли направление перехода сигнала при его распространении от входа к выходу. Это произвольное описание полярности не влияет на фактическое распространение данных или событий через модель. То, как нарастание(восходящий фронт, от 0 к 1) или спад(спадающий фронт, от 1 к 0) сигнала в источнике распространяется к месту назначения, зависит от внутренней логики модуля.

Пути модулей могут задавать любую из трех полярностей:

14.2.7.1 Неизвестная полярность

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

Путь модуля, указанный либо как полное соединение, либо как параллельное соединение, но без оператора полярности + или -, должен рассматриваться как путь модуля с неизвестной полярностью.

Например:
...
Копировать
// Неизвестная полярность
(In1 => q) = In_to_q ;
(s *> q) = s_to_q ;

14.2.7.2 Положительная полярность

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

Путь модуля с положительной полярностью задается префиксом оператора полярности + к => или *>. Например:
...
Копировать
// Положительная полярность
(In1 +=> q) = In_to_q ;
(s +*> q) = s_to_q ;

14.2.7.3 Отрицательная полярность

Для модульных путей с отрицательной полярностью любой переход в источнике может вызвать противоположный переход в пункте назначения, как показано ниже:

Путь модуля с отрицательной полярностью задается префиксом оператора полярности — к => или *>. Например:
...
Копировать
// Отрицательная полярность
(In1 -=> q) = In_to_q ;
(s -*> q) = s_to_q ;

14.3 Назначение задержек для пути модулей

Задержки, возникающие на выходах модуля, где заканчиваются пути, должны быть заданы путем присвоения значений задержки описаниям путей модуля. Синтаксис для объявления значений задержек показан в Синтаксисе 14-6.

...
Копировать
path_delay_value ::=
    list_of_path_delay_expressions
    | ( list_of_path_delay_expressions )
list_of_path_delay_expressions ::=
    t_path_delay_expression
    | trise_path_delay_expression , tfall_path_delay_expression
    | trise_path_delay_expression , tfall_path_delay_expression , tz_path_delay_expression
    | t01_path_delay_expression , t10_path_delay_expression , t0z_path_delay_expression ,
    tz1_path_delay_expression , t1z_path_delay_expression , tz0_path_delay_expression
    | t01_path_delay_expression , t10_path_delay_expression , t0z_path_delay_expression ,
    tz1_path_delay_expression , t1z_path_delay_expression , tz0_path_delay_expression ,
    t0x_path_delay_expression , tx1_path_delay_expression , t1x_path_delay_expression ,
    tx0_path_delay_expression , txz_path_delay_expression , tzx_path_delay_expression
t_path_delay_expression ::=
    path_delay_expression
Синтаксис 14-6 Синтаксис для значения задержки пути

В объявлении задержки пути модуля описание пути модуля (см. 14.2) указывается в левой части, а одно или несколько значений задержки — в правой. Значения задержки могут быть дополнительно заключены в пару круглых скобок. Для пути модуля может быть назначено одно, два, три, шесть или двенадцать значений задержки, как описано в п. 14.3.1. Значения задержки должны быть константными выражениями, содержащими литералы или specparams, и может быть выражение задержки вида min:typ:max.

Например:
...
Копировать
specify
        // Specify параметры
    specparam tRise_clk_q = 45:150:270, tFall_clk_q=60:200:350;
    specparam tRise_Control = 35:40:45, tFall_control=40:50:65;
        // назначение путям модуля
    (clk => q) = (tRise_clk_q, tFall_clk_q);
    (clr, pre *> q) = (tRise_control, tFall_control);
endspecify

В приведенном примере параметры specify, объявленные после ключевого слова specparam, задают значения задержек пути модуля. Назначения путей модуля присваивают эти задержки путям модуля.

14.3.1 Указание задержек перехода для путях модулей

Каждое выражение задержки пути может быть одним значением, представляющим типичную задержку, или разделенным двоеточием списком из трех значений, представляющих минимальную, типичную и максимальную задержку в таком порядке. Если выражение задержки пути приводит к отрицательному значению, оно должно рассматриваться как ноль. В таблице 14-2 описано, как различные значения задержки пути должны быть связаны с различными переходами. Имена выражений задержки пути соответствуют именам, используемым в синтаксисе 14-6.

Таблица 14-2-Связывание выражений задержки пути с переходами
Переходы/Количество заданных выражений задержки пути123612
0 -> 1ttrisetriset01t01
1 -> 0ttfalltfallt10t10
0 -> zttrisetzt0zt0z
z -> 1ttrisetrisetz1tz1
1 -> zttfalltzt1zt1z
z -> 0ttfalltfalltz0tz0
0 -> x****t0x
x -> 1****tx1
1 -> x****t1x
x -> 0****tx0
x -> z****txz
z -> x****tzx

* См. 14.3.2.

Например:
...
Копировать
// одно выражение определяет все переходы
(C => Q) = 20;
(C => Q) = 10:14:20;

// два выражения определяют задержки нарастания и спада
specparam tPLH1 = 12, tPHL1 = 25;
specparam tPLH2 = 12:16:22, tPHL2 = 16:22:25;
(C => Q) = ( tPLH1, tPHL1 ) ;
(C => Q) = ( tPLH2, tPHL2 ) ;

// три выражения определяют задержки переходов нарастания, спада и z
specparam tPLH1 = 12, tPHL1 = 22, tPz1 = 34;
specparam tPLH2 = 12:14:30, tPHL2 = 16:22:40, tPz2 = 22:30:34;
(C => Q) = (tPLH1, tPHL1, tPz1);
(C => Q) = (tPLH2, tPHL2, tPz2);

// шесть выражений определяют переходы к/от 0, 1 и z
specparam t01 = 12, t10 = 16, t0z = 13,
tz1 = 10, t1z = 14, tz0 = 34 ;
(C => Q) = ( t01, t10, t0z, tz1, t1z, tz0) ;
specparam T01 = 12:14:24, T10 = 16:18:20, T0z = 13:16:30 ;
specparam Tz1 = 10:12:16, T1z = 14:23:36, Tz0 = 15:19:34 ;
(C => Q) = ( T01, T10, T0z, Tz1, T1z, Tz0) ;

// двенадцать выражений указывают все задержки переходов в явном виде
specparam t01=10, t10=12, t0z=14, tz1=15, t1z=29, tz0=36,
t0x=14, tx1=15, t1x=15, tx0=14, txz=20, tzx=30 ;
(C => Q) = (t01, t10, t0z, tz1, t1z, tz0, t0x, tx1, t1x, tx0, txz, tzx) ;

14.3.2 Указание задержек перехода x

Если задержки перехода в x не указаны явно, то расчет значений задержек для перехода в x основывается на следующих двух пессимистических правилах:

В таблице 14-3 представлен общий алгоритм расчета значений задержки для x-переходов вместе с конкретными примерами. В таблице представлены следующие две группы x-переходов:

1) Переход из известного состояния s в x: s -> x

2) Переход из x в известное состояние s: x -> s

Таблица 14-3 Расчет задержек для x-переходов
X переходЗначение задержки
Общий алгоритм
s -> xминимум (s -> другие известные сигналы)
x -> sмаксимум (другие известные сигналы -> s)
Конкретные переходы
0 -> xминимум (0 -> z задержка, 0 -> 1 задержка)
1 -> xминимум (1 -> z задержка, 1 -> 0 задержка)
z -> xминимум (z -> 1 задержка, z -> 0 задержка)
x -> 0максимум (z -> 0 задержка, 1 -> 0 задержка)
x -> 1максимум (z -> 1 задержка, 0 -> 1 задержка)
x -> zмаксимум (1 -> задержка z, 0 -> задержка z)
Использование: (C => Q) = (5, 12, 17, 10, 6, 22) ;
0 -> xминимум (17, 5) = 5
1 -> xминимум (6, 12) = 6
z -> xминимум (10, 22) = 10
x -> 0максимум (22, 12) = 22
x -> 1максимум (10, 5) = 10
x -> zмаксимум (6, 17) = 17

14.3.3 Выбор задержки

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

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

После определения активных уточняющих путей необходимо выбрать задержку среди них. Это делается путем сравнения правильной задержки для конкретного запланированного перехода из каждого specify пути и выбора наименьшей.

Например:

Пример 1
...
Копировать
(A => Y) = (6, 9);
(B => Y) = (5, 11);

Для перехода Y от 0 к 1, если A перешел позже, чем B, будет выбрана задержка 6. Но если B перешел более позже, чем A, то будет выбрана задержка 5. А если при последнем переходе A и B сделали это одновременно, то будет выбрана наименьшая из двух задержек нарастания, то есть задержка нарастания от B, равная 5. Задержка спада от A, равная 9, будет выбрана, если Y вместо этого перейдет от 1 к 0.

Пример 2
...
Копировать
if (MODE < 5) (A => Y) = (5, 9);
if (MODE < 4) (A => Y) = (4, 8);
if (MODE < 3) (A => Y) = (6, 5);
if (MODE < 2) (A => Y) = (3, 2);
if (MODE < 1) (A => Y) = (7, 7);

В зависимости от значения MODE могут быть активны от нуля до пяти из этих specify путей. Например, когда MODE равен 2, активны первые три задающих пути. Для перехода по нарастанию будет выбрана задержка 4, так как это наименьшая задержка нарастания среди первых трех. Переход на спад выберет задержку 5, так как это наименьшая задержка спада среди первых трех.

14.4 Смешивание задержек пути модуля и распределенных задержек

Если модуль содержит задержки на пути модуля и распределенные задержки (задержки на примитивных экземплярах внутри модуля), то для каждого пути используется большая из двух задержек.

Например:

Пример 1Рисунок 14-3 иллюстрирует простую схему, смоделированную с помощью комбинации распределенных задержек и задержек пути (показан только путь от входа D до выхода Q). Здесь задержка на пути модуля от входа D до выхода Q равна 22, а сумма распределенных задержек равна 0 + 1 = 1. Поэтому переход на Q, вызванный переходом на D, произойдет через 22 единицы времени после перехода на D.

Рисунок 14-3 иллюстрирует простую схему Verilog HDL, смоделированную с помощью комбинации распределенных задержек и задержек пути (показан только путь от входа D до выхода Q)
Рисунок 14-3 Задержки на пути к модулю больше, чем распределенные задержки

Пример 2 На рисунке 14-4 задержка на пути модуля от D до Q равна 22, но распределенные задержки вдоль этого пути модуля теперь составляют 10 + 20 = 30. Поэтому событие на Q, вызванное событием на D, произойдет через 30 единиц времени после события на D.

На рисунке 14-4 задержка на пути модуля от D до Q равна 22, но распределенные задержки вдоль этого пути модуля теперь составляют 10 + 20 = 30. Поэтому событие на Q, вызванное событием на D, произойдет через 30 единиц времени после события на D
Рисунок 14-4 Задержки на пути к модулю меньше, чем распределенные задержки

14.5 Управление проводной логикой

Выходные сети пути модуля не должны иметь более одного драйвера в пределах модуля. Поэтому проводная логика на выходах тракта модуля не допускается.

На рисунке 14-5 показано нарушение этого правила проводного вывода и метод, позволяющий избежать нарушения правила.

На рисунке 14-5 показано нарушение этого правила проводного вывода и метод, позволяющий избежать нарушения правила Verilog HDL
Рисунок 14-5 Законные и незаконные пути модулей

На рисунке 14-5 (a) любой путь модуля к S является неправильным, потому что конечный пункт пути имеет два источника.

Предполагая, что сигнал S на рисунке 14-5 (a) является проводным, это ограничение можно обойти, заменив проводную логику на стробируемую логику, чтобы создать один источник на выходе. На рисунке 14-5 (b) показано, как добавление третьего вентиля. Заштрихованный вентиль — решает проблему для модуля на рисунке 14-5 (a).

Пример на рисунке 14-6 также является неправильным. В этом примере, когда выходы Q и R соединены вместе, создается ситуация, когда оба пути имеют несколько источников из одного модуля.

Пример на рисунке 14-6 также является неправильным. В этом примере, когда выходы Q и R соединены вместе, создается ситуация, когда оба пути имеют несколько источников из одного модуля
Рисунок 14-6 Пути модулей расставлены неправильно

Хотя несколько выходных источников к месту назначения пути запрещены внутри одного модуля, они разрешены вне модуля. Пример на рисунке 14-7 является законным, потому что Q и R имеют только по одному источнику в пределах модуля, в котором указаны пути модуля.

Пример на рисунке 14-7 является законным, потому что Q и R имеют только по одному источнику в пределах модуля, в котором указаны пути модуля
Рисунок 14-7-Пути к законному модулю

14.6 Детальное управление поведением импульсной фильтрации. Пределы ошибки и отклонения

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

Диапазоны ширины импульса определяют, как обрабатывать импульс, поданный на выход модульного тракта. Они следующие:

2 предельных значения импульсов определяют диапазоны ширины импульсов, связанных с задержкой перехода каждого пути модуля. Предельные значения импульсов называются пределом ошибки и пределом отклонения. Предел ошибки всегда должен быть не меньше предела отклонения. Импульсы, превышающие или равные пределу ошибки, проходят без фильтрации. Импульсы меньше предела ошибки, но больше или равны пределу отклонения, фильтруются до X. Импульсы меньше предела отклонения отклоняются, и импульс не появляется. По умолчанию и предел ошибки, и предел отклонения установлены равными задержке. Эти значения по умолчанию обеспечивают полное поведение инерционного импульса, отбрасывая все импульсы, меньшие, чем задержка.

На рисунке 14-8 задержка нарастания от входа A до выхода Y равна 7, а задержка спада — 9. По умолчанию предел ошибки и предел отклонения для задержки нарастания равны 7. Предел ошибки и предел отклонения для задержки спада оба равны 9. Пределы импульса, связанные с задержкой, формирующей задний фронт импульса, определяют, следует ли фильтровать импульс и каким образом. Форма волны Y’ показывает форму волны, полученную в результате отсутствия фильтрации импульса. Ширина импульса равна 2, что меньше предела отбраковки для задержки нарастания 7. Поэтому импульс фильтруется, как показано на форме волны Y.

На рисунке 14-8 задержка нарастания от входа A до выхода Y равна 7, а задержка спада - 9
Рисунок 14-8 Пример импульсной фильтрации

Существует три способа изменить пределы импульсов по сравнению с их значениями по умолчанию. Во-первых, язык Verilog предоставляет параметр PATHPULSE$ specparam для изменения пределов импульсов по сравнению с их значениями по умолчанию. Во-вторых, в опциях вызова можно указать проценты, применяемые ко всем задержкам пути модуля для формирования соответствующих пределов ошибок и пределов отклонения. В-третьих, аннотация SDF может индивидуально аннотировать предел ошибки и предел отклонения для каждой задержки перехода по пути модуля.

14.6.1 Specify блочного управления предельными значениями импульсов

Предельные значения импульсов могут быть заданы из блока specify с помощью параметра PATHPULSE$ specparam. Синтаксис для использования PATHPULSE$ для задания предельных значений отклонения и ошибки приведен в Синтаксисе 14-7.

...
Копировать
pulse_control_specparam ::=
    PATHPULSE$ = ( reject_limit_value [ , error_limit_value ] )
    | PATHPULSE$specify_input_terminal_descriptor$specify_output_terminal_descriptor
      = ( reject_limit_value [ , error_limit_value ] )
error_limit_value ::=
    limit_value
reject_limit_value ::=
    limit_value
limit_value ::=
    constant_mintypmax_expression
Синтаксис 14-7-Синтаксис для управления импульсами PATHPULSE$

Если указано только значение предела ошибки, оно должно применяться как к пределу отклонения, так и к пределу ошибки.

Предел отклонения и ошибки могут быть указаны для конкретного пути модуля. Если путь модуля не указан, предел отказа и ошибки применяются ко всем путям модуля, определенным в модуле. Если оба параметра PATHPULSE$, специфичные для пути, и неспецифичный параметр PATHPULSE$ появляются в одном и том же модуле, то для указанных путей приоритет отдается параметрам, специфичным для пути.

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

Если в объявлении пути модуля объявлено несколько путей, параметр PATHPULSE$ должен быть указан только для первого входного порта пути и первого выходного порта пути. Указанные предел отказа и предел ошибки должны применяться ко всем остальным путям в объявлении нескольких путей. Параметр PATHPULSE$, указывающий что-либо, кроме входного и выходного портов первого пути, игнорируется.

Например:

В следующем примере путь (clk=>q) получает предел отклонения 2 и предел ошибки 9, как определено первой декларацией PATHPULSE$. Пути (clr*>q) и (pre*>q) получают предел отклонения 0 и предел ошибки 4, как определено второй декларацией PATHPULSE$. Путь (data=>q) не определен явно ни в одном из объявлений PATHPULSE$. Поэтому он получает предел отказа и предел ошибки 3, как определено последним объявлением PATHPULSE$.
...
Копировать
specify
    (clk => q) = 12;
    (data => q) = 10;
    (clr, pre *> q) = 4;

    specparam
        PATHPULSE$clk$q = (2,9),
        PATHPULSE$clr$q = (0,4),
        PATHPULSE$ = 3;
endspecify

14.6.2 Глобальное управление предельными значениями импульсов

Два параметра вызова могут задавать проценты, применяемые глобально ко всем задержкам перехода пути модуля. Опция вызова error limit задает процент от каждой задержки перехода пути модуля, используемый для предельного значения ошибки. Опция вызова reject limit задает процент от каждой задержки перехода пути модуля, используемый для предельного значения отказа. Процентные значения должны быть целым числом от 0 до 100.

Значения по умолчанию для опций вызова пределов отклонения и ошибки равны 100%. Если ни одна из опций не присутствует, то 100% задержки перехода каждого модуля используется в качестве пределов отклонения и ошибки.

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

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

14.6.3 SDF аннотация предельных значений импульсов

Аннотация SDF может быть использована для указания предельных значений импульсов задержек перехода между путями модуля. Более подробно это описано в пункте 16.

При наличии PATHPULSE$, глобальных опций вызова пределов импульса и аннотации SDF значений пределов импульса, значения аннотации SDF имеют приоритет.

14.6.4 Подробные возможности управления импульсами

Стиль поведения фильтрации импульсов по умолчанию имеет два недостатка. Во-первых, фильтрация импульсов до состояния X может быть недостаточно пессимистичной, а длительность состояния X слишком мала, чтобы быть полезной. Во-вторых, неравные задержки могут привести к отклонению импульса, когда задний фронт предшествует переднему фронту, не оставляя никаких признаков того, что импульс был отклонен. В этом подпункте представлены более подробные возможности управления импульсами.

14.6.4.1 Фильтрация импульсов по событию(on-event) в сравнении с фильтрацией по обнаружению(on-detect)

Когда выходной импульс должен быть отфильтрован на X, больший пессимизм может быть выражен, если выход тракта модуля переходит сразу на X (on-detect), а не в уже запланированное время перехода по переднему фронту импульса (on-event).

По умолчанию используется метод фильтрации импульсов по событию X. Когда выходной импульс должен быть отфильтрован по X, передний фронт импульса становится переходом к X, а задний фронт становится переходом от X. Время перехода фронтов не изменяется.

Как и метод on-event, метод фильтрации импульсов по обнаружению изменяет передний фронт импульса на переход к X и задний фронт на переход от X, но время переднего фронта изменяется таким образом, что он возникает сразу после обнаружения импульса.

Рисунок 14-9 иллюстрирует это поведение на примере простого буфера с асимметричным временем нарастания/спада, где пределы отклонения и ошибки равны 0. Показана форма выходного сигнала для подходов «по обнаружению» и «по событию».

Рисунок 14-9 иллюстрирует это поведение на примере простого буфера с асимметричным временем нарастания/спада, где пределы отклонения и ошибки равны 0
Рисунок 14-9 Обнаружение в сравнении с событием

Поведение при обнаружении или при событии может быть выбрано двумя различными способами. Во-первых, один из них может быть выбран глобально для всех выходов тракта модуля с помощью опции вызова on-detect или on-event. Во-вторых, один из вариантов может быть выбран локально с помощью объявления стиля импульса блока specify.

Синтаксис объявления pulsestyle показан в Синтаксисе 14-8.

...
Копировать
pulsestyle_declaration ::=
    pulsestyle_onevent list_of_path_outputs ;
    | pulsestyle_ondetect list_of_path_outputs ;
Синтаксис 14-8 Синтаксис для объявления стиля импульса(pulsestyle)

Если вывод пути модуля появляется в объявлении стиля импульса после того, как он уже появился в объявлении пути модуля, это ошибка.

Опции вызова pulsestyle имеют приоритет над объявлениями блоков specify pulsestyle.

14.6.4.2 Обнаружение отрицательного импульса

Когда задержки на выходе тракта модуля неравны, возможно, что задний фронт импульса будет запланирован на время раньше, чем время планирования переднего фронта. Это приведет к импульсу с отрицательной шириной. При нормальной работе, если расписание для заднего фронта импульса раньше, чем расписание для переднего фронта импульса, то передний фронт отменяется. Переход не происходит, если начальное и конечное состояния импульса одинаковы, не оставляя никаких признаков того, что расписание когда-либо существовало.

Отрицательные импульсы могут быть обозначены состоянием X с помощью стиля поведения showcancelled. Когда задний фронт импульса должен быть запланирован перед передним фронтом, этот стиль заставляет передний фронт быть запланированным на X, а задний фронт — на X. При стиле импульса on-event расписание на X заменяет расписание переднего фронта. При стиле импульса по обнаружению расписание на X составляется сразу после обнаружения отрицательного импульса.

Поведение showcancelled может быть включено двумя различными способами. Во-первых, оно может быть включено глобально для всех выходов путей модуля с помощью опций showcancelled и noshowcancelled invocation. Во-вторых, оно может быть включено локально с помощью объявлений блока specify showcancelled.

Синтаксис для деклараций showcancelled показан в Синтаксисе 14-9.

...
Копировать
showcancelled_declaration ::=
    showcancelled list_of_path_outputs ;
    | noshowcancelled list_of_path_outputs ;
Синтаксис 14-9 — Синтаксис для деклараций с показателями

Ошибкой является появление вывода пути модуля в объявлении showcancelled после того, как он уже появился в объявлении пути модуля. Опции вызовов showcancelled имеют приоритет над объявлениями блоков specify showcancelled.

Показное поведение проиллюстрировано на рисунке 14-10, где показан узкий импульс, поданный на вход буфера с неравными задержками нарастания/спада. Это приводит к тому, что задний фронт импульса планируется раньше, чем передний фронт. Передний фронт входного импульса планирует выходное событие на 6 единиц позже в точке, обозначенной A. Задний фронт импульса происходит на одну единицу времени позже, что планирует выходное событие на 4 единицы позже, обозначенное точкой B. Это второе расписание на выходе происходит на время, предшествующее уже существующему расписанию для переднего фронта выходного импульса.

Форма выходного сигнала показана для трех различных режимов работы. Первая осциллограмма показывает поведение по умолчанию с не включенной функцией showcancelled и стилем on-event по умолчанию. Вторая форма волны показывает поведение с showcancelled в сочетании со стилем on-event. Последняя форма волны показывает поведение с showcancelled в сочетании со стилем on-detect.

Показное поведение, где показан узкий импульс, поданный на вход буфера с неравными задержками нарастания/спада
Рисунок 14-10 Проблема отмены текущего события и ее исправление

Такая же ситуация может возникнуть при почти одновременном переходе на вход, который определяется как переход двух входов ближе друг к другу по времени, чем разница в их соответствующих задержках до выхода. На рисунке 14-11 показаны осциллограммы для двухвходового NAND-вентиля, где первоначально A имеет высокий уровень, а B — низкий. B переходит 0->1 в момент времени 10, вызывая график выхода 1->0 в момент времени 24. A переходит 1->0 в момент времени 12, вызывая график 0->1 в момент времени 22. Стрелками отмечены переходы на выходе, вызванные переходами на входах A и B.

Форма выходного сигнала показана для трех различных режимов работы. Первая осциллограмма показывает поведение по умолчанию с не включенной функцией showcancelled и стилем on-event по умолчанию. Вторая показывает поведение с showcancelled в сочетании со стилем on-event. Третий показывает поведение с showcancelled в сочетании с включением обнаружения.

На рисунке 14-11 показаны осциллограммы для двухвходового NAND-вентиля, где первоначально A имеет высокий уровень, а B - низкий
Рисунок 14-11 — NAND-вентиля с почти одновременным переключением входов, когда одно событие запланировано до другого, которое еще не наступило

Один из недостатков стиля on-event с показным поведением заключается в том, что по мере сближения фронтов выходных импульсов, длительность результирующего состояния X становится меньше. Рисунок 14-12 иллюстрирует, как стиль on-detect решает эту проблему.

Один из недостатков стиля on-event с показным поведением заключается в том, что по мере сближения фронтов выходных импульсов, длительность результирующего состояния X становится меньше. Рисунок иллюстрирует, как стиль on-detect решает эту проблему
Рисунок 14-12 — NAND-вентиля с почти одновременным переключением входа и выходным событием, запланированным на одно и то же время

Например:

Пример 1
...
Копировать
specify
    (a=>out)=(2,3);
    (b =>out)=(3,4);
endspecify

Поскольку в блоке specify нет объявлений pulsestyle или showcancelled, компилятор применяет режимы по умолчанию on-event и noshowcancelled.

Пример 2
...
Копировать
specify
    (a=>out)=(2,3);
    showcancelled out;
    (b =>out)=(3,4);
endspecify

Это объявление showcancelled является ошибочным, потому что оно следует за использованием out объявлении пути модуля. Противоречиво, если бы out имел поведение noshowcancelled от входа a, но showcancelled от входа b.

Пример 3 — Оба этих блока specify дают одинаковый результат. Выходы out и out_b объявлены как showcancelled и on-detect.
...
Копировать
specify
    showcancelled out;
    pulsestyle_ondetect out;
    (a => out) = (2,3);
    (b => out) = (4,5);
    showcancelled out_b;
    pulsestyle_ondetect out_b;
    (a => out_b) = (3,4);
    (b => out_b) = (5,6);
endspecify

specify
    showcancelled out,out_b;
    pulsestyle_ondetect out,out_b;
    (a => out) = (2,3);
    (b => out) = (4,5);
    (a => out_b) = (3,4);
    (b => out_b) = (5,6);
endspecify
Главная
Курсы
Вебинары
3. Лексические правила(Синтаксис) Verilog HDL
4. Типы данных Verilog HDL
5. Выражения и Операторы Verilog HDL
6. Назначения (Assignments) в Verilog HDL
7. Моделирование на уровне вентилей и переключателей в Verilog HDL
8. Примитивы, объявляемые пользователем (UDP) Verilog HDL
9. Процедурные назначения. Поведенческое моделирование в Verilog HDL.
9. If, case for, while и repeat Verilog HDL
9. Initial, always, задержки, блоки Verilog HDL
10. Задачи(task) и функции (function) в Verilog HDL
11. Семантика планирования. Стек (stack) в Verilog HDL
12. Модули(module). Переопределение параметров(defparam).
12. Порты. Иерархические имена в Verilog HDL
12. Generate блоки Verilog HDL
12. Иерархические имена Verilog HDL
13. Конфигурирование содержимого конструкции
13. Использование библиотек. Конфигурирование содержимого конструкции в Verilog HDL
14. Specify блоки в Verilog HDL
15. Setup, hold, setuphold и recovery в Verilog HDL
15. Skew, period, width и nochange Verilog HDL
15. Проверка синхронизации сигналов в Verilog HDL
16. Бэканнотирование с использованием стандартного формата задержки (SDF) в Verilog HDL
17. Системные задачи и функции
17.2 Файлы. Запись и чтение файлов Verilog
17. Задачи временной шкалы, управления, PLA и стохастического анализа Verilog
$time, $stime и $realtime Verilog
17.8. Функции преобразования Verilog
17.9. Функции распределения вероятностей Verilog
17.10. Ввод командной строки. 17.11. Математические функции
18. Дамп файлы изменения значений (VCD)
18. Формат файла VCD расширенные и четырьмя состояниями
19. Директивы компилятора Verilog HDL
20. Обзор интерфейса языка программирования (PLI) Verilog
28. Зашифрованные оболочки
Закрыть