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/