0

私はVHDLが初めてで、バイナリからBCDへのコンバーターを作成しようとしています。インターネットで検索しましたが、今はそれとVHDLを理解するために自分で作成しようとしています。これが私のプログラムです:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Binary_to_BCD is
--generic(n: integer := 2);
    Port ( data     : in unsigned (7 downto 0);
              bcdout : out unsigned (11 downto 0));
end Binary_to_BCD;

architecture Behavioral of Binary_to_BCD is
    -- Inicio el proceso de conversion
    begin
    convert : process (data) is
        variable i : integer := 0;
        variable bin : unsigned (7 downto 0) := data;
        variable bcd : unsigned (11 downto 0) := to_unsigned(0, 12);
        begin
        -- Repito por el numero de bits
        for i in 0 to 7 loop
            bcd := bcd sll 1;       -- Desplazo un lugar a la izquierda el BCD
            bcd(0) := bin(7);       -- Ingreso el nuevo bit al BCD
            bin := bin sll 1;       -- Desplazo el bit que saque antes a la izquierda

            -- Compruebo cada grupo de 4 bits del BCD, si se pasa de 4 le sumo 3
            if(bcd(11 downto 8) > "0101") then
                bcd(11 downto 8) := bcd(11 downto 8) + "0011";
            end if;

            if(bcd(7 downto 4) > "0101") then
                bcd(7 downto 4) := bcd(7 downto 4) + "0011";
            end if;

            if(bcd(3 downto 0) > "0101") then
                bcd(3 downto 0) := bcd(3 downto 0) + "0011";
            end if;

        end loop;
        bcdout := bcd;
    end process convert;
end Behavioral;

66行目でこのエラーが発生します。これはbcdout := bcd;次のとおりです。

Signal 'bcdout' bcdout is at left hand side of variable assignment statement.

unsignedビットと算術演算を回転させる必要があるため、代わりに使用したWebと本を読んだ後std_logic_vector、それでも合成しません。

と に変更しようunsignedinteger:=まし<=たが、何も機能しません。それは非常にばかげているはずですが、私は気づいていません。事前にどうもありがとうございました。

4

3 に答える 3

2

当面の問題は、エラーメッセージや他の回答が指摘するように、シグナル:=のシグナル割り当ての代わりに変数割り当てを誤って使用することです。<=bcdout

ただし、関数に関するコメントで明らかにされているように、VHDL プロセスのどこにいるかについての根本的な混乱があります。

この混乱に対する一般的なアプローチは、「VHDL はプログラミングではなくハードウェア設計に使用される」ことを指摘することです。これは、いくつかの点では有用ですが、人為的に原始的で非常に低レベルの VHDL の使用につながる可能性があり、実際には VHDL を妨げています。

「ソフトウェアの方法」で VHDL を書くことはうまくいきますが、C を学ぶだけで理解できるよりも、ソフトウェアとハ​​ードウェアのエンジニアリングに関するより広い視野が必要です。

上記のコードはおそらく合成可能であり、おそらく機能しますが、ほとんどの場合、あなたが思っていることは実行されません。ただし、完全に異なるアプローチではなく、いくつかの小さな変更が必要です。

いくつかのポインターが役立つ場合があります。

C 関数に相当する VHDL は VHDL 関数です。
VHDL プロシージャに相当する C は void 関数です。
(はい、C にはプロシージャがあります。それは、それらを void 関数と呼んでいるだけです! :-)
VHDL プロセスに相当する C は ... プロセスです。つまり、pthreads または fork/join を使用しない限り、C プログラム全体です。

これで、VHDL が C 言語よりもはるかに合理化された方法で並列計算用に設計されていることがわかります。プロセスはビルディング ブロックに過ぎず、シグナルはプロセス間のメッセージ パッシングまたは共有ストレージの信頼性の高い形式です。

したがって、プロセス内では、(ある程度) ソフトウェア用語で考えることができますが、プロセスを関数であるかのように「呼び出す」ことを考えるのは大きな間違いです。この Q&Aを以前にご覧になったことがある場合は申し訳ありませんが、VHDL プロセスのセマンティクスとプロセス間の信号の使用を理解するのに役立ちます。

ここで、コードの特定の問題について:

1) 非同期です。つまり、クロックされていません。つまり、入力のグリッチにどのように応答するかを保証することは...困難であり、結果がいつ有効になるかを知ることは必要以上に困難です。C でのグローバル変数の制御されていない使用と同様に、ベスト プラクティスではありません。

そのため、より安全で分析しやすい設計を実現するために、時間制御されたプロセスに移行してください。これは、後で速度を上げるためのステップでもあります。しかし今のところ、VHDL クロック処理プロセスをイベント ループまたはおそらく C の割り込みハンドラーと考えてください。指示されるとウェイクアップし、(事実上) ゼロ タイムで実行され、次回まで sleep() されます。

convert : process (clk) is
    variable bin : unsigned (7 downto 0);
    ...
begin
    if rising_edge(clk) then
       bin := data;
       for i in 0 to 7 loop
          ...
       end loop;
    end if;
    bcdout <= bcd;
end process convert;

2) ループが展開され、多くのハードウェアが生成されます。これは問題にならないかもしれません: (ソフトウェアの同等物とは異なり!) 妥当な速さで結果を返します. ..

3) これは実際にはオリジナルの最大の問題です: datatoの割り当てbinは実際にはプロセス変数の初期化であり、割り当てではありません! これは t=0 で 1 回だけ実行されます... これが、これまでに見た誤操作の原因である可能性が最も高いです。

上記の変更されたクロックの例dataでは、プロセスが起動されるたびに、つまりすべてのクロック サイクルで最新の値が割り当てられるため、必要な処理が実行される可能性が高くなります。

4) 些細な問題: "i" の宣言は冗長であり、実際にはループ ステートメントによって作成された新しい暗黙的な "i" によって隠されています。この暗黙的な宣言は、ループの境界から明示的に型を取得するため、明示的な宣言よりも安全で優れています。が 16 ビット型のfor(int i; i<= 100000; i++)場合に何が起こるか想像してみてください...int

于 2013-06-16T12:04:54.183 に答える
0

bcdout はシグナルであり、変数代入演算子 := を使用しています

行を置換

bcdout := bcd;

bcdout <= bcd;

他に問題があるかどうかを確認するためにコンパイルしようとはしていませんが、それはあなたの質問に答えるはずです.

于 2013-06-16T10:35:33.097 に答える
0

うーん、変。bcd を変数ではなくシグナルにしてみましたか?

ただし、ここでの主な問題は、for ループとシーケンシャル ロジックを使用して、「ソフトウェア」の方法で VHDL を記述しようとしていることだと思います。通常、これはハードウェアの説明を書くべき方法ではありません。同時割り当てを含む組み合わせロジック、またはクロックの立ち上がりエッジで処理を行うシーケンシャル ロジックのいずれかを使用する必要があります。実装しようとしているのは組み合わせ回路のようです。その場合、10 進数ごとに個別の同時割り当てを記述する必要があります。並行信号割り当ての例については、 http://www.csee.umbc.edu/portal/help/VHDL/concurrent.htmlを参照してください。おそらく、選択された信号割り当てまたは条件付き信号割り当てのいずれかを使用したいと思うでしょう。

于 2013-06-15T22:13:55.910 に答える