たとえば、reg [7:0] myReg
があるとします。それに値-8'D69
を割り当てます
Verilogは2の補数として保存するので、次のように保存する必要があります。
10111011
私が今持っている問題は、それに対して操作を実行するかどうかです、myReg/2
-34と評価されますか?または、10111011を187に変換してから除算を実行し、93を返しますか?
-8d69
は単なるビットパターンであることを覚えておく必要があります。 regはビットパターンを保持するタイプです。これは、/
に符号付きまたは符号なし算術を実行するように指示する変数のタイプです。
これが合成のためであり、分周器を避けようとすることを念頭に置いている場合は、本当に符号付き分周器を避けようとする必要があります。 >>> 1
を使用すると、合成が小さくなる可能性があります
reg [7:0] a;
reg signed [7:0] b;
reg [7:0] c;
reg signed [7:0] d;
initial begin
a = -8'd69 ;
b = -8'd69 ;
c = -8'd69 ;
d = -8'd69 ;
#10ns;
a = a/2 ;
b = b/2 ;
#10ns;
$display("a : %8b, %d", a, a);
$display("b : %8b, %d", b, b);
$display("c >>>1 : %8b, %d", c>>>1, c>>>1);
$display("d >>>1 : %8b, %d", d>>>1, d>>>1);
end
与える:
a : 01011101, 93
b : 11011110, -34
c >>>1 : 01011101, 93
d >>>1 : 11011101, -35
>> x
x桁右にシフトします。>>> x
右にx桁シフトしますが、符号付きの型の場合は符号拡張します。
注:/2
も私の例では切り上げられます。>>>
は切り捨て/切り捨てられます。
たとえば、reg [7:0] myRegとすると、値-8'D69を割り当てます。
これは実際には符号付きの数値ではなく、正の定数に適用される単項否定で構成される式です。式が-8'd130
の場合、結果はオーバーフローします。符号付き定数は、8'sd69
または単に69
として宣言されます。
私が今持っている問題は、それに対して操作を実行するかどうかです、myReg/2
myReg
は符号なしなので、式の結果も符号なし*になります。結果に署名する必要がある場合はallオペランドに署名する必要があります。これを実現するには、いくつかの方法があります。
//Declare the reg as signed and divide by a signed value
reg signed [7:0] myReg;
assign result = myReg/2;
//Use system functions
assign result = $signed(myReg)/2;
*式の評価に関する完全な規則ははるかに複雑ですが、すべてのオペランドが符号付きでない限り、基本的に、式の結果は符号なしです。
reg signed [7:0] a;
reg [7:0] b;
initial
begin
result = a; //Signed
result = a * a; //Signed
result = a * 10; //Signed
result = $unsigned(a); //Unsigned
result = a[0]; //Unsigned
result = a[7:0]; //Unsigned
result = {a,a}; //Unsigned
result = 10{a}; //Unsigned
result = a + b; //Unsigned
result = a * b; //Unsigned
end
追加します1.デフォルトでは、データ型bitおよびregは符号なしです。 2.データ型int、integer、longint、shortint、およびbyteは、デフォルトで署名されています。 3.これらのデータ型はすべて、デフォルトを変更するために、署名付きまたは署名なしの修飾子を取ることができます。
したがって、-8'D69をmyRegに割り当てると、暗黙的に187に変換されます。次に、myReg/2 = 187/2 = 93、符号なしです。 SystemVerilogが式と代入で暗黙の型変換をいつ、どのように行うかを理解することが重要です。