1

コードが正しく動作しない理由を判断するのに苦労しています。3 ビットのオペコードで ALU を作成しようとしています。

1 つを除くすべての条件が適切に機能しません。オペコード 011 (SEQ)。if(a==b) z<='0' および output<='0' として定義されます。a と b は入力で、z はゼロ フラグです。私は、次の VHDL コードでこの機能を取得することを期待していました

....
    BEGIN

    result <= dummy_result;

    PROCESS (a, b, op) 

        VARIABLE carry: STD_LOGIC:='0';

         --DEFINE ALIAS TO SEPERATE ALU-OP SIGNAL
        alias NEG_TSEL      : STD_LOGIC IS op(2);
        alias ALU_SELECT    : STD_LOGIC_VECTOR(1 downto 0) IS op(1 downto 0);
    BEGIN
         if ALU_SELECT="11" THEN

                if NEG_TSEL='0'  THEN   -- SEQ

                    if a = b THEN
                        dummy_result <="00000";
                    end if;

                elsif NEG_TSEL='1' THEN     --SCO

                    cout <= '1';
                    result <= "XXXXX";


                end if;


        elsif ALU_SELECT="00" THEN...

このコードでは、op = 011 の場合、結果は常にゼロに設定されます。

コードを次のように変更すると:

            .....
            if a = b THEN
                dummy_result <="00000";

            else
                dummy_result <= "10101";
            end if;
.....

正常に動作しますが、結果を変更してはならないため、「10101」ベクトルの代わりに「dummy_result <= dummy_result;」に変更します。しかし、元のケースと同じ結果が得られます。

助言がありますか?私は何か間違ったことをしていますか?

4

2 に答える 2

0

ここでの意図は、別の方法で割り当てられない限り、dummy_result は「結果」の以前の値を保持することを意図していることです。残念ながら、このユニットはクロックなしの組み合わせプロセスとして実装されています。

したがって、このユニットではストレージを確実に実装することはできません。
したがって、このユニットの外部で実装する必要があります。
ほぼ間違いなく、すでにそうです。クロックプロセスとして実装されたレジスタ内。

そのため、そのレジスタの出力を新しい入力ポート「prev_result」として戻し、デフォルトの割り当てをダミー_結果に使用します。これにより、これまでに見つかった特定の障害だけでなく、「dummy_result」への他のすべての割り当てが失われ (他にもあります)、「結果」の古い値が同期的に保持されます。

    PROCESS (a, b, op, prev_result) 
       -- declarations here
    BEGIN
       -- default assignment
       dummy_result <= prev_result;

       if ALU_SELECT="11" THEN
          if NEG_TSEL='0' THEN    -- SEQ
             if a = b THEN
                dummy_result <="00000";
             end if;
       ...
    END PROCESS;

ALU をクロック プロセスにするためにデザインを再構築する方がよいと思いますが、そうしないように指示されている場合は、この (または同様の) ソリューションを採用する必要があります。

于 2013-02-05T18:05:05.207 に答える
0

あなたのコードに関する私の問題は次のとおりです。

result個人的には、すべてのサイクルで 、cout、および に何かを出力する必要があると思いますzero。現在、常に に出力しますがzero、条件付きで他の 2 つのポートにのみ出力します。これはおそらくラッチを作成していますが、これはおそらくあなたが望んでいるものではありません。したがって、たとえば、SCO 操作は にも何かをプッシュする必要がcoutあり、SCO 操作はdummy_resultシグナルに何かをプッシュする必要があります。

減算の実装が期待どおりに機能していません。

when "110" => -- SUB
    tmp_b <= NOT b;
    carry := '1';

    for i in 0 to 4 loop
        dummy_result(i) <= carry XOR a(i) XOR tmp_b(i);
        carry := (a(i) AND tmp_b(i)) OR (tmp_b(i) AND carry) OR (carry AND a(i));
    end loop;
    cout <= carry;

tmp_b信号です。そこで発生するロジックは、順次ではなく、このプロセスの他のすべてと同時に発生します。あなたはおそらくそれを変数にしたいと思うでしょうcarry


また、case ステートメント (if チェーンとは対照的) についてもお知らせしたいと思います。コードは次のようになります。

PROCESS (a, b, op)
    VARIABLE carry: STD_LOGIC:='0';
BEGIN

    case op is
        when "011" => -- SEQ
            dummy_result <= "00000";

        when "111" => -- SCO
            cout <= '1';

        when "000" => -- AND
            dummy_result <= a AND b;

        ...

        when others =>
            dummy_result <= "00000";
            cout <= '0';
    end case;
end process;

元の問題に戻ると、SEQ元のコードは次のようになります。

when op = "011" =>
    if a = b then
        dummy_result <= "00000";
    end if;

ここでの問題は、前述したように、これがラッチである可能性が高いことです。a /= b のときに期待される値を出力する必要がありますが、それは単なる ではありませんdummy_result <= dummy_result。それを物理的なワイヤやチップにプッシュした場合、それはどうなると思いますか?

代わりに、最後のダミー結果の値をこのエンティティに渡すか、特定の操作が結果の値を保持する必要がある場合は、「00000」を出力し、前の値を保持しているものは何でも (登録)、更新しないでください。

于 2013-02-04T05:18:21.400 に答える