有符号数和无符号数之间的转换

1 有符号数和无符号数的表示 三者的最高位均为符号位.

以8位为例:

原码 原码的表示范围-127~-0, +0~+127, 共256个数字。 正0的原码是0000 0000, 负0的原码是1000 0000, 有正0负0之分, 不符
合人的习惯,
反码 除符号位, 原码其余位取反而得 +0:0000 0000,-0:1111 1111 仍然有正0负0之分。
补码 在反码的基础上加1而得 对原码的两种0同时末位加1 +0:0000 0000,-0:0000 0000(因为溢出导致8位全0) 消除了正
0负0之别, 如此一来, 便节省出一个数值表示方式1000 0000, 不能浪费, 用来表示-128, -128特殊之处在于没有相应的反码原
码。也可以这样考虑:

      -1:   1111 1111 
      -2:   1111 1110(在-1的基础上减1,直接将补码减1即可) 
      -3:   1111 1101(在-2补码基础上减1,以下类似) 
      -4:   1111 1100
       …… 
       -127:1000 0001 
       -128:1000 0000 1 2 3 4 5 6 7

如此以来:8位补码表示范围是-128~+127因为0只有一种形式所以,仍然是256个数 若8位代表无符号数, 则表示范围是 : 0~255, 这就是为什么高级语言讲到数据类型, 比如C++中的short类型时(16位长)说其表示范围是:-32768~+32767,而unsigned short表示的
范围则是:0~65535

  1. 在计算机中无符号数用原码表示,有符号数用补码表示
   最高位 也称符号位,1表示负数,0表示正数,符号位为0时,和无符号数的表示是相同的,以下是4位补码的示例
      
 
           0101=−0∗23+1∗22+0∗21+1∗20=50101=−0∗23+1∗22+0∗21+1∗20=5
           1101=−1∗23+1∗22+0∗21+1∗20=−31101=−1∗23+1∗22+0∗21+1∗20=−3


         w位的补码表示的数值范围是[-2w-1, 2w-1-1]

        如4位的补码表示的最小值是-8(1000), 最大值是7(0111).

只有理解了有符号数的补码表示, 才能真正理解无符号数和有符号数的转换、有符号数的截断和溢出等问题.

下面结合modelsim仿真去理解有符号数与无符号数的一些加减法:

verilog和测试脚本年如下:

module sign(
input clk,
input rst,
input signed[7:0] data_1,
input signed[7:0] data_2,
output signed[8:0] data_out1,
output signed[15:0] data_out2,
output signed[15:0] data_out3,
output reg a
);

reg [8:0] data_out1_test;
reg [15:0] data_out2_test;
reg [15:0] data_out3_test;

// assign data_out=data_1+data_2;
always@(posedge clk )
if (rst)
a<=0;
else if (data_1<data_2)
a<=1;
else
a<=0;

always@(posedge clk )
if (rst)
begin
data_out1_test<=9’h0;
data_out2_test<=16’h0;
data_out3_test<=16’h0;
end

 else 
   begin
  data_out1_test<=data_1+data_2;
  data_out2_test<={{8{data_1[7]}},data_1};
  data_out3_test<={{8{data_2[7]}},data_2};
   end 

assign data_out1=data_out1_test;
assign data_out2=data_out2_test;
assign data_out3=data_out3_test;

endmodule

// Verilog Test Fixture Template

`timescale 1 ns / 1 ps

module sign_tb;

reg clk;
reg rst;
reg signed[7:0] data_1;
reg signed[7:0] data_2;
wire signed[8:0] data_out1;
wire signed[15:0] data_out2;
wire signed[15:0] data_out3;
wire a ;

sign   u1     (                  
  .clk           (clk            )    
 ,.rst           (rst            )
 ,.data_1        (data_1         )
 ,.data_2        (data_2         ) 
 ,.data_out1     ( data_out1     )
 ,.data_out2     (data_out2      )
 ,.data_out3     (data_out3      )
 ,.a             (        a      )
 ); 

     

initial                                                
begin      
 
    rst = 1; #248; rst = 0;
     clk = 1; forever #10 clk = ~clk;
	  
 end
 
 
initial                                                
begin      
         data_1=8'h12;data_2=8'h23;
 # 500;  data_1=8'h12;data_2=8'h45;  
 # 500;  data_1=8'h12;data_2=8'h80; 
 # 500;  data_1=8'h80;data_2=8'h45; 
 # 500;  data_1=8'h12;data_2=8'h45; 
 # 500;  data_1=8'h90;data_2=8'h45;  
 # 500;  data_1=8'h9a;data_2=8'h45;
 # 500;  data_1=8'h90;data_2=8'h9a; 	 
	  
 end	 

endmodule

在这里插入图片描述

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值