2014-02-13 3 views
0

저는 프로젝트에 VHDL을 배우려고하는 아날로그 엔지니어입니다. 이 프로젝트는 입력 신호의 상승 에지를 카운트하고 카운트를 더 작은 수로 프리 스케일합니다. 예를 들어 입력에 8 카운트가 있으면 1 카운트가 출력됩니다. 사전 설정 값은 사용자가 변경할 수 있습니다. 나는 prescale 부분을 작동시킬 수 있었지만 압박에서 출력은 끊임없이 높게 갈 것입니다.VHDL 500 ns pulse

내가하고자하는 것은 일단 prescale 카운트가 사용자 선택 값이면 = 500ns 펄스가 일정 로직보다 높게 출력된다는 것입니다.

저는 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

내가 정확하게 문제를 이해하면 'SW'신호를 8로 설정되어있는 경우, 당신은 아무 일도 발생하지 않습니다 동안 일곱 번 '푸시 버튼'을 눌러 할 수 있어야한다 . 8 번에 'OUTPUT'에 500ns 펄스가 나타납니다.

재설정이 제대로 된 것처럼 보이지만 시계는 어디에 있습니까? 엔티티를 통해 시계를 가져와야합니다. 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;