- 12.3 Порты
- 12.3.1 Объявление порта
- 12.3.2 Список портов
- 12.3.3 Декларации портов
- 12.3.4 Список деклараций портов
- 12.3.5 Подключение портов экземпляра модуля по упорядоченному списку
- 12.3.6 Подключение портов экземпляра модуля по имени
- 12.3.7 Вещественные числа в портовых соединениях
- 12.3.8 Подключение разнородных портов
- 12.3.9 Правила подключения к порту
- 12.3.9.1 Правило 1
- 12.3.9.2 Правило 2
- 12.3.9.3 Правило 3
- 12.3.10 Типы сетей, возникающие в результате разнородных соединений портов
- 12.3.10.1 Правило разрешения типа сети
- 12.3.10.2 Таблица типов сетей
- 12.3.11 Подключение знаковых значений через порты
12.3 Порты
Порты обеспечивают средства взаимосвязи между описанием аппаратного обеспечения, состоящего из модулей и примитивов. Например, модуль A может объявляет экземпляр модуля B, используя соединения портов, соответствующие модулю A. Эти имена портов могут отличаться от имен внутренних сетей и переменных, указанных в определении модуля B.
12.3.1 Объявление порта
Синтаксис для портов и списка портов приведен в Синтаксис 12-3.
list_of_ports ::=
( port { , port } )
list_of_port_declarations ::=
( port_declaration { , port_declaration } )
| ( )
port ::=
[ port_expression ]
| . port_identifier ( [ port_expression ] )
port_expression ::=
port_reference
| { port_reference { , port_reference } }
port_reference ::=
port_identifier [ [ constant_range_expression ] ]
port_declaration ::=
{attribute_instance} inout_declaration
| {attribute_instance} input_declaration
| {attribute_instance} output_declaration
12.3.2 Список портов
Ссылка на порт для каждого порта в списке портов в верхней части объявления каждого модуля может быть одной из следующих:
- Простой или расширенный идентификатор
- Битовая выборка вектора, объявленного в модуле
- Частичная выборка вектора, объявленного в модуле
- Конкатенация любого из вышеперечисленных вариантов
Выражение порта является необязательным, поскольку могут быть определены порты, которые не подключаются ни к чему внутреннему в модуле. После определения порта не должно быть другого определения порта с таким же именем.
Первый тип порта модуля, имеющий только выражение port_expression, является неявным портом. Второй тип — это явный порт. В нем явно указывается идентификатор port_identifier, используемый для соединения портов экземпляра модуля по имени (см. 12.3.6), и выражение port_expression, содержащее идентификаторы, объявленные внутри модуля, как описано в 12.3.3. Именованные соединения портов не должны использоваться для неявных портов, если только выражение port_expression не является простым идентификатором или экранированным идентификатором, который должен использоваться в качестве имени порта.
12.3.3 Декларации портов
Каждый port_identifier в выражении port_expression в списке портов для объявления модуля должен быть также объявлен в теле модуля как одно из следующих объявлений порта: input, output или inout. Это дополнение к любому другому объявлению типа данных для конкретного порта — например, reg или wire. Синтаксис объявления порта приведен в Синтаксисе 12-4.
inout_declaration ::=
inout [ net_type ] [ signed ] [ range ] list_of_port_identifiers
input_declaration ::=
input [ net_type ] [ signed ] [ range ] list_of_port_identifiers
output_declaration ::=
output [ net_type ] [ signed ] [ range ]
list_of_port_identifiers
| output reg [ signed ] [ range ]
list_of_variable_port_identifiers
| output output_variable_type
list_of_variable_port_identifiers
list_of_port_identifiers ::=
port_identifier { , port_identifier }
Если объявление порта включает тип сети или переменной, то порт считается полностью объявлены. Повторное объявление порта в объявлении переменной или типа данных сети является ошибкой. В связи с этим все остальные аспекты порта должны быть объявлены в таком объявлении порта, включая определения знака и диапазона, если это необходимо.
Если объявление порта не включает тип сети или переменной, то порт может быть снова объявлен в объявлении сети или переменной. Если сеть или переменная объявлена как вектор, то спецификация диапазона между двумя объявлениями порта должна быть идентичной. После того как имя использовано в объявлении порта, оно не должно быть повторно объявлено в другом объявлении порта или в объявлении типа данных.
Реализации могут ограничивать максимальное количество портов в определении модуля, но это ограничение должно быть не менее 256.
input aport; // Первая декларация
input aport; // Ошибка - множественное объявление, объявление порта
output aport; // Ошибка - множественное объявление, объявление порта
Атрибут signed может быть прикреплен либо к объявлению порта, либо к соответствующему объявлению сети или reg, либо к обоим. Если либо порт, либо wire/reg объявлены как знаковым, то и другой порт будет считаться знаковым.
Неявные сети считаются беззнаковыми. Сети, подключенные к портам без явного объявления сети, считаются беззнаковыми, если только порт не объявлен как знаковым.
module test(a,b,c,d,e,f,g,h);
input [7:0] a; // явного объявления нет - сеть беззнаковая
input [7:0] b;
input signed [7:0] c;
input signed [7:0] d; // без явного объявления сети - сеть знаковая
output [7:0] e; // без явного объявления - сеть беззнаковая
output [7:0] f;
output signed [7:0] g;
output signed [7:0] h; // явного объявления сети нет - сеть знаковая
wire signed [7:0] b; // порт b наследует атрибут signed от net decl.
wire [7:0] c; // сеть c наследует signed атрибут от порта
reg signed [7:0] f; // порт f наследует атрибут signed от reg decl.
reg [7:0] g; // reg g наследует signed атрибут от порта
endmodule
module complex_ports ({c,d}, .e(f));
// Сетки {c,d} получают первые биты порта.
// Имя 'f' объявлено внутри модуля.
// Имя 'e' определено вне модуля.
// Невозможно использовать соединения именованного порта первого порта.
module split_ports (a[7:4], a[3:0]);
// Первый порт - верхние 4 бита 'a'.
// Второй порт - младшие 4 бита 'a'.
// Невозможно использовать соединения с именованным портом, потому что
// порта part-select 'a'.
module same_port (.a(i), .b(i));
// Имя 'i' объявлено внутри модуля как порт inout.
// Имена 'a' и 'b' определены для портовых соединений.
module renamed_concat (.a({b,c}), f, .g(h[1]));
// Имена 'b', 'c', 'f', 'h' определены внутри модуля.
// Имена 'a', 'f', 'g' определены для портовых соединений.
// Можно использовать соединения с именованными портами.
module same_input (a,a);
input a; // Это правильно. Входы связаны вместе.
module mixed_direction (.p({a, e}));
input a; // p содержит как входные, так и выходные направления
output e;
12.3.4 Список деклараций портов
Для указания портов модуля может быть использован альтернативный синтаксис, минимизирующий дублирование данных. Каждый модуль должен быть объявлен либо полностью с использованием синтаксиса списка портов, как описано в п. 12.3.2, либо полностью с использованием list_of_port_declarations, как описано в данном подпункте.
Каждый объявленный порт предоставляет полную информацию о нем. Полностью описывается направление, ширинe, сеть или тип переменной порта, а также то, является ли порт знаковым или беззнаковым. Для объявлений ввода, вывода и двунаправленного в заголовке модуля используется тот же синтаксис, что и для объявления стиля списка портов, за исключением того, что list_of_port_declarations включается в заголовок модуля, а не отдельно (после символа ;, завершающего заголовок модуля).
Например:
module test (
input [7:0] a,
input signed [7:0] b, c, d, // // Несколько портов, которые совместно используют все
// атрибуты могут быть объявлены вместе.
output [7:0] e, // Каждый атрибут декларации
// должны быть в одном объявлении.
output reg signed [7:0] f, g,
output signed [7:0] h) ;
// Незаконно повторно объявлять любые порты из
// модуль в теле модуля.
endmodule
Объявление портов в модуле типа port_reference не должно выполняться с использованием стиля объявлений модулей list_of_port_declarations. Также порты, объявленные с использованием list_of_port_declarations, должны быть только простыми идентификаторами или экранированными идентификаторами. Они не должны быть битовыми, частичными или конкатенациями (как в примере complex_ports). Порты не могут быть разделены (как в примере split_ports). Они также не могут быть именованными портами (как в примере same_port).
Проекты могут свободно смешивать модули, объявленные с использованием каждого синтаксиса. Следовательно, реализации, желающие описанных выше особых случаев объявления портов, могут быть выполнены с использованием первого синтаксиса list_of_ports.
12.3.5 Подключение портов экземпляра модуля по упорядоченному списку
Одним из методов установления связи между выражениями портов, перечисленными в объявлении экземпляра модуля, и портами, объявленными в экземпляре модуле, является упорядоченный список. То есть выражения портов, перечисленные для экземпляра модуля, должны располагаться в том же порядке, что и порты, перечисленные в объявлении модуля.
Например:
Следующий пример иллюстрирует модуль верхнего уровня (topmod), который инстанцирует второй модуль (modB). Модуль modB имеет порты, которые соединены упорядоченным списком. Соединения выполняются следующим образом:
- Порт wa в определении modB подключается к битовой выборке v[0] в модуле topmod.
- Порт wb подключается к v[3].
- Порт c подключается к w.
- Порт d подключается к v[4].
module topmod;
wire [4:0] v;
wire a,b,c,w;
modB b1 (v[0], v[3], w, v[4]);
endmodule
module modB (wa, wb, c, d);
inout wa, wb;
input c, d;
tranif1 g1 (wa, wb, cinvert);
not #(2, 6) n1 (cinvert, int);
and #(6, 5) g2 (int, c, d);
endmodule
Во время моделирования экземпляра b1 modb сначала активируется вентиль and и g2 для получения значения на int. Это значение запускает вентиль not n1 для получения выхода на cinvert, который затем активирует вентиль tranif1 g1.
12.3.6 Подключение портов экземпляра модуля по имени
Второй способ соединения портов модулей заключается в явном связывании двух имен для каждой стороны соединения. Имя объявления порта из объявления модуля в выражение. Т.е. имя, используемое в объявлении модуля, за которым следует имя, используемое в экземпляре модуля. Это составное имя затем помещается в список соединений модуля. Имя порта должно быть именем, указанным в объявлении модуля. Имя порта не может быть битовой выборкой, частичной выборкой или конкатенацией портов. Если объявление порта модуля было неявным, то выражение port_expression должно быть простым или экранированным идентификатором, который будет использоваться в качестве имени порта. Если объявление порта в модуле было явным, то в качестве имени порта используется явное имя.
Выражение порта может быть любым допустимым выражением. Выражение port является необязательным, чтобы экземпляре модуля мог документировать существование порта, не подключая его к чему-либо. Круглые скобки обязательны.
Два типа соединений портов модуля не должны смешиваться. Соединения с портами конкретного экземпляра модуля должны быть все по порядку или все по имени.
Например:
ALPHA instance1 (.Out(topB),.In1(topA),.In2());
module topmod;
wire [4:0] v;
wire a,b,c,w;
modB b1 (.wb(v[3]),.wa(v[0]),.d(v[4]),.c(w));
endmodule
module modB(wa, wb, c, d);
inout wa, wb;
input c, d;
tranif1 g1(wa, wb, cinvert);
not #(6, 2) n1(cinvert, int);
and #(5, 6) g2(int, c, d);
endmodule
Поскольку эти соединения выполняются по имени, порядок их появления не имеет значения. Соединения портов нескольких экземпляров модуля не допускаются, например, следующий пример является незаконным:
module test;
a ia (.i (a), .i (b), // незаконное подключение входного порта дважды.
.o (c), .o (d), // незаконное подключение входного порта дважды.
.e (e), .e (f)); // незаконное подключение двунаправленного порта дважды.
endmodule
12.3.7 Вещественные числа в портовых соединениях
real тип данных не должен быть напрямую подключен к порту. Он должен быть подключен косвенно, как показано в следующем примере. Для передачи битовых шаблонов через порты модуля должны использоваться системные функции $realtobits и $bitstoreal. (Описание этих системных задач см. в разделе 17.8).
module driver (net_r);
output net_r;
real r;
wire [64:1] net_r = $realtobits(r);
endmodule
module receiver (net_r);
input net_r;
wire [64:1] net_r;
real r;
initial assign r = $bitstoreal(net_r);
endmodule
12.3.8 Подключение разнородных портов
Порт модуля можно рассматривать как обеспечивающий связь или соединение между двумя элементами (например, сетями, переменными, выражениями) — одним внутренним для экземпляра модуля и одним внешним для него.
Изучение правил соединения портов, описанных в разделе 12.3.9, покажет, что элемент, получающий значение через порт (внутренний элемент для входов, внешний элемент для выходов), должен быть выражением структурной сети. Элемент, передающий значение, может быть любым выражением.
Порт, который объявлен как вход (output), но используется как выход (input) или inout, может быть принудительно переведен в inout. Если он не принудительно приведен к inout, должно быть выдано предупреждение.
12.3.9 Правила подключения к порту
Правила 12.3.9.1—12.3.9.3 должны определять способ объявления портов модуля и способ их соединения.
12.3.9.1 Правило 1
Входной или выходной порт должен иметь тип net.
12.3.9.2 Правило 2
Каждое соединение порта должно быть непрерывным назначением от источника к получателю, где один подключенный элемент должен быть источником сигнала, а другой — получателем сигнала. Назначение должно быть непрерывным назначением от источника к стоку для входных или выходных портов. Для входных портов назначение представляет собой соединение транзисторов без уменьшения прочности. Получателям в назначении должны быть только сети или структурные выражения сетей.
Выражение структурной сети — это выражение порта, операнды которого могут быть следующими:
- Скалярная сеть
- Векторная сеть
- Константная битовая выборка векторной сети
- Частичная выборка векторной сети
- Конкатенация выражений структурной сети
Следующие внешние элементы не должны подключаться к выходным или входным портам модулей:
- Переменные
- Выражения, отличные от следующих:
- Скалярная сеть
- Векторная сеть
- Константная битовая выборка векторной сети
- Частичная выборка векторной сети
- Конкатенация выражений, перечисленных выше
12.3.9.3 Правило 3
Если сеть по обе стороны от порта имеет тип сети uwire, выдается предупреждение, если сети не объединены в одну сеть, как описано в п. 12.3.10.
12.3.10 Типы сетей, возникающие в результате разнородных соединений портов
Когда через порт модуля соединяются сети разных типов, сети с обеих сторон порта могут принимать один и тот же тип. Результирующий тип сети может быть определен, как показано в таблице 12-1. В таблице внешняя сеть означает сеть, объявленную в экземпляре модуля, а внутренняя сеть означает сеть, объявленную в модуле определение. Сеть, тип которой используется, называется доминирующей сетью. Сеть, тип которой изменяется, называется доминированной сетью. Допускается объединение доминирующей и доминированной сетей в одну сеть. Тип которой должен быть типом доминирующей сети. Полученная сеть называется моделируемой сетью, а недоминированная сеть называется свернутой сетью.
Моделируемая сеть должна принять задержку, указанную для доминирующей сети. Если доминирующая сеть имеет тип trireg, любое значение прочности, заданное для сети trireg, будет применяться к моделируемой сети.
Internal net/ External net | wire, tri | wand, triand | wor, trior | trireg | tri0 | tri1 | uwire | supply0 | supply1 |
---|---|---|---|---|---|---|---|---|---|
wire, tri | ext | ext | ext | ext | ext | ext | ext | ext | ext |
wand, triand | int | ext | ext warn | ext warn | ext warn | ext warn | ext warn | ext | ext |
wor, trior | int | ext warn | ext | ext warn | ext warn | ext warn | ext warn | ext | ext |
trireg | int | ext warn | ext warn | ext | ext | ext | ext warn | ext | ext |
tri0 | int | ext warn | ext warn | int | ext | ext warn | ext warn | ext | ext |
tri1 | int | ext warn | ext warn | int | ext warn | ext | ext warn | ext | ext |
uwire | int | int warn | int warn | int warn | int warn | int warn | ext | ext | ext |
supply0 | int | int | int | int | int | int | int | ext | ext warn |
supply1 | int | int | int | int | int | int | int | ext warn | ext |
КЛЮЧ:
ext = Используется тип внешней сети.
int = Используется тип внутренней сети.
warn = Выдается предупреждение.
Перевод Официального Стандарта Verilog HDL
12.3.10.1 Правило разрешения типа сети
Когда две сети, соединенные портом, имеют разный тип сети, результирующей единой сети может быть присвоен один из следующих типов:
- Тип доминирующей сети, если одна из двух сетей является доминирующей, или
- Тип сети, внешний по отношению к модулю
Если доминирующий тип сети не существует, используется внешний тип сети.
12.3.10.2 Таблица типов сетей
В таблице 12-1 показан тип сети, диктуемый правилом разрешения типа сети.
Моделируемая сеть должна принимать тип сети, указанный в таблице, и задержку, указанную для этой сети. Если выбранная имитируемая сеть является trireg, любое значение силы, указанное для сети trireg, применяется к имитируемой сети.
12.3.11 Подключение знаковых значений через порты
Атрибут знака не должен пересекать иерархию. Для того чтобы знаковый тип пересекал иерархию, ключевое слово signed должно использоваться в объявлении объекта на разных уровнях иерархии. Любое выражение на порте должно рассматриваться как любое другое выражение в присваивании. Они должны быть типизированы, определены по размеру, оценены, а полученное значение присвоено объекту на другой стороне порта по тем же правилам, что и назначение.