在数字逻辑系统,仅仅存在高低。所以用它只代表一个整数数字。并且有3代表性的种类。这是:原码表示(符号加绝对值值)、反码表示(加-minus标志)而补码(符号加补)。这三个在FPGA中都有着广泛的应用。以下分别讨论。
1、原码表示法
原码表示法是机器数的一种简单的表示法。採用符号位级联绝对值的方法表示数字。其最高位为符号位,用0表示正数,1表示负数;其余部分为绝对数值部分。原码一般用二进制形式表示。
比如,X1 = +1010110,X2 = -1001010,则其原码分别为:01010110和11001010
原码表示数的范围与二进制位数有关。当用8位二进制来表示小数原码时,其表示范围:最大值为0.1111111,其真值约为10进制中的0.99;最小值为1.1111111。其真值约为十进制的-0.99。
当用8位二进制来表示整数原码时。其表示范围:最大值为01111111。其真值为十进制的127;最小值为11111111。其真值为十进制的-127。
在原码表示法中。对0有两种表示形式,分别记为+0和-0,以8比特数据为例,其对应的表示为:+0=00000000、-0=10000000。
2、反码表示法
反码可由原码得到。
假设数字是正数,则其反码与原码一样。假设数字是负数,则其反码是对它的原码(符号位除外)各位取反而得到的。
比如:X1 = +1010110, X2=-1001010,则其对应的反码为01010110、10110101。
3、补码表示法
补码表示法师实际中应用最广泛的数字表示法。其表示规则例如以下:若是正数。补码、反码和原码的表示是一样的。若是负数,补码、反码和原码的表示都不一样。
由反码与原码之间的关键,负数的补码等于其反码在最低位加1。
4、各类表示方法小结
原码的长处就是乘除运算方便。不论正负数,乘除运算都一样,并以符号位决定结果的正负号;若做加法则须要推断两数符号是否同样。若作减法,还须要推断两数绝对值的大小,以使大数减小数。
补码的长处是。加法运算方便,不论数的正负都可直接相加。而符号位相同參加运算。
例:给出各类码字表示法的基本加法运算实例,并说明各自特点
(1)首先给出原码的运算演示样例。当中()d代表十进制数。
首先给出一个原码的减法计算实例,完毕“1 + (-1)= 0“”的操作。
(1)d + (-1)d = (0)d
假设读者直接利用原码来完毕上式运算,会发现用符号位的原码进行在加减运算的时候就会出现故障。将数据以8比特的表示形式为例,
(00000001)原 + (10000001)原 = (10000001)原 = (-2)d
计算结果是不对的,问题在于两点:首先。负数的符号位直接改变了计算结果符号;其次,绝对值部分计算也不对。
这说明原码无法直接完毕正数和负数的加法。
(2)既然,原码不能完毕正、负数相加。那么反码形式能够完毕此操作吗?仍然以”1 + (-1) = 0“ 为例,其对应的反码表达式例如以下:
(00000000)反 + (11111110)反 = (11111111)反 = (-0)d
则发现问题出如今+0和-0上。由于实际的计算中的零没有正负之分的。但上式标明了反码完毕正、负数相加后。其绝对值部分是正确的。因此能正确完毕正、负数相加的表达形式必然包括反码的特性。
(3)最后给出补码的相关特性说明,负数的补码就是对反码加1,而正数不变。
以8比特数据为例。通过(-128)d取代了(-10)d。所以其表示范围为【-128,127】。从直观上。补码消除了(+0)和(-0)。而且具备反码特点,那么到底其能完毕正、负加法运算吗?答案是肯定的,以下给出详细实例,所看到的
(00000001)补 + (11111111)补 = (00000000)补 = (0)d
基于以上讨论,能够得到一个基本结论:仅仅有补码才干正确完毕正负加法运算,并将减法运算转化为加法运算,从而简化运算规则。
但对于乘法操作。则以原码形式计算是最方便的。以下有实例。
演示1:原码进行乘法运算 -2 * 2 = -4
module mul(input clk,input rstn,input [7:0] a,input [7:0] b,output [14:0] q_mul,output reg [8:0] q_add,output reg[7:0] ra,output reg[7:0] rb);reg [13:0] rmul;always @(posedge clk or negedge rstn)if(!rstn)beginq_add <= 0;ra <= 0;rb <= 0;rmul <= 0;endelse begin//q_mul <= a*b;if(a[7]==1)ra = {a[7],~a[6:0] + 1};elsera = a;if(b[7]==1)rb = {b[7],~b[6:0] + 1};elserb = b;rmul <= ra[6:0]*rb[6:0];q_add <= {a[7],a} + {b[7],b};endassign q_mul = {a[7]^b[7],rmul};endmodule
演示2:通过reg signed实现
module signedMul(input clk,input rstn,input [7:0] a,input [7:0] b,output [15:0] q);reg signed[7:0] ra;reg signed[7:0] rb;always @(posedge clk or negedge rstn) beginif(~rstn) beginra <= 0;rb <= 0;endelse beginra <= a;rb <= b;endendassign q = ra * rb;endmodule
版权声明:本文博主原创文章,博客,未经同意不得转载。