以往在做一些数字电路设计中未曾涉及到有符号数的计算,因此昨日遇见一道简单的题目,没有搞清楚原理导致答错,特此记录下Verilog中有符号数计算的特点。
一、题目描述以及错误原因
有符号数1111+0010得到的结果是?
其实这道题很简单,但是我的思路错了,计算机表示负数是用补码表示的,所以1111(B)对应的十进制数为1111(B)取反加一,即1000(B)+1=1001(B),也就是-1(D),转换为十进制计算就是-1+2=1,所以结果就是1也就是0001(B)。
我错误的思路:1111因为符号位为1,所以其为负数,其十进制表示为-7(D),-7+2=-5,所以结果为1101(B)。
错误原因:
一定要注意,计算机看数据是以补码的形式看待的,所以一定要转换为补码进行计算!正数的补码就是原码,负数的补码就是原码取反加一。
二、Verilog设计及仿真结果
rtl代码如下:
1 module signedplus( 2 input wire clk, 3 input wire rst, 4 input wire signed [3:0] da, 5 input wire signed [3:0] db, 6 // output reg [4:0] data 7 output reg signed [4:0] data 8 ); 9 10 always @(posedge clk) begin 11 if (rst) begin 12 // reset 13 data <= 'd0; 14 end 15 else begin 16 data <= da + db; 17 end 18 end 19 20 endmoduleView Code
Modelsim仿真结果为下图,可以看出与分析结果一致
另外,因为计算结果data用5位数据来保存,因此两个加数的符号位扩展,da扩展为11111(B),db扩展为00010(B),相加后结果为00 001(B)
而如果按照无符号数来看呢?
1 module signedplus( 2 input wire clk, 3 input wire rst, 4 input wire [3:0] da, 5 input wire [3:0] db, 6 // output reg [4:0] data 7 output reg [4:0] data 8 ); 9 10 always @(posedge clk) begin 11 if (rst) begin 12 // reset 13 data <= 'd0; 14 end 15 else begin 16 data <= da + db; 17 end 18 end 19 20 endmoduleView Code
这里的变化仅仅是去掉了signed描述
仿真结果如下,就是直接相加得到的结果
还有一些博客也介绍了有符号数计算的相关注意事项,值得参考学习
标签:wire,符号,clk,补码,Verilog,计算,input,data From: https://www.cnblogs.com/Achilles7/p/16646701.html