0

我是一名模拟工程师,试图为我的项目学习 VHDL。该项目是计算输入信号的上升沿并将计数预分频为较小的数字。例如,如果输入有 8 个计数,则将输出 1 个计数。预分频值可以由用户更改。我已经设法完成了预分频部分,但在当前输出将不断变高。

我想要做的是,一旦预分频计数 = 用户选择的值,然后输出 500 ns 脉冲而不是恒定逻辑高电平。

我有一个 50 MHz 的时钟,所以输出需要在 25 个锁定周期内保持高电平,但是我不确定如何做到这一点。

任何帮助都会很棒:)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity counter is
port (
    pushbutton: in std_logic;
    SW: in std_logic_vector(7 downto 0); -- user select switches
    RESET: in std_logic;
    OUTPUT: out std_logic;
    LEDS: out std_logic_vector(8 downto 0) -- un used leds

);
end counter;

architecture Behavioral of counter is
signal COUNTER: std_logic;
signal PRESCALER: std_logic_vector(7 downto 0);
signal SWITCH: std_logic_vector(7 downto 0);
begin

CounterProcess: process(RESET, pushbutton)
begin
    if rising_edge(pushbutton) then
        if RESET = '0' then
            PRESCALER <= (others => '0');
            COUNTER <= '0';
        else        
            if PRESCALER < SWITCH - 1 then
            PRESCALER <= PRESCALER + 1;
            else
                PRESCALER <= (others => '0');
                COUNTER <= '1';
                end if;
        end if;
    end if;
end process;

LEDS <= (others => '0'); -- Turn off all unsed LEDs
SWITCH <= SW; -- Asign switch value into a signal 
OUTPUT <= COUNTER; 

end Behavioral;
4

1 回答 1

0

如果我正确理解了问题,如果“SW”信号设置为 8,您应该能够按“按钮”七次而没有任何反应。在第 8 次,“OUTPUT”上应出现 500 ns 脉冲。

看起来你的重置是正确的,但是时钟呢?你必须通过实体把时钟带进来。rise_edge(pushbutton) 的工作实际上很奇怪,因为按钮通常需要去抖动。也就是说,一旦您按下按钮,CounterProcess 将在信号稳定之前记录许多上升沿。此外,COUNTER 仅在模块复位时设置为“0”,因此在正常操作期间它会卡在“1”。

这个问题在我看来最好分为三个过程。按钮输入去抖动的过程。一个预分频器过程,它以去抖信号和 SW 信号作为输入,并在按钮按下计数到 SW 值时输出一个切换信号。最后一个过程是将触发信号作为输入,并在 OUTPUT 上产生一个 500 ns 的脉冲。

对于 CounterProcess,您正在做一些事情,我相信您会弄明白的。但是帮自己一个忙,让所有进程同步:

debounce : process(clk)
  constant max_count : natural := 127;
  variable counter : natural;
  variable prev : std_logic;
begin
  if rising_edge(clk) then
    if rst = '1' then
      -- reset all
    else

      -- if pushbutton is != prev then
      -- check if counter is > max_count, if not we assume
      -- it is still bouncing. if counter is > max_count we
      -- assume this is a new press of the button, so we
      -- toggle the output:
      -- debounced_toggle <= not debounced_toggle;

      prev := pushbutton;
    end if;
  end if;
end process;

CounterProcess: process(clk)
  variable prev : std_logic;
  variable counter : natural;
begin
  if rising_edge(clk) then
    if rst = '1' then
      -- reset all
    else

      -- when debounced_toggle != prev, do your magic
      -- and increment the counter

      -- when counter reaches the value of SW,
      -- reset the counter and toggle the output:
      -- output_toggle <= not output_toggle

      prev := debounced_toggle;
    end if;
  end if;
end process;

output_pulse : process(clk)
  constant max_count : natural := 25;
  variable counter : integer;
  variable prev : std_logic;
begin
  if rising_edge(clk) then
    if rst = '1' then
      -- reset all incl OUTPUT
    else
      OUTPUT <= '0'; -- '0' if not overwritten later in process

      -- if output_toggle != prev,
      -- hold OUTPUT for 25 clock cycles

      prev := debounced_toggle;
    end if;
  end if;
end process;
于 2014-02-13T23:26:10.763 回答