无符号数与有符合数的加法

首先,考虑一个问题,在Verilog中

assign answer = i_a+i_b-i_c;

assign answer_signed = $signed(i_a)+$signed(i_b)-$signed(i_c);

assign answer_unsigned = $unsigned(i_a)+$unsigned(i_b)-$unsigned(i_c);

这几种形式有什么区别?

实验如下,建立源文件和测试文件

`timescale 1ns/1ns

module signed_test(i_a,i_b,i_c,i_mode,o_answer);
input [7:0] i_a,i_b;
input [31:0] i_c;
input [1:0] i_mode;
output [7:0] o_answer;

wire [7:0] answer_unsigned,answer_signed,answer;

assign answer = i_a+i_b-i_c;

assign answer_signed = $signed(i_a)+$signed(i_b)-$signed(i_c);

assign answer_unsigned = $unsigned(i_a)+$unsigned(i_b)-$unsigned(i_c);

assign o_answer = (i_mode==2'd0)? answer:
(i_mode==2'd1)? answer_unsigned:
answer_signed;

endmodule
`timescale 1ns/1ns
module signed_test_tb;

reg [7:0] i_a,i_b;
integer i_c;
reg [1:0] i_mode;
wire [7:0] o_answer;

signed_test u0
(
.i_a(i_a),
.i_b(i_b),
.i_c(i_c),
.i_mode(i_mode),
.o_answer(o_answer)
);

initial
begin
i_mode
=2'd0;
i_a =8'd255;
i_b =8'd128;
i_c =16;

#
100;
i_mode
=2'd1;
i_a =8'd255;
i_b =8'd128;
i_c =16;

#
100;
i_mode
=2'd2;
i_a =8'd255;
i_b =8'd128;
i_c =16;

#
100
i_mode
=2'd0;
i_a =8'd256;
i_b =8'd128;
i_c =16;

#
100;
i_mode
=2'd1;
i_a =8'd256;
i_b =8'd128;
i_c =16;

#
100;
i_mode
=2'd2;
i_a =8'd256;
i_b =8'd128;
i_c =16;

#
100
i_mode
=2'd0;
i_a =8'd255;
i_b =8'd250;
i_c =16;

#
100;
i_mode
=2'd1;
i_a =8'd255;
i_b =8'd250;
i_c =16;

#
100;
i_mode
=2'd2;
i_a =8'd255;
i_b =8'd250;
i_c =16;

end

endmodule

仿真结果如下

 

由结果可知,这几种表示方法,仿真结果是一样的。由此可见,在硬件电路中,硬件都是当作无符号数来进行处理的。所以,我们要进行有符号数的加减乘运算时,需要人为的拓展符号位。

http://www.cnblogs.com/oomusou/archive/2007/11/25/971509.html

http://www.cnblogs.com/oomusou/archive/2009/10/31/verilog_signed_overflow.html

http://www.cnblogs.com/yuphone/archive/2010/12/12/1903647.html

以上几篇文章讨论的就是有符合数的加法和数的溢出问题。

posted on 2011-03-15 16:41  齐威王  阅读(2866)  评论(0编辑  收藏  举报

导航