Button 如何通过按下按钮正确增加显示屏各部分的照明速率

Button 如何通过按下按钮正确增加显示屏各部分的照明速率,button,vhdl,fpga,clock,xilinx,Button,Vhdl,Fpga,Clock,Xilinx,我正在用行为VHDL编程xilinx basys 3板。我正在照亮4x七段显示器的各个部分,使其看起来好像显示器有两个旋转的“轮子”。我的整个项目包括许多组件,如解码器、多路复用器、去抖动器、计数器、显示刷新率时钟分频器等。所有这些都已被我的教授清除。 我目前正在工作的组成部分,在一个250赫兹时钟和一个向上和向下的按钮。向上和向下按钮将允许增加映射到11个不同预分频值的计数器。这些值将相应地改变时钟分频器的最大步长 目前我的重置按钮工作。但是,“向上”和“向下”按钮只是暂停线段的旋转,而不是增

我正在用行为VHDL编程xilinx basys 3板。我正在照亮4x七段显示器的各个部分,使其看起来好像显示器有两个旋转的“轮子”。我的整个项目包括许多组件,如解码器、多路复用器、去抖动器、计数器、显示刷新率时钟分频器等。所有这些都已被我的教授清除。 我目前正在工作的组成部分,在一个250赫兹时钟和一个向上和向下的按钮。向上和向下按钮将允许增加映射到11个不同预分频值的计数器。这些值将相应地改变时钟分频器的最大步长

目前我的重置按钮工作。但是,“向上”和“向下”按钮只是暂停线段的旋转,而不是增加线段的旋转速率。我认为这一部分是问题所在,但我无法找出在这三个过程中的位置

 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.std_logic_unsigned.all;

entity wheelClkDiv is
    Port ( btnUp, btnDown, clk, reset : in STD_LOGIC;   
           --up/down/rst buttons and 250Hz clk initialized as inputs
           clkout : out STD_LOGIC
           -- newly divided clock initialized as output         
         );
end wheelClkDiv;

architecture Behavioral of wheelClkDiv is

signal count : STD_LOGIC_VECTOR(19 downto 0) := x"00000";   --20 bit count value for clk divider
signal temp : STD_LOGIC := '0';                             --temp store value for clk divider
signal countDiv : STD_LOGIC_VECTOR(19 downto 0) := x"00000"; --value given to choose prescalar 
signal btn_counter : STD_LOGIC_VECTOR(3 downto 0) := "0110";    --button press counter
begin
    buttonChoose : process(btnUp, btnDown, reset)
        begin
            if(btnUp = '1') then
                btn_counter <= btn_counter + 1;     --add one to count if up button pushed
            elsif(btnDown = '1') then
                btn_counter <= btn_counter - 1;     --subtract one from count if down button pushed
            elsif(reset = '1') then
                btn_counter <="0110";           --set back to middle speed if reset is pushed
            end if;
    end process;

    setDivideCase : process(btn_counter)
        begin
            case btn_counter is    --case statement to choose prescalar based on btn_counter value
                when "0000" => 
                    countDiv <= b"00000000000110010000"; --3.2s cycle
                when "0001" => 
                    countDiv <= b"00000000000100101100"; --2.4s cycle
                when "0010" => 
                    countDiv <= b"00000000000011001000"; --1.6s cycle
                when "0011" => 
                    countDiv <= b"00000000000010010110"; --1.2s cycle
                when "0100" => 
                    countDiv <= b"00000000000001100100"; --0.8s cycle
                when "0101" => 
                    countDiv <= b"00000000000001001011"; --0.6s cycle
                when "0110" => 
                    countDiv <= b"00000000000000110010"; --0.4s cycle
                when "0111" => 
                    countDiv <= b"00000000000000100110"; --0.3s cycle
                when "1000" => 
                    countDiv <= b"00000000000000011001"; --0.2s cycle
                when "1001" => 
                    countDiv <= b"00000000000000010011"; --0.15s cycle
                when "1010" => 
                    countDiv <= b"00000000000000001101"; --0.1s cycle     
                when others =>
                    countDiv <= b"00000000000000001101";--not correct
            end case;      
    end process;

    wheelDivider : process(clk, reset)
    begin
        if(reset = '1') then    --reset clock count if reset pushed
            count <= x"00000";
            temp <= '0';
        elsif(rising_edge(clk)) then    
            if(count = countDiv) then    --set clk counter value to prescalar
                count <= x"00000";
                temp <= not temp;            
            else
                count <= count + 1;   --keep incrementing clk count until it matches PS
                temp <= temp;
            end if;
        end if;
   end process;
   clkout <= temp;  --give temp value to output clk 
end Behavioral;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.std_logic_unsigned.all;
实体wheelckdiv是
端口(btnUp、btnDown、clk、复位:在标准逻辑中;
--向上/向下/重新设置按钮和250Hz时钟初始化为输入
clkout:输出标准逻辑
--新划分的时钟初始化为输出
);
端轮CLKDIV;
wheelClkDiv的体系结构是
信号计数:标准逻辑向量(19到0):=x“00000”--clk除法器的20位计数值
信号温度:标准逻辑:='0'--时钟分配器的温度存储值
信号计数div:STD_逻辑_向量(19到0):=x“00000”--给定值以选择预分频器
信号btn_计数器:标准逻辑_向量(3到0):=“0110”--按钮按下计数器
开始
按钮选择:进程(btnUp、btnDown、重置)
开始
如果(btnUp='1'),则

btn_counter我看到的第一件事是忽略了
count
信号不断计数的事实。 当您点击重置时,您的
计数回到'x“00000”,这是它工作的唯一原因

但是,当您按下向上/向下按钮时,您将更改countDiv的值,例如

countDiv <= b"00000000000000110010"; --0.4s cycle

我不确定这是否是目前唯一的问题。希望如此。

我看到的第一件事是你忽略了
计数信号不断计数的事实。
当您点击重置时,您的
计数回到'x“00000”,这是它工作的唯一原因

但是,当您按下向上/向下按钮时,您将更改countDiv的值,例如

countDiv <= b"00000000000000110010"; --0.4s cycle

我不确定这是否是目前唯一的问题。希望如此。

谢谢您的反馈。我有点理解你说的话,但不完全理解。你有没有办法给我提供更多的代码来说明要修改什么而不是如何修改?@DrewP我已经用代码示例更新了我的答案,希望能澄清。现在,如果在倒计时期间更新
countDiv
,则不会发生任何情况,但当
count
达到零时,新的倒计时将从更新的
countDiv
值开始。您还可以通过使用
count>=countDiv
检测何时将计数设置为0来解决此问题。倒计时更优越,零检测更简单。您还希望CountDiv上的转换是时钟同步的,否则您不知道会得到什么<代码>计数
将在合成中优化到9位。计数只能达到4.088秒。感谢您的反馈。我有点理解你说的话,但不完全理解。你有没有办法给我提供更多的代码来说明要修改什么而不是如何修改?@DrewP我已经用代码示例更新了我的答案,希望能澄清。现在,如果在倒计时期间更新
countDiv
,则不会发生任何情况,但当
count
达到零时,新的倒计时将从更新的
countDiv
值开始。您还可以通过使用
count>=countDiv
检测何时将计数设置为0来解决此问题。倒计时更优越,零检测更简单。您还希望CountDiv上的转换是时钟同步的,否则您不知道会得到什么<代码>计数
将在合成中优化到9位。计数只能达到4.088秒。过程
按钮选择
不符合合成条件-模拟行为与合成不匹配。在电路板上,
btn_计数器
将充当选通振荡器
btn_计数器
锁存器,两个按钮启用,提供至少一位反向反馈的算术运算。以及由组合延迟控制的单个比特的振荡率。这似乎与您很少观察到的行为描述一致。解决这一问题的历史方法是为每个按钮按下产生一个时钟长的事件,并使
btn_计数器
时钟边缘驱动,将一个时钟事件作为启用(使用250 Hz时钟的基于计数器的去抖动器可以修改为产生一个时钟长的事件)流程
buttonChoose
合成不合格-模拟行为与合成不匹配。在电路板上,
btn_计数器
将充当选通振荡器
btn_计数器
锁存器,两个按钮启用,提供至少一位反向反馈的算术运算。以及由组合延迟控制的单个比特的振荡率。这似乎与您很少观察到的行为描述一致。解决这一问题的历史方法是为每个按钮按下产生一个时钟长的事件,并使
btn_计数器
时钟边缘驱动,将一个时钟事件作为启用(使用250 Hz时钟的基于计数器的去抖动器可以修改为产生一个时钟长的事件)
wheelDivider : process(clk, reset)
    begin
        if(reset = '1') then    --reset clock count if reset pushed
            count <= b"00000000000001001011";
            temp <= '0';
        elsif(rising_edge(clk)) then    
            if(count = x"00000") then    --set clk counter value to zero
                count <= countDiv;
                temp <= not temp;            
            else
                count <= count - 1;   --keep decrementing count until zero
                temp <= temp;
            end if;
        end if;
end process;