当前位置: 首页 > news >正文

基于FPGA的数字信号处理(20)--半减器和全减器

目录

1、前言

2、半减器

3、全减器

4、减法器


         文章总目录点这里:《基于FPGA的数字信号处理》专栏的导航与说明


1、前言

        既然有半加器和全加器,那自然也有半减器和全减器了。尽管在电路中减法的实现基本都是 补码 + 加法 的形式,但是正所谓技多不压身,了解一下半减器和全减器还是有一定作用的,至少能扩宽知识面嘛。

2、半减器

        最简单的减法器叫做 半减器Half Subtractor),它将2个1bit的输入数据相减,输出一个1bit的结果即 差Di(Difference),以及向高位的借位Bo(Borrow output)。例如:

  • 1 - 1 = 01 -1 = 0,不需要向高位借位,差为0,即Bo = 0,Di = 0

  • 1 - 0 = 01 -0 = 1,不需要向高位借位,差为1,即Bo = 0,Di = 1

  • 0 - 1 = 10 -1 = 1, 需要向高位借位,差为1,即Bo = 1,Di = 1

  • 0 - 0 = 00 -0 = 0,不需要向高位借位,差为0,即Bo = 0,Di = 0

        2个1bit数相减,最多只有4种情况(在上面已经例出来了),据此可以写出半减器的真值表:

被减数减数向高位借位
XYDiBo
0000
0111
1010
1100

        从这个真值表,不难推断出输出的逻辑表达式:

  • 差Di在2个输入不同时为1,所以它是输入异或的结果,即 Di = a ^ b

  • 向高位借位Bo在X = 0 且 Y = 1 时才为1,即 Bo= ~X & Y

        有了逻辑表达式后,可以很容易地画出对应的门电路结构:

image-20240426103255933

        顺便提一句,虽然半减器的基本电路是上面这个样子的,但是因为在FPGA中只有查找表LUT而没有具体的门电路,所以如果用FPGA来综合半减器的话,它的电路应该是这个样子的(因为只有2个输入和2个输出,所以只要1个LUT6就可以覆盖到所有情况):

image-20240426105010530

如果你不了解LUT,可以看看这篇文章:从底层结构开始学习FPGA(2)----LUT查找表,或者看看这个专栏:从底层结构开始学习FPGA

        IBUF和OBUF是Vivado自动添加的对输入输出管脚的缓冲,尽管上图显示的是2个LUT2(可能这样的显示更清晰一点),但是实际上就是1个LUT6,下面的资源显示情况也证明了这一点:

image-20240426105038079

        用verilog实现半减器如下:

//使用逻辑表达式来描述半减器
module half_subtractor(input   x,      //被减数input   y,      //减数output  di,     //差output  bo      //向高位借位
);
​
//根据化简结果分别表示:差 与 向高位借位
assign di = x ^ y;  
assign bo = ~x & y;endmodule

        有了RTL,接下来就该要写个对应的TB来测试电路功能是否正常。由于这个电路足够简单(一共只有4种情况),所以我们可以把所有可能的情况都穷举出来,然后观察输出是否符合预期即可。TB如下:

`timescale 1ns/1ns              //时间刻度:单位1ns,精度1ns
​
module tb_half_subtractor();            
​
//定义变量  
reg     x;
reg     y;
wire    di;
wire    bo;
​
//设置初始化条件
initial begin//第1种情况x =1'b0;    y =1'b0;    #10     //第2种情况x =1'b0;    y =1'b1;    #10     //第3种情况x =1'b1;    y =1'b0;#10     //第4种情况x =1'b1;    y =1'b1;#10 $stop();    //结束仿真  
end
​
//例化被测试模块
half_subtractor u_half_subtractor(.x      (x),.y      (y),    .di     (di),   .bo     (bo)
);endmodule

        仿真结果如下:

image-20240426105113676

        通过和真值表的对比(或者验证逻辑表达式也可以),可以发现,电路的输出是符合预期的。

3、全减器

        虽然半减器可以实现2个1bit数的减法,但在实际应用中,更常见的是要实现2个多bits数的减法,那么该如何实现?以2个2bits数的减法为例:

  1. 先把低位和高位的减法先分开。

  2. 低位是2个1bit的减法,所以可以用1个HS(半减器)来实现,它产生的差就是最终结果的低位,它产生的向高位借位要被送入到高位参与它们的减法。

  3. 高位除了要计算减数和被减数的高位外,还有1个来自低位的借位。

        好,现在问题是半减器没有设计来自低位的借位,所以它处理不了这种情况。为此,全减器被设计出来了,它在半减器的基础上,增加了来自低位的借位输入。这样多个全减器就可以级联起来实现多bits的减法了。

        全减器Full Subtractor),它处理2个1bit的输入和来自低位的借位Bi(Borrow input)输入共3个数,输出一个差Di和向高位的借位Bi。例如(格式:被减数- 减数 - 来自低位的借位):

  • 1 - 1 - 1 = 11 - 1 - 1 = 0,来自低位的借位为1, 需要向高位借位,差为0,即Bi = 1,Bo = 0,Di = 0

  • 1 - 1 - 0 = 01 - 1 - 0 = 0,来自低位的借位为0,不需要向高位借位,差为0,即Bi = 0,Bo = 0,Di = 0

  • 1 - 0 - 1 = 01 - 0 - 1 = 0,来自低位的借位为1,不需要向高位借位,差为0,即Bi = 1,Bo = 0,Di = 0

  • 1 - 0 - 0 = 01 - 0 - 0 = 0,来自低位的借位为0,不需要向高位借位,差为1,即Bi = 0,Bo = 0,Di = 1

  • ······

        3个输入一共只有8种情况,把所有情况都穷举出来,就可以列出全减器的真值表:

被减数减数来自低位的借位向高位的借位
XYBiDiBo
00000
00111
01011
01101
10010
10100
11000
11111

        从这个真值表,不难推断出两个输出的逻辑表达式:

  • Di为1的4种情况,~x&~y&bi + ~x&y&~bi + x&~y&~bi + x&y&bi=~x&(~y&bi+y&~bi)+x&(~y&~bi+y&bi) = ~x&(y^bi) + x&~(y^bi) = x ^ y ^ bi

  • Bo为1的4种情况,~x&~y&bi + ~x&y&~bi + ~x&y&bi + x&y&bi = ~x&(~y&bi+y&~bi) + (~x+x)&y&bi = ~x&(y^bi) + y&bi

        有了逻辑表达式后,就很容易画出电路图了(偷了个懒,不是画的,是用vivado生成的):

image-20240426112013178

        根据门电路,可以写出全减器的Verilog实现:

//使用逻辑表达式来描述全减器
module full_subtractor(input   x,      //被减数input   y,      //减数input   bi,     //来自低位的借位output  di,     //差output  bo      //向高位借位
);
​
//根据化简结果分别表示:差 与 向高位借位
assign di = x ^ y ^ bi; 
assign bo = ~x & (y ^ bi) | y & bi;endmodule 

        接下来写个TB测试电路,输入一共只有8个,所以依然用穷举法来测试:

`timescale 1ns/1ns              //时间刻度:单位1ns,精度1ns
​
module tb_full_subtractor();            
​
//定义变量  
reg     x;
reg     y;
reg     bi;
wire    di;
wire    bo;
​
//设置初始化条件
initial begin//第1种情况x =1'b0;    y =1'b0;    bi =1'b0;   #10     //第2种情况x =1'b0;    y =1'b1;bi =1'b0;   #10     //第3种情况x =1'b1;    y =1'b0;bi =1'b0;#10     //第4种情况x =1'b1;    y =1'b1;bi =1'b0;#10     //第5种情况x =1'b0;    y =1'b0;    bi =1'b1;#10     //第6种情况x =1'b0;    y =1'b1;bi =1'b1;#10     //第7种情况x =1'b1;    y =1'b0;bi =1'b1;#10     //第8种情况x =1'b1;    y =1'b1;bi =1'b1;   #10 $stop();    //结束仿真  
end
​
//例化被测试模块
full_subtractor u_full_subtractor(.x      (x),.y      (y),    .di     (di),.bi     (bi),.bo     (bo)
);endmodule

        仿真结果如下所示:

image-20240426112114957

        通过和真值表的对比(或者验证逻辑表达式也可以),可以发现,电路的输出是符合预期的。

4、减法器

        有了全减器后,就可以实现两个多bits数的减法了,这样的电路也被称为减法器。和行波进位加法器的结构类似,我们也可以将多个全减器级联起来搭建减法器,以4bits的减法为例,它的结构如下:

image-20240426113045693

        根据结构图,可以很快地写出它对应的Verilog代码:

//使用多个全减器建联构建减法器
module subtractor(input   [3:0]   x,  //被减数input   [3:0]   y,  //减数input           bi, //来自低位的借位output  [3:0]   di, //差output          bo  //向高位借位
);
​
wire    b1,b2,b3;   //借位连接
​
//例化全减器来构建减法器
full_subtractor u0(.x      (x[0]),.y      (y[0]), .di     (di[0]),.bi     (bi),.bo     (b1)
);
full_subtractor u1(.x      (x[1]),.y      (y[1]), .di     (di[1]),.bi     (b1),.bo     (b2)
);
full_subtractor u2(.x      (x[2]),.y      (y[2]), .di     (di[2]),.bi     (b2),.bo     (b3)
);
full_subtractor u3(.x      (x[3]),.y      (y[3]), .di     (di[3]),.bi     (b3),.bo     (bo)
);
​
endmodule

        这里记得要把之前的全减器也添加进工程。生成的示意图如下(这个排布不能很好地看出来层次结构,但确实没错):

image-20240426121705201

        然后写个TB测试一下这个减法器电路,因为4个bits即16×16=256种情况,加上低位借位的两种情况,也才256×2=512种情况,所以依然用穷举法来测试:

`timescale 1ns/1ns              //时间刻度:单位1ns,精度1ns
​
module tb_full_subtractor();            
​
//定义变量  
reg     [3:0]   x;      //被减数
reg     [3:0]   y;      //减数
reg             bi;     //来自低位的借位
wire    [3:0]   di;     //差
wire            bo;     //向高位借位
​
reg [3:0]   di_real;    //差的真实值,作为对比
reg         bo_real;    //向高位借位的真实值,作为对比
wire        di_flag;    //di正确标志信号
wire        bo_flag;    //bo正确标志信号
​
assign di_flag = di == di_real; //di结果正确时拉高该信号
assign bo_flag = bo == bo_real; //bo结果正确时拉高该信号
​
integer z,i,j;  //循环变量
//设置初始化条件
initial begin//初始化x =1'b0;    y =1'b0;    bi =1'b0;   //设定低位借位为0//穷举所有情况for(z=0;z<=1;z=z+1)beginbi = z;for(i=0;i<16;i=i+1)beginx = i;for(j=0;j<16;j=j+1)beginy = j;if((i-j-z)<0)begin                  //减法结果是负数di_real = (i - j - z)+ 5'd16;   //加上向高位的借位bo_real = 1;                    //向高位的借位为1endelse begin                          //减法结果是正数数di_real = i - j - z;            //结果就是减法本身bo_real = 0;                    //向高位的借位为0end#5;             end endend#10 $stop();    //结束仿真  
end
​
//例化被测试模块
subtractor u_subtractor(.x      (x),.y      (y),    .di     (di),.bi     (bi),.bo     (bo)
);endmodule

        TB中分别用3个嵌套循环将所有情况穷举出来,即bi=0~1、x=0~15和y=0~15的所有情况。减法运算的预期结果也是很容易就可以找出来的,就是直接写减法就行。接着构建了两个标志向量di_flag和bo_flag作为电路输出与预期结果的对比值,当二者一致时即拉高这两个信号。这样我们只要观察这两个信号,即可知道电路输出是否正确。仿真结果如下:

image-20240426122614109

        可以看到,di_flag和bo_flag都是一直拉高的,说明电路输出正确。

相关文章:

基于FPGA的数字信号处理(20)--半减器和全减器

目录 1、前言 2、半减器 3、全减器 4、减法器 文章总目录点这里&#xff1a;《基于FPGA的数字信号处理》专栏的导航与说明 1、前言 既然有半加器和全加器&#xff0c;那自然也有半减器和全减器了。尽管在电路中减法的实现基本都是 补码 加法 的形式&#xff0c;但是正所谓…...

Python:单引号,双引号,三引号的区别

在Python中&#xff0c;单引号&#xff08;&#xff09;、双引号&#xff08;"&#xff09;和三引号&#xff08; 或 """&#xff09;都可以用来定义字符串&#xff0c;但它们之间有一些区别&#xff1a; 单引号&#xff08;&#xff09;和双引号&#xf…...

电子电气架构 ---SOMEIP/SD初入门

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...

一些数学基础概念

一些数学基础概念 概率密度函数(PDF) 概率密度函数&#xff08;Probability Density Function&#xff0c;简称 PDF&#xff09;是描述连续随机变量的概率分布的一种函数。它用来表示随机变量在各个取值区间内的概率密度。 1. 定义 对于一个连续随机变量 ( X )&#xff0c;…...

责任有限公司的一般组织结构

责任有限公司&#xff08;有限责任公司&#xff0c;LLC&#xff09;的组织结构通常是为了确保公司运营的有效性和管理的透明度。以下是一般责任有限公司的组织结构及其主要组成部分&#xff1a; 1. 股东&#xff08;Shareholders&#xff09; 职责和角色 所有者&#xff1a;…...

Leetcode3227. 字符串元音游戏

Every day a Leetcode 题目来源&#xff1a;3227. 字符串元音游戏 解法1&#xff1a;博弈论 分类讨论&#xff1a; 如果 s 不包含任何元音&#xff0c;小红输。如果 s 包含奇数个元音&#xff0c;小红可以直接把整个 s 移除&#xff0c;小红赢。如果 s 包含正偶数个元音&am…...

网络流量分析在运维管理中的重要性与实施策略

在运维管理工作中&#xff0c;网络流量分析是一项不可或缺的技术手段。通过对网络流量的深入剖析&#xff0c;运维团队能够更全面地了解网络状态&#xff0c;及时发现潜在问题&#xff0c;优化网络性能&#xff0c;从而确保企业网络的稳定与高效运行。本文将详细探讨网络流量分…...

通信原理实验——PCM编译码

PCM编译码 实验目的 理解PCM编译码原理及PCM编译码性能熟悉PCM编译码专用集成芯片的功能和使用方法及各种时钟关系熟悉语音数字化技术的主要指标及测量方法 主要仪器设备及软件 硬件&#xff1a;多功能实验箱、示波器、导线 软件&#xff1a;无 实验原理 1. 抽样信号的量…...

matlab的strel()函数的使用方法(OK)

这个函数 是形态学的结构元素 使用方法如下 SE strel(nhood) SE strel("diamond",r) SE strel("disk",r) SE strel("disk",r,n) SE strel("octagon",r) SE strel("line",len,deg) SE strel("rectangle",…...

Linux:Linux权限解析

一、Linux下的用户分类 在Linux下&#xff0c;有两种用户&#xff0c;一种是超级用户&#xff0c;一种是普通用户 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受权限限制&#xff08;制定规则&#xff0c;但不需要遵守规则&#xff09; 普通用户&#xff1…...

Spring面试篇章——IOC

IOC概念和原理 IOC概念 IOC就是控制反射&#xff0c;把对象创建和对象之间的调用过程&#xff0c;交给Spring进行管理使用IOC的目的&#xff1a;降低耦合度 IOC底层原理 xml解析、工厂模式、反射 图解&#xff1a; 原始模式 耦合度太高了&#xff0c;即当dao改了&#xf…...

适合制造业的项目管理软件都有哪些?

项目管理软件涉及进度、预算成本、资源、开发、流程、质量、风险、工时、知识文档、商务等各个方面&#xff0c;是企业项目管理领域的重要辅助工具&#xff0c;能够帮助组织提高项目管理水平与质量&#xff0c;确保项目顺利进行。 一、 奥博思 PowerProject 项目管理系统 Pow…...

微应用(Micro-Applications)、微前端(Micro Frontend)、Qiankun 框架之间的区别和联系

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo :联系我们:VX :tja6288 / EMAIL: 347969164@qq.com 文章目录 微应用(Micro-Applications)、微…...

String的底层构造

1.String类对象的构造&#xff08;后面有每一个接口的实现&#xff09; #define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include<iostream> #include<assert.h> using namespace std;namespace bit {class string{public:typedef char* iterator;typedef const…...

Binder机制的原理

Binder机制是Android系统中用于进程间通信&#xff08;IPC&#xff09;的核心机制&#xff0c;它基于C/S&#xff08;客户端-服务端&#xff09;模型&#xff0c;允许不同进程间进行高效的通信和数据交换。以下是对Binder机制原理的详细解析&#xff1a; 1. Binder架构 Binde…...

JavaScript输出数据的方法?

在JavaScript中&#xff0c;输出数据有以下几种方法&#xff1a; 使用console.log()函数&#xff1a;使用console.log()函数可以将数据输出到浏览器的控制台&#xff0c;例如&#xff1a; console.log("Hello, World!");使用alert()函数&#xff1a;使用alert()函数…...

Redis学习笔记——第19章 事务

第19章 事务 19.1 事务的实现 19.1.1 事务开始 使用multi命令开启一个事务 通过修改客户端的flags字段为REDIS_MULTI 19.1.2 命令入队 当开启事务之后&#xff0c;exec、discard、watch、multi命令立即执行&#xff0c;而其他命令会放入一个队列中&#xff0c;并返回Queue…...

元太电磁膜SUDE-10S19MI-01X驱动适配

屏规格书&#xff1a; dts配置&#xff1a; 首先要确保CONFIG_I2C_HID宏打开&#xff0c;i2c-hid-core.c 文件才能编译进去代码。规格书vendor product 分别为0x2d1f 和0x0165 来区别&#xff0c;不至于影响到整体的hid其他设备。 i2c-hid-dev10 { compatible "hid-…...

C#数据类型 全局变量 类型转换方法(汇总)

1、C#和S7-1200PLC S7.NET通信 C#和S7-1200PLC S7.NET通信-CSDN博客文章浏览阅读98次。一步步建立一个C#项目(连续读取S7-1200PLC数据)_s7协议批量读取-CSDN博客这篇博客作为C#的基础系列&#xff0c;和大家分享如何一步步建立一个C#项目完成对S7-1200PLC数据的连续读取。首先…...

HCIP重修总笔记(中)

第八节 BGP基础 一、BGP产生背景 BGPBorder Gateway Protocol&#xff0c;边界网关协议)是一种用于自治系统间的动态路出协议&#xff0c;是一种外部网关协议。 自治系统AS:一组同一个管理机构进行管理&#xff0c;对外呈现统一选路策略的路由器的集合。 自治系统编号: …...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...