18

そのため、何日も私を悩ませていたバグは、False に評価されて True に評価されるはずだったコードのセクションであることが判明しました。私の最初のコードは次のようになりました:

if(~x && ~y) begin
    //do stuff
end

つまり、x が NOT ONE で y が NOT ONE の場合は処理を行います。デバッガーをステップ実行すると、x が 1 であるにもかかわらず、if ステートメントの式が TRUE になり、後続のコードが実行されることに気付きました。

ただし、ステートメントを次のように変更すると:

if(x == 0 && y == 0) begin
//do stuff
end

また、試しました:

if(!x && !y) begin
//do stuff
end 

if ステートメント内のコードは評価されませんでしたが、これは予期された動作でした。~ はビットごとの否定であり、 ! 論理否定ですが、(~x && ~y) と (!x && !y) は同じものに評価されるべきではありませんか? 残念ながら、コードベースが大きすぎるため、ここに貼り付けることはできませんが、コードを意図したとおりに動作させるために行った変更はこれだけです。ありがとう。


以下のコメントの 1 つに対応して、この動作をテストするテスト ケースを作成しました。

`timescale 10ns/1ns

module test_negation();
        integer x, y;

    initial begin
        x = 1; y = 0;

        if(~x && ~y) begin
            $display("%s", "First case executed");
        end

        if(!x && !y) begin
            $display("%s", "Second case executed");
        end

        if(x == 0 && y == 0) begin
            $display("%s", "Third case executed");
        end
    end endmodule

そして不思議なことに、私が観察した元の動作を確認するために、「最初に実行されたケース」が出力されます。

4

2 に答える 2

9

分かりました。上記のコードの変数 "x" は Verilog 整数 ( integer x;) でした。ただし、整数変数は Verilog では 32 ビットの整数として表されます。したがって、私が観察したように x は「1」でしたが、~x は「0」ではなく、「111111111111111111111111111110」になります! したがって、最初のケースが実行されたのは当然のことです。私のせいです。すべての答えをありがとう。

于 2013-05-07T18:02:01.040 に答える
8

~はビット単位の演算子であり、引数の反転を返します。

!は論理演算子で、1 ビットを返します。

例:

reg [7:0] bit_wise, logic_op;
initial begin
  bit_wise = ~8'hA1; // bit_wise == 8'h5E
  logic_op = !8'hA1; // logic_op == 8'b00
  $display("bit_wise:%h logic_op:%h", bit_wise, logic_op); // bit_wise:5e logic_op:00
end

あなたの例:

if(~x && ~y) begin
    //do stuff
end

事実上、次と同じです。

if(x!='1 && y!='1) begin // '1 means the with of x all 1s and the with of y all 1s
    //do stuff
end

一般に、最適なコーディング スタイルは、if ステートメント内で論理演算子を使用することです。データ代入操作では、ビット単位の演算子のみを使用してください。

于 2013-05-07T17:50:46.830 に答える