5. Операторы присвоения по условию

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

  • Conditional signal assignment (присвоение сигналу значения по условию)
  • Selected signal assignment (присвоение сигналу значения по выбору)

Conditional signal assignment

Присвоение значения по условию аналогично оператору if-else в высокоуровневых языках программирования. Синтаксис выглядит следующим образом:

1 library ieee;
2 use ieee.std_logic_1164.all;
3 entity mux_mod is
4  port(
5   a_data : in std_logic_vector(3 downto 0);
6   b_data : in std_logic_vector(3 downto 0);
7   sel    : in std_logic;
8   q_data : out std_logic_vector(3 downto 0)
9  );
10 end entity;
11 architecture rtl of mux_mod is 
12 begin
13  q_data <= a_data when sel = '0' else b_data;
14 end rtl;

Запись в строке 13 является присвоением по условию: на выход q_data подаются значения со входа a_data только при условии нулевого значения входа sel, во всех других случаях на выход поступят значения со входа b_data. Как можно догадаться такое описание соответствует поведению схемы мультиплексора:


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

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

1 library ieee;
2 use ieee.std_logic_1164.all;
3 entity mux_mod2 is
4  port(
5   a_data : in std_logic_vector(3 downto 0);
6   b_data : in std_logic_vector(3 downto 0);
6   c_data : in std_logic_vector(3 downto 0);
7   sel0   : in std_logic;
7   sel1   : in std_logic;
8   q_data : out std_logic_vector(3 downto 0)
9  );
10 end entity;
11 architecture rtl of mux_mod is 
12   signal sels : std_logic_vector(1 downto 0);
13 begin
14  q_data <= a_data when sels = "00" else b_data
15                   when sels = "01" else c_data;
16  sels <= sel1 & sel0; -- операция конкатенации
17 end rtl;

Данное описание синтезируется в следующую схему:


Теперь на схеме видно, что выход q_data определяется сразу двумя мультиплексорами

!NB Обратите внимание: каскадирование происходит путем подключения выхода мультиплексора ко входу другого. Получается, что при различных комбинациях управляющих сигналов данные будут проходить разные по количеству элементов пути. Принято считать, что у сигнала a_data выше приоритет, отсюда и название этого вида мультиплексирования — с приоритетом.

Selected signal assignment

Присвоение значения по выбору аналогично оператору switch-case в высокоуровневых языках программирования. Синтаксис выглядит следующим образом:

1 library ieee;
2 use ieee.std_logic_1164.all;
3 entity mux_mod is
4  port(
5   a_data : in std_logic_vector(3 downto 0);
6   b_data : in std_logic_vector(3 downto 0);
7   sel    : in std_logic;
8   q_data : out std_logic_vector(3 downto 0)
9  );
10 end entity;
11 architecture rtl of mux_mod is 
12 begin
13  with sel select
14    q_data <= a_data when '0',
15              b_data when others;
16 end rtl;

Запись в строках  14-15 является присвоением в порт q_data по выбору sel. Результат компиляции будет аналогичным первому варианту в начале страницы.

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

1 library ieee;
2 use ieee.std_logic_1164.all;
3 entity mux_mod2 is
4  port(
5   a_data : in std_logic_vector(3 downto 0);
6   b_data : in std_logic_vector(3 downto 0);
6   c_data : in std_logic_vector(3 downto 0);
7   sel0   : in std_logic;
7   sel1   : in std_logic;
8   q_data : out std_logic_vector(3 downto 0)
9  );
10 end entity;
11 architecture rtl of mux_mod is 
12   signal sels : std_logic_vector(1 downto 0);
13 begin
14  with (sels) select
15     q_data  <= a_data when "00",
16 	          b_data when "01",
17                c_data when others;
18  sels <= sel1 & sel0; -- операция конкатенации
19 end rtl;

В таком описании схема уже не имеет приоритетов между состояниями селектора, поэтому данное описание синтезируется в следующую схему:



!NB Обратите внимание: теперь мультиплексоры уже не упакованы в "пачки", а сигнал управления подключен не сверху, а слева. Такой мультиплексор выбирает номер бита из входа DATA по порядковому номеру SEL.

Полезные ссылки:
Surf VHDL: concurrent conditional assignments https://surf-vhdl.com/vhdl-syntax-web-course-surf-vhdl/vhdl-concurrent-conditional-assignment/