【问题标题】:VHDL change CLK speedVHDL 改变 CLK 速度
【发布时间】:2026-02-14 06:45:01
【问题描述】:

从这段代码中我创建了一个块,然后添加 CLK、KEY[0] 和 LEDR[0:15]

   library ieee;
use ieee.std_logic_1164.all;

--library work;
--use work.car_pkg.all;


entity knight_rider2 is
    port (  clk, resetn, clock_button : in std_logic;
        led1, led2, led3, led4, led5, led6, led7, led8, 
        led9, led10, led11, led12, led13, led14, led15 : out std_logic);
end entity knight_rider2;



architecture fsm of knight_rider2 is
    type state_types is (start, forward1, forward2, forward3, 
    forward4, forward5, forward6, forward7, forward8, forward9, 
    forward10,forward11,forward12, forward13, forward14);


    signal state: state_types;
    signal led_states : std_logic_vector(14 downto 0);

begin

             count : process(clk, resetn, clock_button)
begin
  if clock_button = '0' then
    counter   <= 0;
    fsm_pulse <= '0';
  else
    if rising_edge(clk) then
      counter     <= counter + 1;
      fsm_pulse   <= '0';
      if counter = divider then
        fsm_pulse <= '1';
        counter   <= 0;
      end if;
    end if;
  end if;
end process;


    combined_next_current: process (clk, resetn, clock_button)
    begin
        if (resetn = '0') then
            state <= start;
        elsif rising_edge(clk) then
            if fsm_pulse = '1' then
            case state is

                when start => 
                    state <= forward1;

                when forward1 =>                
                    state <= forward2;              


                when forward2 =>                    
                        state <= forward3;              

                when forward3 =>            
                        state <= forward4;              

                when forward4 =>                    
                        state <= forward5;                  


                when forward5 =>                
                        state <= forward6;                  


                when forward6 =>                    
                        state <= forward7;                  


                when forward7 =>                
                            state <= forward8;              

                when forward8 =>                    
                            state <= forward9;      


                when forward9 =>                    
                            state <= forward10;                     

                when forward10 =>                       
                            state <= forward11;


                when forward11 =>                   
                            state <= forward12;                 


                when forward12 =>                       
                            state <= forward13;


                when forward13 =>                       
                            state <= forward14;



                when forward14 => state <=start;

                when others =>
                state <= forward1;

            end case;
        end if;
    end process;


    --combinational output logic

    --internal signal to control state machine transistions


    led_select : process(state)
begin
  case state is
    when forward1 =>
     led_states <= "000000000000011";
     when forward2 =>
     led_states <= "000000000000110";
    when forward3 =>
     led_states <= "000000000001100";
    when forward4 =>
     led_states <= "000000000011000";
     when forward5 =>
     led_states <= "000000000110000";
     when forward6 =>
     led_states <= "000000001100000";
     when forward7 =>
     led_states <= "000000011000000";
     when forward8 =>
     led_states <= "000000110000000";
     when forward9 =>
     led_states <= "000001100000000";
     when forward10 =>
     led_states <= "000011000000000";
     when forward11=>
     led_states <= "000110000000000";
     when forward12=>
     led_states <= "001100000000000";
     when forward13=>
     led_states <= "011000000000000";
     when forward14=>
     led_states <= "110000000000000";
     when others =>
     led_states <= "100000000000001";

  end case;
end process;

led1 <= led_states(0);
led2 <= led_states(1);
led3 <= led_states(2);
led4 <= led_states(3);
led5 <= led_states(4);

led6 <= led_states(5);
led7 <= led_states(6);
led8 <= led_states(7);
led9 <= led_states(8);
led10 <= led_states(9);

led11 <= led_states(10);
led12 <= led_states(11);
led13 <= led_states(12);
led14 <= led_states(13);
led15 <= led_states(14);





end;

但现在我想添加 KEY[1] 按钮来改变速度,例如:

第一次按下:2*f

2 按:4*f

3 次按下:8*f

4 按:f

5 按:2*f 等

那么,我怎样才能改变这段代码来做我想做的事呢?

【问题讨论】:

    标签: vhdl fpga


    【解决方案1】:

    您可以通过使用计数器来更改状态机的运行速率,例如:

    -- Generate a counter at your main clock frequency
    -- counter is declared as an integer.
    count : process(clock, resetn)
    begin
      if resetn = '0' then
        counter   <= 0;
        fsm_pulse <= '0';
      else
        if rising_edge(clock) then
          counter     <= counter + 1;
          fsm_pulse   <= '0';
          if counter = divider then
            fsm_pulse <= '1';
            counter   <= 0;
          end if;
        end if;
      end if;
    end process;
    

    新信号声明如下:

    signal fsm_pulse : std_logic;
    signal counter   : integer;
    signal divider   : integer;
    

    然后,在您的 FSM 流程中,您可以使用您生成的 fsm_pulse 触发状态转换:

    combined_next_current: process (clk, resetn)
    begin
        if (resetn = '0') then
            state <= start;
        elsif rising_edge(clk) then
          if fsm_pulse = '1' then
            case state is
                when start => 
                    state <= forward1;
                when forward1 =>                
                    state <= forward2; 
    
            ...
    
            etc (your remaining states)
          end if;
    

    每当计数器达到您选择的分频器值时,fsm_pulse 将在单个时钟周期内设置为“1”。分频器值表示您希望在每个 FSM 转换之后发生的时钟周期数,例如,零分频器将使 FSM 转换为主时钟频率,而分频器为 1 将使 FSM 转换为主时钟频率减半.

    【讨论】:

    • 对不起,我有点看不懂你的代码;在 CLK 上,我总是发送 10。(我更新了我的代码并添加了你,但我收到了一些错误)
    • 什么是分频器,fsm_pulse是什么类型?
    • 我刚刚查看了您更新的代码,您应该将 fsm_pulsedividercounter 声明为信号,而不是变量(我已经编辑了我的帖子以向您展示要使用的类型) .我认为您不应该使用clock_button 作为重置。如果您打算使用clock_button 来循环频率,您应该设置另一个状态机,每次按下clock_button 时将divider 设置为不同的值。由于clock_button 似乎是一个外部硬件按钮,您应该考虑对其进行去抖动以检测按钮按下。
    • resetn - 重置按钮,clock_button - 更改频率按钮
    • 在您链接的代码的第 31 行中,您使用 clock_button 作为重置,因此将其改回 resetn