我是一名模拟工程师,正在尝试为我所拥有的项目学习VHDL。该项目是计算输入信号的上升沿,并将计数预分频到较小的数字。例如,如果输入上有8个计数,则输出1个计数。预分频值可以由用户更改。我已经成功地完成了预分量部分的工作,但是在现有的情况下,输出会不断变高。
我要做的是,一旦预分频计数=用户选择的值,则输出500 ns脉冲而不是常数逻辑高。
我有一个50 MHz的clk,因此输出需要保持高电平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;
答案 0 :(得分:0)
如果我正确理解了问题,如果'SW'信号设置为8,你应该能够在没有任何反应的情况下按下“按钮”七次。在八次,'OUTPUT'上应出现500 ns脉冲。
看起来你的重置是正确的,但时钟在哪里?你必须通过实体带来时钟。 rising_edge(按钮)工作实际上很奇怪,因为按钮通常需要去抖动。也就是说,一旦按下按钮,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;