1

Verilog コードの一部を次に示します。私はそれが 3 つの同一の結果を返し、すべて 8 ビット表現の -1 を返すことを期待しています。

module trivial;

    reg we;
    reg [7:0] c;

    initial
      begin
        c = 8'd3;
        we = 1'b1;
        $display ("res(we) = %d", (we ? (-$signed(c)) / 8'sd2 : 8'd0));
        $display ("res(1)  = %d", (1'b1 ? (-$signed(c)) / 8'sd2 : 8'd0));
        $display ("res = %d", (-$signed(c)) / 8'sd2);
      end

endmodule

簡単に言えば、私が持っている標準のバージョン (1364-2001) では、セクション 4.1.5 で、除算はゼロに向かって丸められるため、-3/2=-1 と述べています。また、セクション4.5では、演算子記号はオペランドのみに依存すると述べています(編集:ただし、「自己決定式」の場合のみ。標準の記号の部分と幅の部分を一緒に読む必要があることがわかります)。したがって、除算を含む部分式は、おそらくそれが使用されるコンテキストの影響を受けないはずであり、$signed を含む部分式についても同様です。それで、結果はすべて同じになるはずですか?

3 つの異なるシミュレーターが私に同意しません。そして、それらのうちの2つだけが互いに同意します。明らかな原因は、予想される符号付き除算ではなく、符号なし除算が使用されていることです。(-3=253、253/2=126.5)

シミュレーターのいずれかが正しいかどうか、またその理由を教えてください。(下記参照)明らかに何かが欠けているに違いありませんが、何かお願いします。どうもありがとう。編集:欠けていたものについては上記を参照してください。Icarus にはバグがあり、他の 2 つのシミュレーターは正しいと思います。

注意: 三項選択の未使用の値は、符号付きか符号なしかにかかわらず、何の違いもないようです。編集:これは正しくありません。おそらく、署名された番号で再試行する前に、変更したテストを保存するのを忘れていました

Modelsim のアルテラ版:

$ vsim work.trivial -do 'run -all'
Reading C:/altera/12.1/modelsim_ase/tcl/vsim/pref.tcl

# 10.1b

# vsim -do {run -all} work.trivial
# Loading work.trivial
# run -all
# res(we) = 126
# res(1)  = 126
# res =   -1

GPL カバー

GPLCVER_2.12a of 05/16/07 (Cygwin32).
Copyright (c) 1991-2007 Pragmatic C Software Corp.
  All Rights reserved.  Licensed under the GNU General Public License (GPL).
  See the 'COPYING' file for details.  NO WARRANTY provided.
Today is Mon Jan 21 18:49:05 2013.
Compiling source file "trivial.v"
Highest level modules:
trivial

res(we) = 126
res(1)  = 126
res =   -1

イカルス Verilog 0.9.6

$ iverilog.exe trivial.v && vvp a.out
res(we) = 126
res(1)  =   -1
res =   -1
4

1 に答える 1

2

NCSIMは以下を提供します:

res(we) = 126
res(1)  = 126
res     =  -1

しかし、マルチプレクサへのすべての入力が署名されている場合、次のようになります。

$display ("res(we) = %d", (we ?   (-$signed(c)) / 8'sd2 : 8'sd0)); //last argument now signed
$display ("res(1)  = %d", (1'b1 ? (-$signed(c)) / 8'sd2 : 8'sd0));
$display ("res     = %d",         (-$signed(c)) / 8'sd2);

res(we) =   -1
res(1)  =   -1
res     =   -1

符号なしの数値を使用して算術演算を実行する場合、算術演算は符号なしとして実行されることを思い出してください。ビット選択を使用する場合も同じことが起こります。

reg signed [7:0] c;
c = c[7:0] + 7'sd1; //<-- this is unsigned

例では、マルチプレクサは1行の式の一部であり、これは最適化のために論理的にフラット化されていると想定しているため、すべての引数の符号付き/符号なしが考慮されます。

于 2013-01-22T10:17:11.483 に答える