FPGA秋招-笔记整理(3)无符号数、有符号数

news2024/10/5 12:47:32

参考:Verilog学习笔记——有符号数的乘法和加法

一、无符号数、有符号数

将输入输出全部定义为有符号数

(1)无符号数读取按照原码进行,有符号数的读取应该按照补码读取,计算规则为去掉符号位后取反、加1在计算数值。

(2)直接赋值十进制数据,乘数在以无符号数读取时时按照原码读取,127就对应 8 位二进制数 8’b0111_1111,十进制 128 就对应 8 位二进制 8’b1000_0000;而以有符号数读取的时候是会直接转换为补码形式,如 -127,先去掉符号位是 127,对应 7 位二进制数 7’b111_1111,取反为 7’b000_0000,加 1 为 7’b000_0001,将符号位补回到最高位为 8’b1000_0001;对于 -128 的表示比较特殊,8-bit的二进制数最高位是符号位,表示正负,剩下的 7-bit 能够表示的数的范围是 0 ~ 127,前面加上 ± 就能表示 -127 ~ 127,其中有 2 个数很特殊就是 8’b0000_0000 和 8’b1000_0000,按照上面会出现 +0 和 -0,为了区分出这两个数,前人定义 8’b0000_0000 表示 0,而 8’b1000_0000 表示 -128,这样不仅能区分开两个数,还多表示了一个数 -128(整个计算机体系通用,其他位数时类似表示一个负数)

(3)计算准则:

                 无符号 * 无符号 = 无符号;

                 有符号 * 有符号 = 有符号;

                 如果表达式中有一个无符号数,则所有的操作数都会被强行转换为无符号数;

当后面设计输入输出时,如果是有符号,那么将相关计算的输入/输出和中间量都显式的用 signed 定义。(如果是有符号数的计算,那么所有的输入、输出、中间量的计算都应该设置为有符号数

符号扩展计算方法:

计算准则:

对于乘法,在运算的时候将符号位扩展到和积的位数相等。一般使用位拼接符{}进行计算。

对有符号数的加法,同样的,要么相关的运算全部定义成有符号数,要么进行符号位的扩展对于加法操作,只需要每个被加数扩展 1 位符号位即可


参考:Verilog学习笔记——有符号数的乘法和加法

案例:

下面的输入和输出都没有指定成 signed 有符号数,计算时默认是按照无符号数计算(是把读取到的 8 位二进制数当做原码去算),此时若外部传入的数据实际上是有符号数(比如 FIR 滤波器传入了正负均有的待滤波信号),那么需要对符号位进行扩展来计算乘法和加法;


module signed_test_2(
    input   [7:0]   data_in_1,
    input   [7:0]   data_in_2,
    output  [15:0]  data_out_1,
    output  [15:0]  data_out_2
);

对于乘法,需要扩展符号位 到 和积的位数相等,比如乘数a为 N-bit,乘数 b 为M-bit,两个相乘得到 N+M 位数据,此时需要对 a 扩展 M-bit 到 N+M 位,对 b 扩展 N-bit 到 N+M 位;

下面,使用 位拼接符 { } 来做演示,位拼接符可以按照二进制的位来进行高低位的拼接,假设 data_in_1= 8’b1000_0011,对于 {{8{data_in_1[7]}},data_in_1} 可以这样理解:

(1) 先看 8{data_in_1[7]},表示取出 8-bit 数据 data_in_1 的最高位 data_in_1[7],重复 8 次,相当于 { data_in_1[7], data_in_1[7], data_in_1[7], data_in_1[7], data_in_1[7], data_in_1[7], data_in_1[7], data_in_1[7] },即高位扩展 8-bit 的 1

(2) {{8{data_in_1[7]}},data_in_1} 相当于在 data_in_1 的前面补上 8 个 data_in_1[7],即 结果为 16-bit 的 16’b1111_1111_1000_0011;

//不做符号位扩展,直接相乘
assign data_out_1 = data_in_1 * data_in_2;
//做符号位扩展,再相乘
assign data_out_2 = {{8{data_in_1[7]}},data_in_1} * {{8{data_in_2[7]}},data_in_2};

仿真测试数据如下,1 处用十六进制给出数据,2 处用有符号的十进制赋值,3 处是为了和 2 处对比,看最后赋值是否一样;

仿真结果如下,可以看到上图 2 处和 3 处的赋值在仿真时是同样的数据,把所有数据都用有符号的十进制数显示(右键数据 Radix -> Signed Decimal)

 (可以看到对于负数数据的读入是将其补码读入)

可以看到,data_out_1的结果是错的(没有补符号位),data_out_2的结果是对的(补符号位);

利用IP进行计算

除此之外,还可以调用乘法器的 IP 来代替 乘法符号 *,或者加法器的 IP 来代替 加法符号 +,在 IP 核中配置输入输出为有符号数即可

二、有符号位的位宽匹配问题

参考:verilog有符号数的位宽转换_verilog 有符号数位宽大到位宽小-CSDN博客

当有符号低位宽向高位宽匹配时,高位需要补充符号位

reg [3:0]	original;								//定义4位有符号数寄存器变量
reg [7:0]	later;									//定义8位有符号数寄存器变量
assign later = {{4{original[3]}}},original};		//高4位补original的符号位

当有符号高位宽向低位宽匹配时,直接对于低位进行截取,当然在这个过程中可能会将符号位截掉。

对于短位宽赋值给长位宽的情况,需要对高位进行位扩展,具体是扩展1还是扩展0,记住:完全依据右操作数!,具体如下:
1)右操作数是无符号数,则无论左操作数是什么类型,高位都扩展成0;
2)右操作数是有符号数,则要看右操作数的符号位,按照右操作数的符号位扩展,符号位是1就扩展1,是0就扩展0;
3)位扩展后的左操作按照是无符号数还是有符号数解释成对应的十进制数值,如果是无符号数,则直接转换成十进制数值,如果是有符号数,则看成2的补码解释成十进制数;
4)从上面4种情况看出,有符号数赋值成无符号数会出现数据错误的情况,因此要避免这种赋值,而其他情况都是可以保证数据正确的。

                   
引自:https://blog.csdn.net/qq_31006535/article/details/106216391

三、例子 

1. 题目

根据指示信号select的不同,对输入信号a,b实现不同的运算。输入信号a、b为8bit有符号数,

当select[1:0] = 0,输出a;

当select[1:0] = 1,输出b;

当select[1:0] = 2,输出a+b;

当select[1:0] = 3,输出a-b。

 思路:有符号数的加减法有两种方式

(1)将有符号数输入、输出、中间变量全部定义为有符号数

注意:如果在运算工程中出现无符号数,那么在运算的过程中都会将有符号数(补码形式)视为无符号数参与计算

(2)采用符号位扩展的方式进行运算


`timescale 1ns/1ns
module data_select(
  input clk,
  input rst_n,
  input signed[7:0]a,
  input signed[7:0]b,
  input [1:0]select,
  output reg signed [8:0]c
);

always@(posedge clk,negedge rst_n)begin
    if(~rst_n)begin
        c <= 9'b0;
    end
    else begin
        case(select)
            2'b00: c<= {a[7],a};
            2'b01: c<= {b[7],a};
            2'b10: c<= {a[7],a} + {b[7],a};
            2'b11: c<= {a[7],a} - {b[7],a};
        endcase
    end
end
endmodule

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1630962.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

84.柱形图中最大的矩阵

二刷终于能过了. 思路解析: 不愧是hard,第一步就很难想, 对于每一个矩阵,我们要想清楚怎么拿到最大矩阵, 对于每个height[i],我们需要找到left和right,left是i左边第一个小于height[i]的,right是右边第一个小于height[i]的,那么他的最大矩阵就是height[i] * (right-left-…

暗区突围无限测试资格获取教程 暗区突围怎么参加测试教程推荐

《暗区突围&#xff1a;无限》是一款强调极致真实与沉浸感的军事策略游戏&#xff0c;它邀请玩家踏入危机四伏的战场&#xff0c;通过射击、智取与突袭&#xff0c;铺就一条满载财富的道路。在这片未知与挑战并存的土地上&#xff0c;游戏赋予玩家极高的行动自由&#xff0c;旨…

苍穹外卖绕过微信支付

经过以下改动可实现&#xff1a; 1、不用微信支付端口 2、弹出支付成功的界面 3、数据库修改支付成功后的数据 #在OrderServiceImpl.java里加入Autowiredprivate OrderService orderService; #在OrderServiceImpl.java里的payment函数做以下改动 #图片里有&#xff0c;红色为原…

如何从requirements.txt文件中安装pytorch

平时使用requirements.txt文件来安装python的依赖&#xff0c;如下所示&#xff1a; Flask3.0.0 Flask-Cors4.0.0 elastic-transport8.11.0 elasticsearch8.11.1但是如果我们的依赖中包含pytorch依赖&#xff0c;显然是不能简单的通过这个方式来进行的&#xff0c;例如&#x…

怎样将便签软件搬家?便签迁移攻略

便签软件已成为我们日常生活中不可或缺的记录工具。无论是重要的工作内容&#xff0c;还是琐碎的生活事务&#xff0c;我们都会在便签中一一记下。然而&#xff0c;当我们需要更换电脑或其他设备时&#xff0c;如何将这些珍贵的便签内容迁移到新设备上&#xff0c;成为了许多人…

Linxu系统服务管理,systemd知识/进程优先级/平均负载/php进程CPU100%怎么解决系列知识!

shell脚本&#xff08;命令&#xff09;放后台 sleep 300& 放到后台运行&#xff0c;脚本或命令要全路径 nohup&#xff1a;用户推出系统进程继续工作 【功能说明】 nohup 命令可以将程序以忽略挂起信号的方式运行起来&#xff0c;被运行程序的输出信息将不会显示到终端 如…

VS2019配合QT5.9开发IRayAT430相机SDK

环境配置 VS2019 QT5.9 编译器版本 MSVC2017_64添加系统环境变量&#xff08;完毕后重启电脑&#xff09; 从VS2019中下载Qt插件 从VS2019中添加单个编译组件 上述操作完成后用VS打开工程文件&#xff0c;工程文件地址 &#xff1a; C:\Users\86173\Desktop\IRCNETSDK_W…

337. 打家劫舍 III 树上最大独立集

这个题目其实就是 树形结构的 打家劫舍 (隔一家抢一家) 在打家劫舍中,我们是使用dp[i]记录当前的最大值,如果上一家刚抢过,就返回dp[i-2] 而对于这个题目,我们对每个节点记录两个状态,就是抢和没抢的最大值 具体转移方程如下: dfs(node,rob) 表示对于当前node节点,抢了true或…

最大连续1的个数 ||| ---- 滑动窗口

题目链接 题目: 分析: 题目中说可以将最多k个0翻转成1, 如果我们真的这样算就会十分麻烦, 所以我们可以换一种思路: 找到一个最长的子数组, 最多有k个0解法一: 暴力解法: 找到所有的最多有k个0的子字符串, 返回最长的解法二: 找到最长的子数组, 我们可以想到"滑动窗口算…

968.监控二叉树 树上最小支配集

法一: 动态规划 一个被支配的节点只会有三种状态 1.它本身有摄像头 2.他没有摄像头, 但是它的父节点有摄像头 3.他没有摄像头, 但是它的子节点有摄像头 我们 dfs(node,state) 记录在node节点时(以node为根的子树),状态为state下的所有最小摄像头 // 本身有摄像头就看左右孩子…

2024/4/28 C++day5

有以下类&#xff0c;完成特殊成员函数 class Person { string name; int *age; } class Stu:public Person { const double score; } #include <iostream> #include <string> using namespace std; class Person { string name; int *age ; publi…

Vision Pro“裸眼上车”,商汤绝影全新舱内3D交互亮相

2023年&#xff0c;Apple Vision Pro的横空出世让人们领略到了3D交互的魅力&#xff0c;商汤绝影通过深厚的技术研发实力和高效的创新迭代效率&#xff0c;带来两大全新座舱3D交互&#xff1a;3D Gaze高精视线交互和3D动态手势交互。 作为全球首创的能够通过视线定位与屏幕图标…

16.Blender 基础渲染工作流程及安装ACES

安装插件和菜单栏设置 在菜单栏的编辑里打开偏好设置 里面的插件界面 搜索node 给第三个打勾 点击安装&#xff0c;导入cat插件 安装完后&#xff0c;一定要打勾&#xff0c;选择上cat插件 这样N窗口才会显示MMD选项 导入场景 点击打开 把输出模式的帧率改为30fps 按…

CSS 之 transition过渡动画

一、简介 ​ CSS 制作 Web 动画有两种方式&#xff1a; 帧动画&#xff08;Keyframe Animation&#xff09;和过渡动画&#xff08;Transition Animation&#xff09;。针对不同的业务场景中&#xff0c;我们应该选择不同的动画方式&#xff0c;通常来说&#xff1a;对于交互元…

OpenHarmony实战开发-多层级手势事件

多层级手势事件指父子组件嵌套时&#xff0c;父子组件均绑定了手势或事件。在该场景下&#xff0c;手势或者事件的响应受到多个因素的影响&#xff0c;相互之间发生传递和竞争&#xff0c;容易出现预期外的响应。 本章主要介绍了多层级手势事件的默认响应顺序&#xff0c;以及…

MySQL8.0 msi版本安装教程

MySQL8.0 msi 版本安装教程 1> 官网下载安装包 2> 安装MySQL 2.1双击打开下载的安装包&#xff0c;进入到下面这个页面&#xff0c;选择 Custom 选项&#xff0c;之后&#xff0c;点击next 说明&#xff1a; 2.2 选择所需产品&#xff0c;更改安装位置(当然也可以默认安…

公式SUM(A2:C4C2:D5)一共对几个单元格进行求和?

一、公式中的几个问题 1.括号和冒号是双字节的字符。 这个不用多说了&#xff0c;相信题主中是提问时书写笔误&#xff0c;实际在Excel中写公式时肯定用的是英文单字节字符。 2.括号里是两个区域&#xff0c; 但两个区域之间是怎样的运算关系并没有说&#xff0c;或者说是遗…

数据结构之顺顺顺——顺序表

1.浅谈数据结构 相信我们对数据结构都不陌生&#xff0c;我们之前学过的数组就是最基础的数据结构&#xff0c;它大概就长这样&#xff1a; 数组 而作为最简单的数据结构&#xff0c;数组只能帮助我们实现储存数据这一个功能&#xff0c;随着学习的深入&#xff0c;和问题的日渐…

远程控制软件优化(1)

远程控制软件优化&#xff08;1&#xff09; 第一版存在以下缺点&#xff1a; 1、四大部分中 Robot States 部分过于简陋&#xff0c;不适合放到论文中 2、Lidar BEV 图像显示效果非常差&#xff0c;显示不全且很稀疏 3、视频流传输延时过高&#xff0c;无法实现远程控制 以…

学python的第二十三天

原文链接&#xff1a;Python 图形化界面设计&#xff08;Tkinter&#xff09; - 简书 (jianshu.com) 子窗体&#xff08;Toplevel&#xff09; 直接上代码&#xff1a; # 子窗体 from tkinter import *def newwindow():winNew Toplevel(root)winNew.geometry(320x240)winNe…