プロが教えるわが家の防犯対策術!

何度も申し訳ないです。
質問させてください
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)

A 回答 (2件)

フルアダー モジュールのインスタンス化部分だけ書きます。


一工夫が必要なのは最上位ビットだけであとは普通の全加算器と同じです。

私は、
>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 ====
    • good
    • 0

やりたいことがよくわからんのですが....


2個の符号付き 16bit 整数を受け取って, 何bit の符号付き整数を出すんでしょうか?
17bit でよければ full adder の carry out が 最上位になりますよね.
16bit で出力し, オーバーフローを検出したいなら確か carry out と 16bit 目の xor かなんかでわかったような気がします.
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!