我正在创建一个使用L297控制器的FPGA板来驱动步进电机的体系结构。因此,为了改变速度,我创建了一个时钟分流器,以更改L297采集的时钟频率。时钟分隔符正常工作。我的问题是我创建了Mutiple Clock输出,其中将使用板上的按钮选择其中一个,因此当我将这些信号连接到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时正确的仿真结果:在此处输入图像描述
在这里,输入被强制为时钟:在此处输入图像描述谢谢您的帮助
让我们更仔细地看一下过程的内容:
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
。至关重要的是,仅当您的choice_select
信号中有event
(即过渡(时,仅执行多路复用器和计数器的块。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;
。