Verilog基础知识(有符号数运算规则,加减运算,乘法运算中的符号位拓展问题) 您所在的位置:网站首页 源码可以直接进行加减运算吗对吗 Verilog基础知识(有符号数运算规则,加减运算,乘法运算中的符号位拓展问题)

Verilog基础知识(有符号数运算规则,加减运算,乘法运算中的符号位拓展问题)

2024-07-14 21:28| 来源: 网络整理| 查看: 265

rule of thumb The format of the signed type is two’s complement. 有符号数均为补码表示If any operand in an expression is unsigned the operation is considered to be unsigned. 只有计算表达式右边有无符号数,整个计算式都按照无符号数规则运算只有算式右边全为有符号数,运算才会自动补齐所需的bit数,n+n=n+1.n*n=2nThe value -4 represented as a 3bit signed hex value would be specified as -3’sh4. A decimal number is always signed. verilog2001中用’s来特别声明有符号数,十进制的数都是有符号数Type casting using $unsigned will make the operation unsigned. The operand will be sign extended with 0’s if necessary. $usigned()函数在高位补0A=$signed(B) will extend using sign bit. $unsigned()函数会在高位补与符号位相同的bit basic signed addition

两个n bit数相加,得到n+1 bit结果,比如-2(3’sb110)+3(3’sb011)=1(4’sb0011)

//Code Example 1: Addition - Verilog 1995 module add_signed_1995 ( input [2:0] A, input [2:0] B, output [3:0] Sum ); assign Sum = {A[2],A} + {B[2],B}; endmodule // add_signed_1995 //Code Example 2: Addition - Verilog 2001 module add_signed_2001 ( input signed [2:0] A, input signed [2:0] B, output signed [3:0] Sum ); assign Sum = A + B; endmodule // add_signed_2001 signed + unsigned

如果是两个3bit有符号数+1bit进位。如果在verilog2001中直接用符号位拓展

sum=A+B+carry_in //整个计算式会转换成无符号计算,signed to unsigned conversion occurs sum=A+B+$signed(carry_in) //就会出现当carry_in=1时候拓展为4'b1111,这时候本来是加1,却变成了减1 sum = A + B + $signed({1'b0,carry_in}) //正确的做法

正确的做法是

// Code Example 3: Add with Carry - Verilog 1995 module add_carry_signed_1995 ( input [2:0] A,dsa input [2:0] B, input carry_in, output [3:0] Sum ); assign Sum = {A[2],A} + {B[2],B} + carry_in; endmodule //add_carry_signed_1995 // Code Example 5: Add with Carry - Correct module add_carry_signed_final ( input signed [2:0] A, input signed [2:0] B, input carry_in, output signed [3:0] Sum ); assign Sum = A + B + $signed({1'b0,carry_in}); endmodule // add_carry_signed_final basic signed multiplication

两个n bit数相乘,得到2n bit结果。如果-3(3’sb101) * 2 (3’sb010) 得到正确结果 -6 (6’sb111010)。但如果乘数是负数,则最高位的乘积需要以减法参与运算,而不是加法。

// Code Example 6: Signed Multiply - Verilog 1995 module mult_signed_1995 ( input [2:0] a, input [2:0] b, output [5:0] prod ); wire [5:0] prod_intermediate0; wire [5:0] prod_intermediate1; wire [5:0] prod_intermediate2; wire [2:0] inv_add1; assign prod_intermediate0 = b[0] ? {{3{a[2]}}, a} : 6'b0; assign prod_intermediate1 = b[1] ? {{2{a[2]}}, a, 1'b0} : 6'b0; // Do the invert and add1 of a. assign inv_add1 = ~a + 1'b1; assign prod_intermediate2 = b[2] ? {{1{inv_add1[2]}}, inv_add1, 2'b0} : 6'b0; assign prod = prod_intermediate0 + prod_intermediate1 + prod_intermediate2; endmodule // Code Example 7: Signed Multiply - Verilog 2001 module mult_signed_2001 ( input signed [2:0] a, input signed [2:0] b, output signed [5:0] prod ); assign prod = a*b; endmodule signed * unsigned prod = a*b; //整个运算变成无符号,-3(3'sb101)*2(3'b010)变成5(6'b000101)*2(6'b000010)=10(6'b001010) prod = a*$signed(b); //当乘数的MSB=1的时候会出错,2(3'sb010)*7(3'b111)变成 //-2(6'sb000010)*-1(6'sb111111)=2(6'sb110010) prod = a*$signed({1'b0,b}); //正确做法 // Code Example 11: Signed by Unsigned Multiply module mult_signed_unsigned_2001 ( input signed [2:0] a, input [2:0] b, output signed [5:0] prod ); assign prod = a*$signed({1'b0,b}); endmodule signed shift

逻辑移位’>>’, ‘>>3; //8'b11110100



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有