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;,

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