Advertisement

Verilog中有符号数定义

阅读量:

Verilog中有符号数定义

在Verilog语言中进行负数运算时,在声明变量时必须将其定义为有符号类型(signed)。同时,在一个运算表达式中所有的操作数必须全部是带有符号类型的变量或者全部是不带符号类型的变量;如果混用了带和不带符号的变量进行运算,则可能导致错误。

负数在Verilog中通常采用补码形式存储。当一个变量在其运算过程中的某一步骤出现负数值时,默认会被存储为二进制补码形式。如果该变量未定义为带有符号位的数据类型,则在后续运算中将被使用其上一步骤所得的二进制补码数值作为无符号数值进行处理(即视为正数值),这将导致错误结果。以下通过Sobel边缘检测算法为例来具体说明这一情况。

sobel算子在计算过程中会出现负值。

复制代码
    reg      [9:0]   Gx       ;//可能会出现负值,这里仅用reg定义寄存器型变量
    reg      [9:0]   Gy       ;
    reg     [20:0]  Gxy_square;
    reg 	  [20:0]	 y			  ;
    always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        Gx<=10'b0;
    end
    else if(Gx_flag1)  begin
        Gx<=((a3-a1)+((b3-b1)<<1)+(c3-c1));   //这里计算出现负值,并且会以补码的类型储存,比如a1=1
    end
    end
    always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        Gxy_square  <=  21'b0;
    		  y<=0;
    end
    else if(Gx_flag2)  begin
        Gxy_square  <=  ((Gx*Gx)+(Gy*Gy));
    		  y<= (Gx)*(Gx);
    end
    end

a_1=\{a\}_{{\text{{v}}}}=\{b\}_{{\text{{v}}}}=\{c\}_{{\text{{v}}}}=\{\dots,\dots,\dots\}\right.$, $b_1$={\dots,\dots,\dots}\right., b_2=\{\dots,\dots,\dots\}\right., c_2=\{\dots,\dots,\dots\}\right.$, $c_3$={\dots,\dots,}$等未知数值存在时,在第几行中得到结果为7;然而在计算结果为7与自身相乘的过程中就会出现错误的原因在于负数补码运算中正数值参与运算会导致数值变化

在这里插入图片描述

改成下面代码就没问题了。

复制代码
    reg signed     [9:0]   Gx       ;
    reg signed     [9:0]   Gy       ;
    reg signed    [20:0]  Gxy_square;
    reg signed	  [20:0]	 y			  ;
在这里插入图片描述

在有符号数定义之后,在计算机中通常采用二进制形式表示数值。其中最高位即为符号位;除了最左边一位外的其他有效位也作为符号位。例如,在这种情况下:

复制代码
    reg signed [2:0]	a;
    a<=(-1);
    //a的二进制补码形式为111
    
    a>>1;  //011

:0] a;
a<=(-1);
//a的二进制补码形式为111

a>>1; //011

复制代码
    右移直接在左边补0。

全部评论 (0)

还没有任何评论哟~