2016-10-19 10 views
1

これは私が書いたシンプルなコードです。私は122116を得ました。しかし、 'outt'の幅を33ビット([32:0])に変更すると、コードがうまく動作し、正解-140028を返すようです。この行動の理由は何ですか?どのようにしてレジスタのビット幅を正しく決定できますか?

`timescale 1ns/1ps 

module valu_parser(clk,outt); 

input clk; 
reg signed [31:0] r_1; 
reg signed [31:0] r_2; 
output reg signed [31:0] outt; 

initial begin 
    r_1 = -47938; 
    r_2 = -150096; 
end 

always @ (posedge clk) begin 
    outt <= ((r_1 + r_2)* 11585 + 8192)>>>14; 
end 
endmodule 

答えて

-1

あなたは11585で-198034(R1 + R1)を掛けるときは、結果の最上位ビットを使用すると、32ビット符号付きの値を有する場合0(OUTT [31])、その開始が正である持っている答えでは、持っています肯定的な結果。あなたが33ビットのためにそれを変更するとき、あなたの最高ビットは1(outt [32])であり、結果は負の値であり、正しい答えを持っています。

1

r_1とr_2が定数ではないと仮定して、少なくとも33ビット(右シフトが33ビットを使用する前の一時的な結果)を必要とする演算を実行し、理論的には32 + "被乗数定数のサイズ" 。

コードで生成されるハードウェアについて考えると、ハードウェアが最初に乗算を行い、続いて右シフトが行われるように、これらのビットを一時的にどこかに格納する必要があります。

これはトリックを行いますが、最初はもっと多くのレジスタを生成します。このモジュールを使用して定数を生成する場合は、定数をハードコーディングすることをお勧めします。

module valu_parser(clk,outt); 

input clk; 
reg signed [31:0] r_1; 
reg signed [31:0] r_2; 
reg signed [32:0] temp; 
output reg signed [31:0] outt; 

initial begin 
    r_1 = -47938; 
    r_2 = -150096; 
end 

always @ (posedge clk) begin 
    temp <= ((r_1 + r_2)* 11585 + 8192); 
end 

assign outt = temp>>>14; 

endmodule 

ここではコンセプトを見ることができます:https://www.edaplayground.com/x/3BXy

+0

本当にありがとうございました! – RONEY

1

式では、Verilogは計算に使用するビット数を決定する必要があります。

演算子+*演算子の結果、文脈決定式となります。式F = A + B;の場合、使用されるビット数は最大でF,A、およびBです。通常は、FABを追加した結果を格納するのに十分な幅であることを保証するため、これは正常に機能します。同様に、式F = A * B;と同様に、通常FABを乗算した結果を格納するのに十分な幅であることを保証するので、正常に動作します。

ただし、シフト右演算子を追加することで、シフト演算子の左辺の式を計算するために実際に必要なビット数よりも狭い変数を割り当てることができました。 Verilogが計算に使用するビット数は、outt,r_1,r_2,11585および8192の幅の最大値です。これらはすべて32ビット幅(11585および8192を含む)なので、32ビットが計算に使用されます。あなたが発見したように、32ビットでは不十分ですが、あなたが選んだ値では33ビットです。他の値では、33ビットでも十分ではありません。完全に柔軟なソリューションを実現するには、乗算に66ビット(32 + 32 + 1 + 1) - 32ビット+ 32ビットを加え、各加算に1ビット増加する必要があります。

r_1および/またはr_2を広げたり、中間値を使用したりすることができます(ここでのヒダの答えを参考にしてください)。

+0

ありがとうございました!それはそれをクリアする! :) – RONEY

関連する問題