zoukankan      html  css  js  c++  java
  • 有符号数和无符号数在计算机中的存储方式以及在Verilog中的运用($signed函数)

    #0.计算机组底层的电路只认识0和1,并没有任何数制和逻辑的概念。

    #1.首先在计算机中数字分为 定点数和浮点数; 定点数又分为定点整数和定点小数;定点整数有无符号和有符号两种 ;这里主要讨论无符号数和有符号数在计算机中是如何存储以及在VerilogHDL语言中如何使用。
    #2.VerilogHDL语言中除了integer类型之外的所有数据类型默认都是无符号类型;
    #3.符号扩展是用于两个运算操作数的位数不一样的时候,进行位数的统一的操作;这里只讨论相等位数;

    一,无符号数
    #如果要进行两个无符号数之间的大小比较该如何进行;首先应该注意的就是无符号数在计算机中是以原码形式存储的;原码存储就意味着这种表示方式下,任何计算结果都会是无符号数,这是因为1.存储位数是一定的所以最高位进位会被舍弃掉。2.如下图一样,所有加减的本质就是绕圈顺时针逆时针转。既然是这样,就是说直接用相减看差的方式是不可能得出正确的结果的;

    如:*这时候会想:因为Verilog中的数据默认是用无符号形式存储的,因此这个可以直接进行比较大小
    if(A - B > 0) C = 1;
    else C = 0;
    但实际上在无符号数中计算结果永远都是正的!所以这个不行*

    #所以真正真确的方式应该是从本质入手,也就是说两个数相减或相加,只要有溢出也就是最高位有进位那么结果一定是不对的,从这里入手在考虑实现细节。
    module comparator(
    input [3:0]A,
    input [3:0]B,
    output reg [3:0]C
    );

    reg [4:0]tempA;
    reg [4:0]tempB;
    reg [4:0]tempresult;
    always@()begin
    tempA = {0, A}; //对无符号数进行0扩展,实现标志位
    tempB = {0, B};
    tempresult = tempA - tempB;
    if(tempresult[4] == 0)begin
    C = 1; //被减数比较大
    end
    else if(tempresult[4] == 1)begin //这是有进位了,但是实际是被舍弃的
    C = 0; //减数比较大
    end

    end
    endmodule


    #BUT!在Verilog中已经有函数可以直接实现这种无符号数之间的转换;
    module comparator(
    input [3:0]A,
    input [3:0]B,
    output reg [3:0]C

    );

    always@()begin
    if($unsigned(A) > $unsigned(B)) C = 1; //刚才说过因为Verilog中的数默认是无符号数,因此可以这个函数也可以不写;;但是一定不能写成是相减的形式
    else C = 0;
    end

    endmodule

    二,有符号数
    #这里需要理解的是,有符号数有两种存储方式:原码形式和补码形式;但是几乎所有的计算机都使用二进制补码表示法来表示存储于n为存储单元的有符号整数。具体一些:假设4‘b1001是一个有符号数,用原码形式4’b1001=-1;但是用补码形式的话4'b1001=-7.在补码表示法中,对一个正数是直接用原码来表示,只有负数采用补码来表示,这是因为补码(~B+1)实际上是对负数取绝对值的运算,比如4‘b1001在补码下实际值为-7(还不理解就去查一下补码的表),对其进行取反加一就变成4'b0111=+7;*  (实际上有符号数的表示就是用补码来表示的,所以以后的所有情况都只考虑是在补码表示法下的用法)

    #这里在说明一下补码表示法下的运算,注意这里的“补码”是一种表示法!不是转换方式,具体来讲就是”正数不变,负数取反加一“;就这么简单。先看一下加法运算:如果4’b0110 + 4'b1001 就直接进行运算 = 4‘b1111;而实际上原式子用十进制写的话就是 6 + (-7) = -1;而4’b1111在补码表示下就是-1! 在看一下减法运算:如果4'b0110 - 4'b1001这时候就需要对被减数进行取反加一操作了,也就是对其加上绝对值~这是什么意思呢? 先看一下原式子的十进制表示:6 - (-7) = 6 + 7;所以实际上之所以要对被减数进行取反加一就是为了”负负得正“。接下来就很简单:4‘b0110 + 4'b0111 = 4'b1101; 会发现这时候计算结果4'b1101补码形式下等于-3,而正确应该是6+7 = 13;为什么呢? 对,是因为溢出了。因为4位有符号数的表示范围:0~7 -1~-8; 但是本质上应该可以理解了。


    这里不具体谈如何从最底层进行无符号数的大小比较,主要是因为Verilog中函数已经实现了具体的功能;这里又一些细节:

    对两个有符号数。必须考虑两个数是同号还是异号:
    A 、 对两个同符号数。因其相减不会溢出,即OF=0。 SF=0:被减数大于减数
    SF=1:被减数小于减数
    B 、如果比较的两个数符号不相同,此时就有可能出现溢出 ·若OF =0 (即无溢出),则有:
    如果被减数大于减数,SF =0,
    如果被减数小于减数,SF =1;
    如果被减数等于减数,sF =0,同时ZF =1;
    ·若OF =1(有溢出) .则:
    如果被减数大于减数,SF =1
    如果被减数小于减数,SF =0。
    若OF ⊕SF=0,则dest >src;
    若OF ⊕SF=1,则dest <src 。

    //比较两个有符号数的大小
    module comparator(
    input [3:0]A,
    input [3:0]B,
    input [3:0]C

    );

    always@()begin
    if($signed(A) > $signed(B)) C = 1; //同样这里不能写成减法的形式
    else C = 0;

    end
    endmodule

    所以这里需要记住的就是:

    有符号数的 (A > B) 和 (A-B>0)是不一样的,因为提供有符号类型的人已经帮你写好了如何进行比较的算法,所以用正确的方式去用,但是如果自己实现的话,就要考虑很多情况。

  • 相关阅读:
    1、springcloud gateway
    -webkit-overflow-scrolling:touch 相关
    SpringBoot(一)原理剖析:SpringApplication启动原理
    JAVA基础面试题
    JVM面试题
    排序(四)选择排序:简单选择排序
    排序(三)插入排序:简单插入排序和希尔排序
    排序(二)交换排序:冒泡排序与快速排序
    排序(一)简介
    多线程面试题
  • 原文地址:https://www.cnblogs.com/haotianmichael/p/8024777.html
Copyright © 2011-2022 走看看