无符号数与有符合数的加法
首先,考虑一个问题,在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
以上几篇文章讨论的就是有符合数的加法和数的溢出问题。
路漫漫其修远兮,吾将上下而求索