- 締切済み
verilog 符号付加減算(最上位符号拡張)について教えてください
何度も申し訳ないです。 質問させてください 2の補数形式の加減算 q = a + b において、a[15:0] b[15:0]であるとすると q はオーバーフローを考えてq= [16:0] となります。 そしてaとbの最上位ビットが符号となるためa[15]とb[15]の組合せを場合わけして q[16]の最上位bitに出力する必要があるのではないかと考えています。 なので、以下のように記述したのですが…うまくいっていません。 ********************************************* module fulladder_16(a,b,q); input [15:0] a,b; output [16:0] q; wire [15:0] cin,out_q; reg s; //フルアダーモジュールをインスタンス fulladd add0(.a(a[0]),.b(b[0]),.cin(1'b0),.q(out_q[0]),.cout(cin[0])); fulladd add1[15:1](.a(a[15:1]),.b(b[15:1]),.cin(cin[14:0]),.q(out_q[15:1]),.cout(cin[15:1])); //aとbの最上位ビットの組合せを分けて、sに代入 always@(a[15] or b[15] or cin[15]) begin if(a[15] == 1) if(b[15] == 1) s = 1; else if(b[15] == 0) if(cin[15] == 1) s = 0; else s = 1; else if(a[15] == 0) if(b[15] == 1) if(cin[15] == 1) s = 0; else s = 1; else if(b[15] == 0) s = 0; end //最後に出力 q をbit拡張 assign q = {s,out_q}; endmodule //fulladder module fulladd(a,b,cin,q,cout); input a,b,cin; output q,cout; assign q = a^b^cin; assign cout = (a & b)|(b & cin)|(cin & a); endmodule ************************************************ これでシミュレーションを行ったところ a = 0000000000000000 b = 0000000000000000 q = xxxxxxxxxxxxxxxxx0000000000000000 a = 0001000100010001 b = 0011010100100100 q = xxxxxxxxxxxxxxxxx0100011000110101 a = 0010001000100010 b = 0101111010000001 q = xxxxxxxxxxxxxxxxx1000000010100011 a = 0011001100110011 b = 1101011000001001 q = xxxxxxxxxxxxxxxxx0000100100111100 a = 0100010001000100 b = 0101011001100011 q = xxxxxxxxxxxxxxxxx1001101010100111 a = 0101010101010101 b = 0111101100001101 q = xxxxxxxxxxxxxxxxx1101000001100010 a = 0110011001100110 b = 1001100110001101 q = xxxxxxxxxxxxxxxxx1111111111110011 a = 0111011101110111 b = 1000010001100101 q = xxxxxxxxxxxxxxxxx1111101111011100 a = 1000100010001000 b = 0101001000010010 q = 111111111111111111101101010011010 a = 1001100110011001 b = 1110001100000001 q = 111111111111111110111110010011010 a = 1010101010101010 b = 1100110100001101 q = 111111111111111110111011110110111 となりうまく最上位ビットが出力してくれませんでした。 どなたか教えてください…(TT)
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- irija_bari
- ベストアンサー率73% (70/95)
フルアダー モジュールのインスタンス化部分だけ書きます。 一工夫が必要なのは最上位ビットだけであとは普通の全加算器と同じです。 私は、 >fulladd add1[15:1](.a(a[15:1]),.b(b[15:1]),.cin(cin[14:0]),.q(out_q[15:1]),.cout(cin[15:1])); のような記述方法を知らないため長々と書いていますが、sususun さんの記述方法で あれば add1 ~ add14 は 1 行で記述できるのではないでしょうか。 ==== begining of code ==== fulladd add0(.a(a[0]),.b(b[0]),.cin(1'b0),.q(q[0]),.cout(cin[0])); fulladd add1(.a(a[1]),.b(b[1]),.cin(cin[0]),.q(q[1]),.cout(cin[1])); fulladd add2(.a(a[2]),.b(b[2]),.cin(cin[1]),.q(q[2]),.cout(cin[2])); fulladd add3(.a(a[3]),.b(b[3]),.cin(cin[2]),.q(q[3]),.cout(cin[3])); fulladd add4(.a(a[4]),.b(b[4]),.cin(cin[3]),.q(q[4]),.cout(cin[4])); fulladd add5(.a(a[5]),.b(b[5]),.cin(cin[4]),.q(q[5]),.cout(cin[5])); fulladd add6(.a(a[6]),.b(b[6]),.cin(cin[5]),.q(q[6]),.cout(cin[6])); fulladd add7(.a(a[7]),.b(b[7]),.cin(cin[6]),.q(q[7]),.cout(cin[7])); fulladd add8(.a(a[8]),.b(b[8]),.cin(cin[7]),.q(q[8]),.cout(cin[8])); fulladd add9(.a(a[9]),.b(b[9]),.cin(cin[8]),.q(q[9]),.cout(cin[9])); fulladd add10(.a(a[10]),.b(b[10]),.cin(cin[9]),.q(q[10]),.cout(cin[10])); fulladd add11(.a(a[11]),.b(b[11]),.cin(cin[10]),.q(q[11]),.cout(cin[11])); fulladd add12(.a(a[12]),.b(b[12]),.cin(cin[11]),.q(q[12]),.cout(cin[12])); fulladd add13(.a(a[13]),.b(b[13]),.cin(cin[12]),.q(q[13]),.cout(cin[13])); fulladd add14(.a(a[14]),.b(b[14]),.cin(cin[13]),.q(q[14]),.cout(cin[14])); fulladd add15(.a(~a[15]),.b(~b[15]),.cin(cin[14]),.q(q[15]),.cout(out_q)); assign q[16] = ~out_q; //add1 ~ add14 は以下のように記述する? //fulladd add1_14[14:1](.a(a[14:1]),.b(b[14:1]),.cin(cin[13:0]),.q(q[14:1]),.cout(cin[14:1])); ==== end of code ====
- Tacosan
- ベストアンサー率23% (3656/15482)
やりたいことがよくわからんのですが.... 2個の符号付き 16bit 整数を受け取って, 何bit の符号付き整数を出すんでしょうか? 17bit でよければ full adder の carry out が 最上位になりますよね. 16bit で出力し, オーバーフローを検出したいなら確か carry out と 16bit 目の xor かなんかでわかったような気がします.