无锡做推广的网站织梦cms做网站教程视频
无锡做推广的网站,织梦cms做网站教程视频,企业所得税怎么申报,seo 0xu前言
逻辑门本质上操作的是单个二进制数#xff0c;通过高低电压或者有无信号来表示#xff0c;并且#xff0c;因为二进制数的原因#xff0c;一个数字#xff0c;我们可以通过二进制数来表示#xff0c;整数可以精确表示#xff0c;浮点数可以近似表示 本篇文章使用逻…前言
逻辑门本质上操作的是单个二进制数通过高低电压或者有无信号来表示并且因为二进制数的原因一个数字我们可以通过二进制数来表示整数可以精确表示浮点数可以近似表示 本篇文章使用逻辑门来构建加法器 git地址https://gitlab.com/lingyanTools/comvirtual.git
加法器
先来看整数一个二进制整数是怎么进行加法运算的呢 看下面两个二进制数 A 101 十进制 01100101 二进制 A 101十进制 01100101二进制 A101十进制01100101二进制 B 201 十进制 11001001 二进制 B 201十进制 11001001二进制 B201十进制11001001二进制 我们从右边开始往左侧进行计算计算相应的位如果大于1则进位整个流程如下
默认进位是01 1 进位0 0进位10 0 进位1 1进位01 0 进位0 1进位00 1 进位0 1进位00 0 进位0 0进位01 0 进位0 1进位01 1 进位0 0进位10 1 进位1 0进位1
因为最后有个进位所以最终的结果位100101110 302 101 201 很容易发现对于二进制的加法的每一位操作有两个值需要我们确定一个是当前的进位值 C i C_i Ci一个是当前的计算值 F i F_i Fi可以用下面的公式表示 { F i ( X i 异或 Y i ) 异或 C i − 1 , C i ( X i 与 C i − 1 ) 或 ( Y i 与 C i − 1 ) 或 ( X i 与 Y i ) \begin{cases} F_i (X_i 异或 Y_i) 异或 C_{i-1},\\ C_i (X_i 与 C_{i-1}) 或 (Y_i 与 C_{i-1}) 或 (X_i 与 Y_i ) \end{cases} {Fi(Xi异或Yi)异或Ci−1,Ci(Xi与Ci−1)或(Yi与Ci−1)或(Xi与Yi)
用电路表示 F i F_i Fi的值为
用电路表示 C i C_i Ci的值为
我们把通过输入 X i X_i Xi、 Y i Y_i Yi和 C i − 1 C_{i-1} Ci−1获取输出$F_i 和 和 和C_i$用C语言表示如下
/*** 全加器* 输入两个二进制位其实就是两根电路* 输入进位位c* param:* f输出值* c1:输出进位值* 返回加法位*/
void full_add(long x,long y,long c,long* f, long* c1)
{long a xor_gate(x, y);*f xor_gate(a, c);long b1 and_gate(x, c);long b2 and_gate(y, c);long b3 and_gate(x, y);*c1 or_gate(or_gate(b1, b2),b3);
}这个电路组合叫做全加器
串位进位加法器
上述的全加器可以计算一位的加法我们把每位的运算连起来就是我们上面计算过程列出的那样从右向左依次计算假设我们需要满足一个64位的加法器我们可以用64个全加器串行连接起来下图中n64
这种连接方式叫做串位进位加法器 这样我们的64位加法器就可以用C语言描述了
/*** 逻辑运算器的加法* param* in_1输入1* in_2输入2* bits选择执行加法的位数* 初始进位并且返回执行后的进位* return: 返回输出结果*/
long alu_add(long in_1, long in_2, long bits,long* c)
{long result 0;for(int i 0;ibits;i){long x alu_bit(in_1, i); // 获取输入1的第i位long y alu_bit(in_2, i); // 获取输入2的第i位long f 0;full_add(x, y, *c, f, c);result | fi;}return result;
}/*** 获取二进制位* param* in_1:输入的数据* bits:获取哪一位的二进制位,0~sizeof(long)-1* return* 返回获取到的数据0或1*/
unsigned long alu_bit(unsigned long in_1, long bits)
{unsigned long a 1;return ((abits)in_1)bits;
}进位选择加法器
串位进位加法器由于是串行的这就导致每一步的运算必须等待前面一位计算完成。几乎所有的算术运算都要用到ALU, ALU的核心还是加法器因此要提高运算速度, 加法器的速度非常关键。 在进行进位选择加法器讲解之前先介绍一种选择器2-1选择器
2-1选择器
2-1选择器是根据一位控制位控制2个输入输出哪一个的电路选择器电路图如下
我们可以用C语言实现一下
long select_2_1(long in_1,long in_2,long door)
{long a1 and_gate(in_1, door);long a2 and_gate(in_2, not_gate(door));return or_gate(a1, a2);
}并且该C函数可以不止实现单个位的选择对于64位以内的可以通过该方法返回选择后的值。
进位选择加法器
进位选择加法器是这样一种算法比如对于64位的加法分成四部分
A015位B1631位C3247位D4863位
BCD部分都有两种计算逻辑一种假设进位为0一种假设进位为1 所以AB0B1C0C1D0D1可以并行运算。运算完成后进行拼接拼接逻辑如下
根据A的进位选择B0或者B1根据上一步选择的B0或者B1是否发生进位选择C0或者C1根据上一步选择的C0或者C1是否发生进位选择D0或者D1
下面看一下C语言的实现
long alu_add_16(long in_1, long in_2)
{long ac 0;long bc0 0;long bc1 1;long cc0 0;long cc1 1;long dc0 0;long dc1 1;// 下面这些并行运算long a alu_add(in_1, in_2, 16,ac);long b0 alu_add(in_116, in_216, 16,bc0);long b1 alu_add(in_116, in_216, 16,bc1);long c0 alu_add(in_132, in_232, 16,cc0);long c1 alu_add(in_132, in_232, 16,cc1);long d0 alu_add(in_148, in_248, 16,dc0);long d1 alu_add(in_148, in_248, 16,dc1);long b select_2_1(b1, b0, ac);long c select_2_1(c1, c0, bb1?bc1:bc0);long d select_2_1(d1, d0, cc1?cc1:cc0);return a | b16 | c32 | d48;
}如何进行减法运算
使用逻辑门进行减法运算涉及借位运算比较麻烦但是我们可以通过操作将减法运算变成加法运算比如对下面的减法运算 A X − Y A X - Y AX−Y 我们可以写成加法的形式 A X ( − Y ) A X (-Y) AX(−Y)
而对于补码编码的数据来说-Y等于Y取反然后加1取反操作之需要对Y执行反相器即可而加1的操作正好可以通过设置加法的初始进位为1来进行处理下面给出减法运算的C语言电路描述
long alu_not(long in_1, long bits)
{long res 0;for(int i 0;ibits;i){long x alu_bit(in_1, i); // 获取输入1的第i位res | (not_gate(x)i);}return res;
}long alu_sub(long in_1, long in_2, long bits)
{long a alu_not(in_2,64);int c 1;return alu_add(in_1, a, bits,c);
}这样我们就使用C语言按照电路图的设计实现了加减的逻辑处理。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88401.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!