0

ハザード検出や分岐予測などを備えたスーパースカラー風のパイプライン CPU の動作を説明および実証するために、VHDL を学習しています。

私は小さく始めているので、練習のために、次のような非常に単純な「電卓」のデザインを作成してみました。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_signed.all;

entity calculator is
    port(
        in_A  : in  std_logic_vector(3 downto 0);
        in_B  : in  std_logic_vector(3 downto 0);
        add : in std_logic;
        sub : in std_logic;
        out_C : out std_logic_vector(3 downto 0)
    );
end entity calculator;

architecture RTL of calculator is
    signal next_output : std_logic_vector(3 downto 0);
begin
    process(in_A, in_B, add, sub)
        variable temp_x, temp_y, temp_z : integer;
    begin

        temp_x := conv_integer(in_A);
        temp_y := conv_integer(in_B);

        if(add = '1') and (sub = '0') then
            temp_z := temp_x + temp_y;
            next_output <= std_logic_vector(to_unsigned(temp_z, 4));
        elsif(add = '0') and (sub = '1') then
            temp_z := temp_x - temp_y;
            next_output <= std_logic_vector(to_unsigned(temp_z,4));
        else
            temp_z := 0;
            next_output <= std_logic_vector(to_unsigned(temp_z,4));
        end if;

        out_C <= next_output;
    end process;
end architecture RTL;

ただし、ここに示されているように、入力が変更された後にのみ出力が設定される理由がわかりません (私が推測するテストベンチコードは無関係です):

モデルシム

出力を正しく、遅滞なく利用できるようにするために何をすべきか知りたいです。add が 1 の場合、出力は入力に応じて遅滞なく設定する必要があります (まあ、私が書いたようにしたいのですが、そうではありません :) )

また、出力がいつフリップフロップに記憶されるのか、説明を書いた方法でフリップフロップに記憶されるかどうかを誰かが説明してくれませんか。

また、私を助けるためのすべてのアドバイス、批判、およびガイダンスに本当に感謝しています。これは単純な ADD/SUB 計算機にすぎません。約 2 か月で命令セットを含むプロセッサ全体を説明する必要があります。私が受けたクラスは役に立たなかったので、良い学習チュートリアルを教えてくれるかもしれません:(

前もって感謝します!:)

4

2 に答える 2

1

<=中間シグナルへのシグナルの割り当ては、プロセスの同じ実行では表示されないため、新しい値が表示next_outputされるまでプロセスをもう一度実行する必要があるため、遅延が発生します。out_C <= next_output

out_C <= next_outputDavid Koontz が書いたように、プロセスの外に移動することができます。

別の方法としては、すべての中間信号と変数のリッジを取得し、IEEE 標準パッケージのみを使用し numeric_stdて、Synopsys 独自のパッケージをスキップすること を含め、コードを以下のように書き直すことですstd_logic_signed

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
...
architecture RTL of calculator is
begin
    process(in_A, in_B, add, sub)
    begin
        if(add = '1') and (sub = '0') then
            out_C <= std_logic_vector(signed(in_A) + signed(in_B));
        elsif(add = '0') and (sub = '1') then
            out_C <= std_logic_vector(signed(in_A) - signed(in_B));
        else
            out_C <= std_logic_vector(to_signed(0, out_C'length));
        end if;
    end process;
end architecture RTL;

Davidが同様の提案をしたのを見ましたが、とにかく私のものを手に入れることができます:-)

于 2015-02-12T18:39:25.913 に答える