VHDL: выход мультиплексора не следует за входами, когда дело доходит до тактовых сигналов
Я создаю архитектуру для управления шаговым двигателем, используя плату FPGA с контроллером L297. Поэтому, чтобы изменить скорость, я создал делитель тактовых частот, чтобы изменить тактовую частоту, принимаемую L297. Делитель часов работает просто отлично. Моя проблема в том, что я создал несколько выходов тактового сигнала, один из которых будет выбран с помощью кнопок на плате, поэтому, когда я подключаю эти сигналы к MUX, выходной сигнал не совсем правильный, когда дело доходит до входных сигналов тактового генератора, но он работает нормально с STD_LOGIC. Это код, который я использовал для MUX
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;
entity TEST_MUX is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
D : in STD_LOGIC;
E : in STD_LOGIC;
choice_select : in STD_LOGIC;
choice_valid : in STD_LOGIC;
choice_reset : in STD_LOGIC;
Choice : out STD_LOGIC);
end TEST_MUX;
architecture Behavioral of TEST_MUX is
signal count : integer := 0;
signal S_out : STD_LOGIC ;
begin
process ( choice_select , choice_valid, choice_reset,A,B,C,D,E)
begin
if (choice_reset = '0') THEN
count <=0;
S_out <= 'Z';
else
if (choice_select'event) and (choice_select ='1') THEN
count <= count + 1;
if (choice_valid = '1') THEN
case count is
when 1=> S_out<=A ;
when 2=> S_out<=B ;
when 3=> S_out<=C ;
when 4=> S_out<=D;
when 5=> S_out<=E ;
when others => S_out <= 'Z';
end case;
end if;
end if;
end if;
end process;
Choice<=S_out;
end Behavioral;
Вот правильный результат моделирования при вводе STD_LOGIC: введите описание изображения здесь
Здесь с вводом в качестве часов: введите описание изображения здесь Спасибо за помощь
1 ответ
Давайте посмотрим на содержание вашего процесса более внимательно:
process ( choice_select , choice_valid, choice_reset,A,B,C,D,E)
begin
if (choice_reset = '0') THEN
-- Reset things
else
if (choice_select'event) and (choice_select ='1') THEN
-- Counter and multiplexer here
end if;
end if;
end process;
Вы поместили много сигналов в свой список чувствительности, но единственными двумя сигналами, которые могут заставить ваш процесс что-либо делать, являются: choice_reset
а также choice_select
, Важно отметить, что блок, в котором находятся мультиплексор и счетчик, выполняется только при наличии event
(т.е. переход) в вашем choice_select
сигнал. Изменения в A
, B
и т. д., не включайте этот блок, и поэтому вы не увидите, что ваш мультиплексор делает что-либо, если только эти сигналы изменились.
Что вам нужно сделать, это переместить мультиплексор в другой, не разогнанный процесс:
process (count, choice_valid, choice_reset, A, B, C, D, E)
begin
if (choice_reset = '0') THEN
S_out <= 'Z';
elsif (choice_valid = '1') THEN
case count is
when 1 => S_out <=A;
when 2 => S_out <=B;
when 3 => S_out <=C;
when 4 => S_out <=D;
when 5 => S_out <=E;
when others => S_out <= 'Z';
end case;
end if;
end process;
Сказав все это, правильный способ реализовать тактовые мультиплексоры в большинстве устройств FPGA состоит в том, чтобы использовать любые выделенные тактовые мультиплексоры, которые может иметь устройство. Это гарантирует, что часы остаются в сетях маршрутизации часов, и могут даже обеспечить переключение между часами без сбоев. Возможно, вы сможете установить, что мультиплексор на основе LUT достаточен для вашего приложения, но это не должно быть исходным предположением.
Вы можете использовать функции rising_edge()
или же falling_edge()
как лучшая альтернатива 'event
стиль, используемый в вашем коде, т.е. if rising_edge(choice_select) then
,
Согласно комментарию, вы также не должны use ieee.std_logic_arith.all;
или же use ieee.std_logic_unsigned.all;
,