VHDL:按钮去抖动(或不去抖动,视情况而定)
我已经阅读了其他帖子,但似乎无法修复我的。我不熟悉VHDL,所以我相信这是一个简单的修复程序 简言之,按钮没有去抖动。代码编译并生成位流程序。在测试台中,按钮按下工作,但输出LED不会改变。在电路板上,按下按钮会使随机发光二极管亮起(我猜是因为反弹)。根据示意图,输入通过去抖动器 有人能确定这个问题吗?任何其他提示和提示都将不胜感激:) 谢谢 EDIT1:增加了上升沿(clk)。 另外请注意,当我按下任一按钮时,按下该按钮时,所有LED都会亮起 按钮计数器.vhdVHDL:按钮去抖动(或不去抖动,视情况而定),vhdl,fpga,xilinx,vivado,debounce,Vhdl,Fpga,Xilinx,Vivado,Debounce,我已经阅读了其他帖子,但似乎无法修复我的。我不熟悉VHDL,所以我相信这是一个简单的修复程序 简言之,按钮没有去抖动。代码编译并生成位流程序。在测试台中,按钮按下工作,但输出LED不会改变。在电路板上,按下按钮会使随机发光二极管亮起(我猜是因为反弹)。根据示意图,输入通过去抖动器 有人能确定这个问题吗?任何其他提示和提示都将不胜感激:) 谢谢 EDIT1:增加了上升沿(clk)。 另外请注意,当我按下任一按钮时,按下该按钮时,所有LED都会亮起 按钮计数器.vhd library IEEE;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity button_counter is
port( clk : in std_logic;
btnU : in std_logic;
btnD : in std_logic;
led : out std_logic_vector (15 downto 0));
end button_counter;
architecture behavioral of button_counter is
component debouncer is
port( clk : in std_logic;
btn : in std_logic;
btn_clr : out std_logic);
end component;
signal btnU_clr : std_logic;
signal btnD_clr : std_logic;
begin
debouncer_btnU : debouncer port map (clk => clk, btn => btnU, btn_clr => btnU_clr);
debouncer_btnD : debouncer port map (clk => clk, btn => btnD, btn_clr => btnD_clr);
process(clk)
variable count : integer := 0;
begin
if (rising_edge(clk)) then
if(btnU_clr = '1') then count := count + 1;
elsif(btnD_clr = '1') then count := count - 1;
end if;
led <= std_logic_vector(to_unsigned(count, led'length));
end if;
end process;
end behavioral;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.NUMERIC_STD.ALL;
实体按钮_计数器为
端口(时钟:在标准逻辑中;
btnU:标准逻辑中;
btnD:标准逻辑中;
led:输出标准逻辑向量(15到0);
结束按钮计数器;
按钮计数器的结构是
分量去抖器
端口(时钟:在标准逻辑中;
btn:标准逻辑中;
btn_clr:输出标准逻辑);
端部元件;
信号btnU\U clr:标准逻辑;
信号btnD\U clr:标准逻辑;
开始
去Bouncer_btnU:去Bouncer端口映射(clk=>clk,btn=>btnU,btn_clr=>btnU_clr);
去Bouncer_btnD:去Bouncer端口映射(clk=>clk,btn=>btnD,btn_clr=>btnD_clr);
过程(clk)
变量计数:整数:=0;
开始
如果(上升沿(clk)),则
如果(btnU_clr='1'),则计数:=计数+1;
elsif(btnD_clr='1')则count:=count-1;
如果结束;
led您忘记了按钮计数器中的上升沿
process(clk)
variable count : integer := 0;
begin
if(btnU_clr = '1') then count := count + 1;
elsif(btnD_clr = '1') then count := count - 1;
end if;
led <= std_logic_vector(to_unsigned(count, led'length));
end process;
我不确定,但我认为工具链会对此产生一些警告。所以请检查一下
而且您的测试台不包含任何时钟生成过程,因此您不会有时钟信号。也许这会让你相信你的设计是可行的(或者你是否忘记了帖子中的时钟信号?在你的代码更新之后,还有几个问题:
测试台上没有生成时钟
测试台上的刺激(按钮按下)没有充分计时
去抖动器不会为单个时钟生成启用
为了便于设计验证的模拟,您的设计已修改为允许较慢的时钟(看起来您实际使用的是100 MHz时钟)。其思想是减少计算需求和显示波形存储
前两点在测试台中讨论:
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体按钮\u计数器\u tb为
结束实体按钮\u计数器\u tb;
按钮计数器tb的结构是
--注意:后缀_tb已被删除,反复键入很烦人
信号时钟:标准逻辑:='0';--已添加默认值“0”
信号btnU:std_逻辑;
信号btnD:std_逻辑;
信号led:标准逻辑矢量(15至0);
组件按钮计数器
泛型(--添加泛型
CLKP:时间:=10纳秒;
债务:时间:=6.5毫秒——去盎司时间支持不同的
); -- 机械按钮/开关
港口(
clk:标准逻辑中;
btnU:标准逻辑中;
btnD:标准逻辑中;
led:输出标准逻辑向量(15至0)
);
端部元件;
恒定CLKP:时间:=12.5 us;——添加的长度刚好足以显示debounce
固定负债:时间:=6.5毫秒;——补充
开始
时钟:--添加了时钟进程
过程
开始
等待CLKP/2;
clk 2秒然后--停止模拟
等待
如果结束;
结束过程;
受测试单元:
按钮计数器
通用映射(--添加了通用映射
CLKP=>CLKP,
债务=>债务
)
港口地图(
时钟=>clk,
btnU=>btnU,
btnD=>btnD,
发光二极管=>发光二极管
);
--刺激:
--过程
--开始
--btnU_tb这个问题已经得到了很好的回答,但我想强调一下同步和去抖动的不同技术
同步
对于同步,可以使用简单的缓冲器或链,避免为缓冲器或链中的每个阶段创建单独的信号/变量。通用常数可用于控制链的长度(至少2个):
signal sync_buffer:std_logic_vector(sync_buffer_MSB downto 0);--N位同步缓冲器。
...
同步缓冲区“0”);--N位同步缓冲器(最少2位)。
别名sync_输入:std_逻辑是sync_缓冲区(sync_缓冲区\u MSB);--同步输入是同步缓冲区的MSB。
恒定最大计数:自然:=去盎司周期/时钟周期;
信号计数器:自然范围0到最大计数:=0;--指定范围以减少合成的位数。
开始
断言同步\u位>=2报告“同步缓冲区中至少需要2位。”;
进程(时钟)
可变边_内部:标准_逻辑:='0';
可变上升_内部:标准_逻辑:='0';
变量fall_internal:std_逻辑:='0';
开始
如果上升沿(时钟),则
--同步异步输入。
--sync_缓冲区的MSB是同步输入。
sync\u buffer您的测试台似乎没有任何驱动clk
,这是故意的吗?是的,我可以确定问题。基于锁存器的计数器在启用时用作选通振荡器。至少有一个“位”被增量或减量反转。启用时会有一个反馈路径。有耽搁。工艺灵敏度列表不正确,模拟
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity button_counter_tb is
end button_counter_tb;
architecture behavioral of button_counter_tb is
signal clk_tb : std_logic;
signal btnU_tb : std_logic;
signal btnD_tb : std_logic;
signal led_tb : std_logic_vector (15 downto 0);
component button_counter
port(clk : in std_logic;
btnU : in std_logic;
btnD : in std_logic;
led : out std_logic_vector (15 downto 0));
end component;
begin
UUT: button_counter port map (clk => clk_tb, btnU => btnU_tb, btnD => btnD_tb, led => led_tb);
process
begin
btnU_tb <= '0';
btnD_tb <= '0';
wait for 100ns;
btnU_tb <= '1';
wait for 100ns;
btnU_tb <= '0';
wait for 100ns;
btnU_tb <= '1';
wait for 100ns;
btnD_tb <= '1';
wait for 100ns;
btnU_tb <= '0';
wait for 100ns;
btnD_tb <= '0';
end process;
end behavioral;
process(clk)
variable count : integer := 0;
begin
if(btnU_clr = '1') then count := count + 1;
elsif(btnD_clr = '1') then count := count - 1;
end if;
led <= std_logic_vector(to_unsigned(count, led'length));
end process;
process(clk)
variable count : integer := 0;
begin
if(rising_edge(clk)) then
...
end if;
end process;