Сложные операторы if не могут быть смоделированы

Я намерен объединить многие операторы 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 говорит мне, что «есть проблема рядом с 'или'», но я ее не вижу.

Будет ли это лучше (надежнее) в аппаратной реализации?

Спасибо

Может быть, в скобках термины?

IronMan 29.07.2019 22:08

Я пробовал, не работает

vgl94 29.07.2019 22:21

Операторы VHDL and и or имеют одинаковый порядок старшинства, поэтому без обязательных скобок, описанных пользователем 1155120, может быть легко неясно, означает ли A or B and CA or (B and C) или (A or B) and C. Например, в Python оператор and имеет более высокий приоритет, чем оператор or, поэтому A or B and C эквивалентен A or (B and C). Обязательные круглые скобки в VHDL делают язык менее подверженным ошибкам.

Morten Zilmer 30.07.2019 12:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
154
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

if (config = "0001" and counter = 40) or (config = "0010" and counter = 52) then
    res <= '1';
else
    res <= '0';
end if;

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

Упс, это правда. Я пробовал это много раз, и это не сработало... Я не знаю, что случилось. В другой теме: если я положу это как функцию в пакет, будет ли это такая же аппаратная реализация? Спасибо

vgl94 30.07.2019 01:40

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

Morten Zilmer 30.07.2019 10:32
Ответ принят как подходящий

Укажите Минимальный, полный и проверяемый пример, например:

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 | xnor

relational_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, требующее круглых скобок, позволяет избежать сложности повторной оценки всего выражения для определения его древовидной структуры без наложения приоритета логических операторов на алгебру Джорджа Буля, отмечая, что выражения также могут создавать значения произвольных типов. Нет никаких ограничений на размер или сложность выражений, а круглые скобки подразумевают поддеревья.

Ваш ответ очень полный, спасибо

vgl94 30.07.2019 14:51

Другие вопросы по теме