2017-06-08 21 views
2

Imは3までカウントアップし、0にカウントダウンします。 例:0 1 2 3 2 1 0 1 2 3 2 1 0 ...VHDLアップ/ダウンカウンタのエラーカウント

私がやったこと

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

entity Counter is 
    port(
    Clock: in std_logic; 
    Reset: in std_logic; 
    Output: out std_logic_vector(0 to 1)); 
end Counter; 

architecture Behavioral of Counter is 
    signal temp: std_logic_vector(0 to 1); 
    signal down: std_logic := '0'; 
begin process(Clock,Reset) 
    begin 
     if Reset='0' then 
     temp <= "00"; 
     down<= '0'; 
     elsif(rising_edge(Clock)) then 
      if temp="11" then 
       down<= '1'; 
      elsif temp="00" then 
       down<='0'; 
      end if; 

      if down='0' then 
       temp <= temp +1; 
      else 
       temp <= temp-1; 
      end if; 

     end if; 
    end process; 
    Output <= temp; 
end Behavioral; 

はどういうわけか、出力が間違っている何 ...真ん中の数字を示すことなく、3から0に起こっていますか?

+1

おそらくそれはカウントダウンではなくオーバーフローしています。あなたは信号ではなく可変であると考えていたので、 '<='ではなく ':='(即時の割り当て)を使用しましたか? – diginoise

+2

Strangeでは、std_logic_vectorに何かを追加できます。どのツールを使用しますか?そしてそれは@diginoiseが言ったのと同じです。 'temp =" 11 "'を指定すると 'down <= '1' 'が割り当てられますが、プロセスが終了した後に起こります。したがって、if down = '0' then 'でチェックされても' 0 'です。それがオーバーフローする理由です。反対方向でも同じ。 – Staszek

+1

@Staszek彼らはstd_logic_unsigned legacy pacakgeを使用しています。 –

答えて

4

あなたはすべての信号を見ているわけではありません。何が起こるかはdownをご覧ください。クロックド同期ロジックを使用しているため、tempが検出されたクロックサイクルではdownが変更されるため、1クロックサイクル後にの効果を得ます。。私。変更down1クロックサイクル以前 ...:tempが3の場合、downは依然として従って0、MOD 4 = 0

一つの可能​​な解決策は、一歩先このことがある

は、(+ 1 3)であろうtemp = 2。

もう1つの問題は、標準化されていないパッケージSTD_LOGIC_ARITHSTD_LOGIC_UNSIGNEDをロジックアレイと逆方向に組み合わせることです。それは予期しない結果をもたらす可能性があります。標準化されたパッケージを使用してください。例:

library ieee; 
use ieee.STD_LOGIC_1164.ALL; 

entity counter is 
    port(
     clk : in std_logic; 
     rst_n : in std_logic; 
     output : out std_logic_vector(1 downto 0) 
    ); 
end entity; 

architecture behavioral of counter is 
    use ieee.numeric_std.ALL; 
    signal temp : unsigned(output'range) := (others => '0'); 
    signal down : std_logic := '0'; 
begin 
    process(clk, rst_n) 
    begin 
     if rst_n = '0' then -- why asynchronous reset?? 
      temp <= (others => '0'); 
      down <= '0'; 
     elsif(rising_edge(clk)) then 
      if temp = 2 then 
       down <= '1'; 
      elsif temp = 1 then 
       down <= '0'; 
      end if; 
      if down = '0' then 
       temp <= temp + 1; 
      else 
       temp <= temp - 1; 
      end if; 
     end if; 
    end process; 
    output <= std_logic_vector(temp); 
end architecture; 

-

entity counter_tb is end entity; 

library ieee; 
use IEEE.STD_LOGIC_1164.ALL; 

architecture behavioral of counter_tb is 
    signal clk : std_logic; 
    signal rst_n : std_logic; 
    signal output : std_logic_vector(1 downto 0); 
begin 
    DUT: entity work.Counter 
     port map(
      clk => clk, 
      rst_n => rst_n, 
      output => output 
     ); 

    rst_n <= '1'; 
    process 
    begin 
     clk <= '0', '1' after 1 ns; 
     wait for 2 ns; 
    end process; 
end architecture; 

次の時間... を完全なセットを形成するために、あなたのテストベンチを追加してください、みんなと同じように、4を使用:(3 - スペースのインデントを使用しないでください)

+0

これはうまくいった!それはあふれていた –