2011-10-30 13 views
0

VHDLの増分:( こんにちは!私はしばらくの間、この問題に取り組んできました。私はそれが私はかなり理解していないから始まる問題だ気持ちを持っている。問題をコーディングする内部信号

--I」 m内部メモリへのアクセス、それぞれ2ビット数の4行。私はメモリに読み書きできました。問題は次のデータセットを格納するアドレスをインクリメントすることです。

- 私ユニットは、3つの状態を持つFSMによって制御される。私は3つの内部信号addressin:次に読み取られるべきアドレスへのポインタaddressout:次に書き込まれるアドレスへのポインタaddressall、アドレスそれはtに入る彼は実際の記憶段階です。

PROCESS (y) 
    BEGIN 
    CASE y IS 
    WHEN I=> 
    enable<='0'; 

    WHEN reed=> 
    enable<='0'; 
    IF (addressin="00" OR addressin="01" OR addressin="10") THEN 

     addressin<=addressin+"01"; 
    ELSE 
     addressin<="00"; 
    END IF; 
    addressall<=addressin; 

    WHEN rite=> 
    enable<='1'; 
    IF (addressout="00" OR addressout="01" OR addressout="10") THEN 
     addressout<=addressout+1; 
    ELSE 
     addressout<="00"; 
    END IF; 
    addressall<=addressout; 

    END CASE; 
END PROCESS;  

memorystage: memory PORT MAP (clck, NOT reset, NOT enable, addressall, datain, dataout);  

yが変化したときにプロセスがアクティブになりますが(状態が変化するコードは見ていないです。)私の問題があり、アドレシンが変更されます、アドレスを変更しないだろう、とそうaddressallはなります...しかし、決して1つだけで決して決して連続的なロジックではありません。(私はこれを16進表示で見ることができます)例えば、私はaddressinを得るでしょう:3 3 1 0 3 0 3 0 2 0 2 1 0 ....と同じ他の2つのアドレス信号。私は何が間違っているのか分かりません。これは大規模なプロジェクトの一部に過ぎないので、私はそれを取り上げてそれに取り組んだ。 :(私は間違っている?ありがとうをやって何をしています。-jenn

+0

もう少しコードを投稿できますか?どのライブラリを使用していますか?あなたの信号はどんなタイプですか?また、「リード」と「ライト」のような綴りがある理由はありますか? –

答えて

1

私はあなたがVHDLの(very well definedが、多くの場合、初心者に混乱)信号更新ルールの餌食に落ちたんだと思います。この質問も参照してください。.. When do signals get assigned in VHDL?

信号は、唯一のプロセスの終了時に更新される(またはwaitが発生したときに、私たちは今のところそのオプションを残しておきます!)


IF (addressin="00" OR addressin="01" OR addressin="10") THEN 
    addressin<=addressin+"01"; 
ELSE 
    addressin<="00"; 
END IF; 
addressall<=addressin; 

addressallを取得しますPRあなたがまだ更新していない値に設定した値ではありません。の値はaddressinではありません。

、あなたが望む動作を取得プロセス内variableaddressinを変更する(そしてあなたが:=割り当てにすべて<=割り当てを変更する必要があります)します。変数は、必要な方法で機能します。更新はすぐに適用されます。

私はたいていプロセス内のものに変数を使用し、他のプロセスとの通信のためのシグナルを残します。

+0

ああ、ええ、私はそれを知っています。そして私はそれが欲しい、私はポインタが次のものを指していることを望む。したがって、addressallは00になりますが、addressinは01になります。私の問題は、addressall、inまたはoutがどちらも1つ増えていないことです。それは2になり、次に0に行き、3に行きます。論理的な順序もありません。例:3,3,2,0,1,0,2,2,2,0.私はある種のパターンを見ることができるかどうかを見ていましたが、運はありません。しかし、お返事ありがとう!私はaddressin <= address + 1;と他の多くの方法も持っていました。 – user1020394

0

同期デザインを使用できるかどうかはわかりませんが、一緒に投げました。このデザインは、あなたがリードまたは儀式の状態にある場合、時計の更新と同じくらい早くあなたのアドレスポインタ(addressin、addressout)を通って増加します。

PROCESS (y, clk) BEGIN 
    IF rising_edge(clk) then 
     enable<='0'; 
     CASE y IS 
      WHEN I=> 

      WHEN reed=> 
       IF(addressin ="11") then 
        addressin <= "00"; 
       ELSE 
        addressin <= addressin + 1; 
       END IF; 

       addressall<=addressin; 

      WHEN rite=> 
       enable<='1'; 

       IF(addressout ="11") then 
        addressout <= "00"; 
       ELSE 
        addressout <= addressin + 1; 
       END IF; 

       addressall<=addressout; 
     END CASE; 
    END IF; 
END PROCESS;  

memorystage: memory PORT MAP (clck, NOT reset, NOT enable, addressall, datain, dataout); 

あなただけそれはあなたが何かをしたい場合は、私達にあなたのコードの多くを与える必要が

prev_state : PROCESS (y,clk) BEGIN 
    IF rising_edge(clk) then 
     ybuff <= y; 
    END IF; 
END PROCESS; 

PROCESS (y, clk) BEGIN 
    IF rising_edge(clk) then 
     IF (ybuff /= y) then 
      enable <= '0'; 
      CASE y IS 
       .... 
       .... 

ような何かを行うことができ、一度状態変化あたり更新する場合。これは少しハッキングされています(あなたの状態ロジックや更新信号はありません)

私は、現在のaddressallの更新が正しい方法ではないことに同意します。彼はあなたがこれを修正するために変数を使うことができると言ったように、あるいはあなたが本当にそれを保つことを望むならば、アドレスを更新してより奇妙なものをより明確かつ制御する別個のプロセスブロックに置くべきです。今(と私は2番目掲載単一のアップデータで)あなたは常に(あなたの状態マシンの後ろと1サイクル)あなたのポインタの背後にある一つのアドレスになります

0

考慮すべきいくつかの追加のポイント:

1)がありますイン/アウトアドレスがどのようにインクリメントされるかの不一致:addressin<=addressin+"01";およびaddressout<=addressout+1;。これらの割り当ての動作は、オペランドの信号タイプに依存します。そのため、実際の問題ではないかもしれませんが、情報が役立つのはこのためです。

2)アドレス信号の変更は、yをオンに切り替えることに直接関係していると仮定することは比較的安全です。これは、このプロセスの機密性リスト内の唯一の信号です。波形ビューアのアドレスの横にあるyの値を調べましたか?

3)パウロは、このことを示唆したが、私はちょうどあなたがこの回路は)同期(「クロックさ」にしたいかもしれ理由を明確にしたいです。感度リストにクロックがなければ、このプロセスはyの変更にのみ影響を受けます。したがって、このプロセスによって暗黙任意のメモリ素子は、クロックの完全無知なり、が入力yを変更することによってのみ影響されます。リードポインタを進める言い換えれば、yidlereed状態間トグルする必要があります。ロジックは、読み取りポインタreed状態がy上に存在するすべてのクロックサイクルを進める必要がある場合は、これが意図されたかどうかを判断する必要がありますか。メモリ要素が指定されたクロックを受け取らないのは非伝統的かもしれません。なぜなら、クロックは静的タイミング解析を簡素化するために特殊な処理を受けるからですが、言語によって禁止されているわけではありません(下流のツールについても同じことを約束できません)。一般的に

、あなたはVHDLのニュアンスのいくつかを達成して把握しようとしている何が良いアイデアを持っているように聞こえるので、次のステップは、さらに予期しない動作を分離することです。より多くのコードはいくつかの潜在的な問題を排除するのに役立ちますが、おそらく、仮定を同時にテストし、再現可能な例を提供する最良の方法は、予期しない動作を示すテストベンチを作成することです。

たとえば、ここにあなたのプロセスのクロックドコピーを行使するためにテストベンチがあります。

Library ieee; 
Use ieee.std_logic_1164.all; 
Use ieee.numeric_std.all; 

Entity test Is 
End Entity; 

Architecture main of test Is 
    Signal enable, clock : std_logic := '0'; 
    Signal addressin, addressout, addressall : unsigned(0 to 1) := "00"; 
    Type op_t is (reed, idle, rite); 
    Signal y : op_t; 
    Signal done : boolean; 
Begin 
    clocks: process 
    begin 
     if not done then 
      clock <= not clock; 
      wait for 0.5 ns; 
     else 
      wait; 
     end if; 
    end process; 

    PROCESS (clock, y) 
    BEGIN 
    if rising_edge(clock) then 
    CASE y IS 
     WHEN idle=> 
      enable<='0'; 

     WHEN reed=> 
      enable<='0'; 
      IF (addressin="00" OR addressin="01" OR addressin="10") THEN 
       addressin<=addressin+1; 
      ELSE 
       addressin<="00"; 
      END IF; 
      addressall<=addressin; 

     WHEN rite=> 
      enable<='1'; 
      IF (addressout="00" OR addressout="01" OR addressout="10") THEN 
       addressout<=addressout+1; 
      ELSE 
       addressout<="00"; 
      END IF; 
      addressall<=addressout; 

    END CASE; 
    end if; 
    END PROCESS; 

    main: Process 
    Begin 
     y <= idle; 
     wait for 1 ns; 
     y <= reed; 
     wait for 1 ns; 
     assert addressall = "00"; 
     wait for 1 ns; 
     assert addressall = "01"; 
     wait for 1 ns; 
     assert addressall = "10"; 
     wait for 1 ns; 
     assert addressall = "11"; 
     y <= idle; 
     wait for 1 ns; 
     done <= true; 
     wait; 
    End Process; 

End Architecture; 
関連する問題