2014-02-13 66 views
0

我是一個模擬工程師,試圖學習VHDL爲我有一個項目。該項目將計算輸入信號的上升沿並將計數預分頻爲較小的數值。例如,如果輸入上有8個計數,則會輸出1個計數。預分頻值可以由用戶改變。我已經成功地完成了prescale部分的工作,但是在目前的情況下,輸出會不斷高漲。VHDL 500納秒脈衝

我想要做的是一旦預分頻計數= =用戶選擇的值,那麼輸出500ns的脈衝而不是恆邏輯高。

我有一個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; 

回答

0

如果我理解正確的問題,如果「SW」信號被設置爲8,你應該能夠按「按鈕」的七倍,而沒有任何反應。在第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;