2012-02-20 1 views
0

このコードは非常にシンプルでなければならず、私は何が間違っているのか分かりません。 これは何をすべきか説明しています:誰でもこのVHDLコードを手伝ってもらえますか(現在は機能していません)?

1つの7セグメントディスプレイに数値を表示する必要があります。誰かがプッシュボタンを押すたびに、その数字を1つずつ増やす必要があります。番号を0に設定するリセットボタンもあります。それだけです。ここでVHDLコードである:

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

entity PWM is 
    Port (cp_in : in STD_LOGIC; 
      inc : in STD_LOGIC; 
       rst: in std_logic; 
      AN : out STD_LOGIC_VECTOR (3 downto 0); 
      segments : out STD_LOGIC_VECTOR (6 downto 0)); 
end PWM; 

architecture Behavioral of PWM is 
    signal cp: std_logic; 

    signal CurrentPWMState: integer range 0 to 10; 
    signal inco: std_logic; 
    signal temp: std_logic_vector (3 downto 0); 
begin 
    --cp = 100 Hz 
    counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp); 
    debounce: entity debounce port map (inc, cp, inco); 
    temp <= conv_std_logic_vector(CurrentPWMState, 4); 
    ss: entity decoder7seg port map (temp, segments); 

    process (inco, rst) 
    begin 
     if inco = '1' then 
      CurrentPWMState <= CurrentPWMState + 1; 
     elsif rst='1' then 
      CurrentPWMState <= 0; 
     end if; 
    end process; 

    AN <= "1110"; 
end Behavioral; 

エンティティdjelitelj(50MHzのクロックを分割するために使用されるカウンタ):

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

entity PWM is 
    Port (cp_in : in STD_LOGIC; 
      inc : in STD_LOGIC; 
       rst: in std_logic; 
      AN : out STD_LOGIC_VECTOR (3 downto 0); 
      segments : out STD_LOGIC_VECTOR (6 downto 0)); 
end PWM; 

architecture Behavioral of PWM is 
    signal cp: std_logic; 

    signal CurrentPWMState: integer range 0 to 10; 
    signal inco: std_logic; 
    signal temp: std_logic_vector (3 downto 0); 
begin 
    --cp = 100 Hz 
    counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp); 
    debounce: entity debounce port map (inc, cp, inco); 
    temp <= conv_std_logic_vector(CurrentPWMState, 4); 
    ss: entity decoder7seg port map (temp, segments); 

    process (inco, rst) 
    begin 
     if inco = '1' then 
      CurrentPWMState <= CurrentPWMState + 1; 
     elsif rst='1' then 
      CurrentPWMState <= 0; 
     end if; 
    end process; 

    AN <= "1110"; 
end Behavioral; 

デバウンシングエンティティ:ここで

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
use IEEE.STD_LOGIC_ARITH.all; 
use IEEE.STD_LOGIC_UNSIGNED.all; 
ENTITY debounce IS 
    PORT(pb, clock_100Hz : IN STD_LOGIC; 
     pb_debounced  : OUT STD_LOGIC); 
END debounce; 

ARCHITECTURE a OF debounce IS 
    SIGNAL SHIFT_PB : STD_LOGIC_VECTOR(3 DOWNTO 0); 
BEGIN 

-- Debounce Button: Filters out mechanical switch bounce for around 40Ms. 
-- Debounce clock should be approximately 10ms 
process 
begin 
    wait until (clock_100Hz'EVENT) AND (clock_100Hz = '1'); 
     SHIFT_PB(2 Downto 0) <= SHIFT_PB(3 Downto 1); 
     SHIFT_PB(3) <= NOT PB; 
     If SHIFT_PB(3 Downto 0)="0000" THEN 
     PB_DEBOUNCED <= '1'; 
     ELSE 
     PB_DEBOUNCED <= '0'; 
     End if; 
end process; 
end a; 

となるBCD 7セグメントデコーダ:

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

entity decoder7seg is 
    port (
     bcd: in std_logic_vector (3 downto 0); 
     segm: out std_logic_vector (6 downto 0)); 
end decoder7seg; 

architecture Behavioral of decoder7seg is 
begin 
    with bcd select 
     segm<= "0000001" when "0000", -- 0 
     "1001111" when "0001",  -- 1 
     "0010010" when "0010",  -- 2 
     "0000110" when "0011",  -- 3 
     "1001100" when "0100",  -- 4 
     "0100100" when "0101",  -- 5 
     "0100000" when "0110",  -- 6 
     "0001111" when "0111",  -- 7 
     "0000000" when "1000",  -- 8 
     "0000100" when "1001",  -- 9 
     "1111110" when others;  -- just - character 

end Behavioral; 

誰かが私のミスをどこに見ましたか? 私はSpartan-3 Startedボードでそのデザインを試しましたが、動作していません...プッシュボタンを押すたびに、私は狂った(ランダム)値を取得します。リセットボタンが正常に動作しています。 ありがとう!!!!

+0

あなたは "djelitelj"を提供していませんが、あなたはPWMを2回ペーストしました。 – Philippe

答えて

2

は、私はこの問題はここにあると思います:

process (inco, rst) 
begin 
    if inco = '1' then 
     CurrentPWMState <= CurrentPWMState + 1; 
    elsif rst='1' then 
     CurrentPWMState <= 0; 
    end if; 
end process; 

あなたがCurrentPWMStateをリセットしますrst='1'とき。しかし、inco='1'あなたは無限にをCurrentPWMStateに追加してください。これは、ラッチを介した非同期フィードバックループのようなものです。あなたはここで何か縁を敏感にするべきです。クロック信号を使用してincoをキャプチャし、0→1の変化を検出してから1を追加する必要があります。

1

前の回答に同意します。

このようなコードは、トリックを行う必要があります。

process (inco, ps, rst) 
begin 
    if rst='1' then 
    CurrentPWMState <= '0'; 
    prev_inco <= inco; -- This signal captures the previous value of inco 
    elsif ps'event and ps='1' then 
    if inco='1' and prev_inco='0' then -- Capture the flank rising. 
     CurrentPWMState <= CurrentPWMState + 1; 
    end if; 
    prev_inco <= inco; 
    end if; 
end process; 

私は(ちょうどここでコード化された)のコードを試していないが認識するが、私はそれは大丈夫だと思います。

関連する問題