2011-10-28 14 views
1

Dフリップフロップを使用して4ビットリングカウンタをモデル化しました。リングカウンタの未定義出力テスト波形

Dフリップフロップは別のファイルにあり、私のワークスペースに含まれています。 Dフリップフロップは正しく動作します(正しい出力波形を与えます)。

これは、リングカウンタのコードである:ここ

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 

entity ring4counter is 
    port (
     clk: std_logic; 
     output: out std_logic_vector(3 downto 0)); 
end ring4counter; 

architecture ring4counter_arch of ring4counter is 
    component dff 
    port (
     clk: std_logic; 
     d: in std_logic; 
     q: out std_logic; 
     qbar: out std_logic); 
    end component; 

    signal temp:std_logic_vector(3 downto 0):=(others=>'0'); 
begin 
    r1: dff port map(clk, temp(3), temp(0)); 
    r2: dff port map(clk, temp(0), temp(1)); 
    r3: dff port map(clk, temp(1), temp(2)); 
    r4: dff port map(clk, temp(2), temp(3)); 
    output <= temp; 
end ring4counter_arch; 

は、リングカウンタのテストベンチ・コードである:

library ieee; 
use ieee.std_logic_1164.all; 

entity ring4_tb is end ring4_tb ; 

architecture arch of ring4_tb is 
    component tbc is 
    port (
     clk: std_logic; 
     output: out std_logic_vector(3 downto 0)); 
    end component ; 

    component dff 
    port (
     clk: std_logic; 
     d: in std_logic; 
     q: out std_logic; 
     qbar: out std_logic); 
    end component; 

    constant period : time := 50 ns ; 

    signal clk  : std_logic := '0' ;  
    signal done  : boolean := false ; 
    signal output : std_logic_vector(3 downto 0) ; 

    shared variable cycle : natural := 0 ; 

    signal temp:std_logic_vector(3 downto 0):=(others=>'0'); 

begin 
-- this is the unit under test 
    u1: tbc 
    port map(
     clk => clk, 
     output => output) ; 

    clkprocess: process(done, clk) 
    begin 
    if (not done) then 
     if (clk = '1') then 
     cycle := cycle + 1 ; 
     end if ; 
     clk <= not clk after period/2 ; 
    end if ; 
    end process ; 

    r1: dff port map(clk, temp(3), temp(0)); 
    r2: dff port map(clk, temp(0), temp(1)); 
    r3: dff port map(clk, temp(1), temp(2)); 
    r4: dff port map(clk, temp(2), temp(3)); 
    output <= temp; 

    testbench: process 
    begin 
    wait until (clk = '0') ; 
    temp <= "1000"; 
    wait for period*4 ; 

    done <= true ;  -- force the clock process to shutdown 
    wait ;   -- this waits forever 
    end process ; 
end arch ; 

しかし、「出力」の波形は、すべてのビットは「U」です。 どこが間違っていますか?

+0

私はこれが古い投稿だと知っていますが、私は文体的なコメントをしたいと思います。現実世界での投稿による投稿を行うと、あなたは狩りと殴られます。これまでにしないでください。単純なコンポーネントのための '' r1:dffポートマップ(clk => clk、d => temp(3)、q => temp(0)); 'は単純です。 DFFコンポーネントが必要です)。 –

+0

私は殴られるとは思わない!私はリングカウンターにDFFは必要ないと知っています。しかし、あなたが(私が学んでいることを意味して)学習しているとき、それは明らかではない経路をとるのが理にかなっています。 –

答えて

2

tempを "1000"に初期化しようとしているときのテストベンチプロセスでは、フリップフロップもtemp信号を駆動していますので、効果的にバス競合が発生します。

+0

あなたはバスを運転する複数のものを持つことはできません(一般的に) –

+0

私はそれを訂正できる方法はありますか?私はあまりVHDLを知らない。私はさらに線temp <= "1000"を省いても、変更はありません。 –

+0

Dフリップフロップの初期化方法を変更する必要があります。 1つの方法は、DとQ入力を分離し、リセット時に初期化値を明示的にロードすることです。私はコメントに書式設定されたコードを置くことはできませんが、r1:dffポートマップ(clk、temp_in(3)、temp(0)); reset = '1'のときtemp_in <= "1000" else temp;あなたは正しい方向に向かうべきです。 –

-1

Dフリップフロップにイネーブル信号を追加することです。回路をリセットしたい場合は、イネーブル信号を "L"にしてから、 "1000"に変更してください。

r1: dff port map(clk, temp(3), temp(0), enable); 

process(clk,reset) 
begin 
if(rising_edge(clk)) then 
if(reset='1') then 
    enable='0'; 
    temp <= "1000"; 
else 
    enable <= '1'; 
end if; 
end if; 
end process; 
+1

私はそれがうまくいくとは思わない - DFFはリセット中でも信号を駆動している。 –

+0

@Martin:メモ。しかし、Q <= Dがイネーブル信号がハイの場合にのみ割り当てられるように、Dフリップフロップを定義すればどうでしょうか?そうでなければ、割り当ては行われません。その場合にはうまくいくのでしょうか? – vipin

+0

割り当てが発生したときではありません。プロセスのどこかに割り当てがあるという事実によって、「ドライバ」が作成され、ドライバが衝突します。 VHDLには非アクティブなドライバはありません。 'std_logic'を使うと、Zドライバを使うことができます.Zドライバは期待通りに解決しますが、まだドライバです。 –

0

信号を設定するには、リングカウンタでtempの初期化を使用してください。

これは、アーキテクチャと合成ツールによって正しく合成されない場合があることに注意してください。

これを行う最も一般的な目的は、リセット信号をon以外のすべてのDFFに追加し、その信号にプリセット信号を入力することです。その後、最初にリセットをアサートし、DFFを適切な値に設定します。

これは、明示的なDFFを使用する必要がないように、コードを単純化したものです。またtempの幅を変更することができ、コードはあなたのためのすべての残りを行います。

process (clk) 
begin 
    if reset = '1' then 
     temp <= (0=>'1', others => '0'); -- set one bit high, the others low. 
    elsif rising_edge(clk) then 
     -- take the high bit and move it to the low bit. 
     -- Move the other bits left 1 place 
     temp <= temp(temp'high-1 downto 0) & temp(temp'high); 
    end if; 
end process; 

(注意:!コードだけでメッセージに入力し、そこでは、構文タイプミスがあるかもしれません)


BTW、shared variableは、protectedタイプでない限り、悪い考えです。彼らは競争条件を持つことができます。

関連する問題