Я намерен объединить многие операторы if в один (на VHDL), например:
из этого рабочего фрагмента
if config = "0001" and counter = 40 then
res <= '1';
elsif config = "0010" and counter = 52 then
res <= '1';
else
res <= '0';
end if;
к этому неработающему фрагменту
if config = "0001" and counter = 40 or config = "0010" and counter = 52 then
res <= '1';
else
res <= '0';
end if;
Vivado говорит мне, что «есть проблема рядом с 'или'», но я ее не вижу.
Будет ли это лучше (надежнее) в аппаратной реализации?
Спасибо
Я пробовал, не работает
Операторы VHDL and
и or
имеют одинаковый порядок старшинства, поэтому без обязательных скобок, описанных пользователем 1155120, может быть легко неясно, означает ли A or B and C
A or (B and C)
или (A or B) and C
. Например, в Python оператор and
имеет более высокий приоритет, чем оператор or
, поэтому A or B and C
эквивалентен A or (B and C)
. Обязательные круглые скобки в VHDL делают язык менее подверженным ошибкам.
Вы должны поставить скобки следующим образом:
if (config = "0001" and counter = 40) or (config = "0010" and counter = 52) then
res <= '1';
else
res <= '0';
end if;
Что касается аппаратной реализации, я думаю, что два кода, скорее всего, будут содержать одни и те же компоненты, или разница будет незначительной.
Упс, это правда. Я пробовал это много раз, и это не сработало... Я не знаю, что случилось. В другой теме: если я положу это как функцию в пакет, будет ли это такая же аппаратная реализация? Спасибо
Аппаратная реализация будет (как правило) такой же, даже если вы обернете операцию в функцию в пакете. Пока схема, описываемая кодом VHDL, одна и та же, (как правило) не имеет значения, как эта схема описана. Инструменты (обычно) преобразовывают код VHDL во внутреннее описание схемы на ранней стадии реализации, что растворяет любую обертку функции или процесса.
Укажите Минимальный, полный и проверяемый пример, например:
library ieee;
use ieee.std_logic_1164.all;
entity unworking_snippet is
end entity;
architecture snippet of unworking_snippet is
signal config: bit_vector (3 downto 0) := "0001";
signal counter: integer range 0 to 52 := 40;
signal res: std_logic;
begin
process (config, counter)
begin
if config = "0001" and counter = 40 or config = "0010" and counter = 52 then
res <= '1';
else
res <= '0';
end if;
end process;
end architecture;
Что приведет к сообщению об ошибке, указывающему на ваш оператор if. Например, ghdl указывает на две ошибки в операторе if:
ghdl -a unworking_snippet.vhdl
unworking_snippet.vhdl:16:45:error: only one type of logical operators may be used to combine relation
unworking_snippet.vhdl:16:64:error: only one type of logical operators may be used to combine relation
ghdl:error: compilation error
где строка 16 содержит условие оператора if, символ 45 — это «о» в or
, а символ 64 — это «а» во втором and
.
Они жестко запрограммированы в синтаксическом анализе выражений VHDL, описанном в форме Баккуса Наура (BNF) в IEEE Std 1076-2008 9. Expressions, 9.1 General:
An expression is a formula that defines the computation of a value.
expression ::=
condition_operator primary
| logical_expression
logical_expression ::=
relation { and relation }
| relation { or relation }
| relation { xor relation
| relation [ nand relation ]
| relation [ nor relation ]
| relation { xnor relation }
relation ::=
shift_expression [ relational_operator shift_expression ]
shift_expression ::=
simple_expression [ shift_operator simple_expression ]
simple_expression ::=
[ sign ] term { adding_operator term }
term ::=
factor { multiplying_operator factor }
factor ::=
primary [ ** primary ]
| abs primary
| not primary
| logical_operator primary
primary ::=
name
| literal
| aggregate
| function_call
| qualified_expression
| type_conversion
| allocator
| ( expression )
где вы обнаружите, что при ручном анализе условия оператора if единственный способ иметь два разных логических оператора в качестве отношений в другом логическом операторе - это если первичный содержится в круглых скобках:
if (config = "0001" and counter = 40) or (config = "0010" and counter = 52) then
Путь через БНФ — это отношение => сдвиг_выражение => простое_выражение => термин => логический_оператор первичный, первичный => (выражение). Это происходит для обеих сторон оператора or
.
Подстановка обновленного условия оператора if позволяет MCVe успешно анализировать (компилировать).
В то время как лишние скобки часто вводятся теми, кто имеет опыт программирования, скобки требуются для разных логических операторов в одном и том же выражении (config = "0001" and counter = 40 or config = "0010" and counter = 52
в исходном «неработающем» фрагменте).
Поскольку это требование синтаксического анализа в BNF, не может быть никакой разницы между функциональностью моделирования и постсинтеза.
VHDL обрабатывает логические операторы с одинаковым приоритетом:
9.2 Операторы
9.2.1 Общие положения
The operators that may be used in expressions are defined as follows. Each operator belongs to a class of operators, all of which have the same precedence level; the classes of operators are listed in order of increasing precedence.
...
logical_operator ::= and | or | nand | nor | xor | xnorrelational_operator ::= = | /= | < | <= | > | >= | ?= | ?/= | ?< | ?<= | ?> | ?>=
...Operators of higher precedence are associated with their operands before operators of lower precedence. Where the language allows a sequence of operators, operators with the same precedence level are associated with their operands in textual order, from left to right. The precedence of an operator is fixed and cannot be changed by the user, but parentheses can be used to control the association of operators and operands.
In general, operands in an expression are evaluated before being associated with operators. For certain operations, however, the right-hand operand is evaluated if and only if the left-hand operand has a certain value. These operations are called short-circuit operations. The binary logical operations and, or, nand, and nor defined for operands of types BIT and BOOLEAN are all short-circuit operations; furthermore, these are the only short-circuit operations.
Здесь язык не позволяет использовать последовательность операторов из-за отсутствия приоритета между логическими операторами.
9.1 абзацы 3 и 4
Each primary has a value and a type. The only names allowed as primaries are attributes that yield values and names denoting objects or values. In the case of names denoting objects other than objects of file types or protected types, the value of the primary is the value of the object. In the case of names denoting either file objects or objects of protected types, the value of the primary is the entity denoted by the name.
The type of an expression depends only upon the types of its operands and on the operators applied; for an overloaded operand or operator, the determination of the operand type, or the identification of the overloaded operator, depends on the context (see 12.5). For each predefined operator, the operand and result types are given in the following subclause.
Следующий подпункт — 9.2, а тип выражений, полученных в результате операторов отношения, — тип BOOLEAN (9.2.3 Операторы отношения).
Ограничение BNF, требующее круглых скобок, позволяет избежать сложности повторной оценки всего выражения для определения его древовидной структуры без наложения приоритета логических операторов на алгебру Джорджа Буля, отмечая, что выражения также могут создавать значения произвольных типов. Нет никаких ограничений на размер или сложность выражений, а круглые скобки подразумевают поддеревья.
Ваш ответ очень полный, спасибо
Может быть, в скобках термины?