【问题标题】:VHDL clock generator with different speeds using button使用按钮具有不同速度的 VHDL 时钟发生器
【发布时间】:2015-07-03 02:55:10
【问题描述】:

我是 VHDL 的新手,目前正在研究生成两种不同时钟速度的时钟发生器。 一切正常,除了慢速和快速speed_status之间的切换。 “速度按钮”似乎有问题,因为有时我必须多次按下它才能更改当前设置的速度。 “重置按钮”始终按预期工作。我的 VHDL 代码有问题还是我需要添加某种软件去抖动?如果是这样,为什么重置按钮有效? 您能否给我一些建议,我可以改进时钟发生器的哪些部分(代码/逻辑)?

entity clk_gen is
Port ( clk_in : in  STD_LOGIC;
       clk_btn_in : in STD_LOGIC_VECTOR (3 DOWNTO 0);
       clk_out : out  STD_LOGIC);
end clk_gen;

architecture Behavioral of clk_gen is
    signal temp : STD_LOGIC := '0';
    begin
    clock: process(clk_in,clk_btn_in)
        variable counter : integer range 0 to 49999999 := 0;
        constant freq_cnt_slow : integer := 49999999;
        constant freq_cnt_fast : integer := 4999999;
        type speed is (slow, fast);
        variable speed_status : speed := slow;
        begin
            if rising_edge(clk_in) then
                -- RESET BUTTON PRESSED
                if (clk_btn_in = "1000") then
                    temp <= '0';
                    counter := 0;
                    speed_status := slow;

                -- SPEED BUTTON
                elsif (clk_btn_in = "0100") then
                    if (speed_status = fast) then
                    speed_status:= slow;
                elsif (speed_status = slow) then
                     speed_status := fast;
                end if;
            end if;

            if ((counter = freq_cnt_fast) and (speed_status = fast)) then
                temp <= NOT(temp);
                counter := 0;
            elsif ((counter = freq_cnt_slow) and (speed_status = slow)) then
                temp <= NOT(temp);
                counter := 0;
            else
                counter := counter + 1;
            end if;

        end if;
    end process clock;

    clk_out <= temp;
end Behavioral;

我使用 Xilinx ISE 13.4 和基于 Xilinx Virtex 5 的 XC5VLX110T。

【问题讨论】:

    标签: button vhdl debouncing


    【解决方案1】:

    您的速度模式似乎会在按钮处于“按下”状态时切换。除非您可以保证您的按钮仅在一个时钟周期内被“按下”,否则状态可能会切换多次,从而使您按下按钮后的状态基本上是随机的(取决于按下按钮的确切时间)。

    首先,您需要在按钮上设置一个去抖电路。这可以在外部实现,也可以在 FPGA 内实现。我不会在这里详细介绍开关去抖动,但是您可以在其他地方轻松找到有关此的信息。其次,您需要将按钮转换为同步信号,即与您的时钟有固定关系的信号。您的示例的示例同步器是:

    signal button_reg1 : std_logic_vector(3 downto 0) := (others => '0');
    signal button_reg2 : std_logic_vector(3 downto 0) := (others => '0');
    

    ...

    process (clk_in)    
    begin
        if (rising_edge(clk_in)) then
            button_reg2 <= button_reg1;
            button_reg1 <= clk_btn_in;
        end if;
    end process;
    

    button_reg2 将与时钟建立固定关系。 如果没有这个,您可能会违反speed_status 寄存器上的设置/保持约束。最后,您需要将按钮的按下转换为长度为一个时钟周期的脉冲。示例:

    signal speed_button_reg : std_logic := '0';
    signal speed_button_pressed : std_logic := '0';
    

    ...

    process (clk_in)    
    begin
        if (rising_edge(clk_in)) then
            speed_button_reg <= button_reg2(2);
            if (speed_button_reg = '0' and button_reg2(2) = '1') then
                -- The button has just been pressed (gone from low to high)
                -- Do things here, or set another signal e.g.
                speed_button_pressed <= '1';
            else
                speed_button_pressed <= '0';
            end if;
        end if;
    end process;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2021-05-26
      相关资源
      最近更新 更多