Verilog基础:位宽拓展和有符号数运算的联系

发布时间:2026/10/27 1:12:32
Verilog基础:位宽拓展和有符号数运算的联系 相关文章Verilog基础专栏https://blog.csdn.net/weixin_45791458/category_12263729.html我们以Verilog官方手册中的几个经典例子来看当有符号数、无符号数、位宽拓展和算术运算混在一起时到底会发生什么见下图。很多人刚开始学Verilog时最容易犯的一个错误就是把HDL里的“数”直接当成数学里的整数来看待认为-12/3就一定等于-4但在Verilog里表达式的结果除了和数值本身有关还和位宽、是否有符号、操作数类型以及上下文决定的扩展方式密切相关。也就是说Verilog不是简单地先算数值再决定如何存放而是会先根据规则确定操作数的位宽和符号属性再进行运算最后再把结果赋给目标变量。在阅读以下内容前需要知道对于有符号数和无符号数数字本身是不会改变的改变的只是对这串数字的解释有符号数将最高位当做符号位剩下的位当做是补码无符号数则没有符号位。没有位宽和基数的常数被当做32位有符号数算术运算符只有在操作数都为有符号数时才会执行有符号数计算结果才是有符号数。例3、2、1均被当做有符号数3/-1是有符号数除法结果为-3的补码2d3/-1是无符号数除法结果为0。我们定义了一个32位的有符号整数变量(variable)一个16位的无符号默认寄存器变量一个16位的有符号(signed)寄存器变量。后面这些例子的关键就在于同一个值放到不同类型的变量里或者参与不同上下文下的表达式时解释方式会完全不同。intA-4d12;首先我们发现赋值表达式左端的intA是32位的根据上下文位宽拓展规则右端的4位常数会被首先拓展至32位注意此时右端的数是一个无符号数因为在d前没有s符号所以会被高位补0拓展为000...01100但由于常数前又有取负运算符所以最后表达式的结果为111...10100符号位取反其他位取反加一即-12的32位补码但此时的表达式结果并不被当做有符号数-12来看而是解释为一个无符号的大正数这同样是因为d前没有s符号。最后将表达式的值赋值给有符号整数变量intA所以这个原来的大整数又被解释为有符号数最后intA的值还是-12。regAintA/3;赋值表达式右端的结果根据有符号数除法的规则得到的结果是-4的32位补码111...11100且解释为有符号数即但之后将表达式的值赋值给了16位无符号寄存器变量根据截断法则高16位被直接截断包括符号位低16位被赋值给regA且被解释为无符号数即regA得到的是1111111111111100即65532。regA-4d12;与intA-4d12;同理赋值表达式右端的无符号4位常数被补0拓展到regA的宽度即16位的0000000000001100又因为常数前有取负运算符所以最后右端表达式的结果为1111111111110100即-12的16位补码但此时的右端表达式结果并不被当做有符号数-12来看而是解释为一个无符号的大正数这是因为d前没有s符号。最后将右端表达式的值赋值给无符号寄存器变量regA被解释为无符号数,即regA得到的是1111111111110100即65524。intAregA/3;赋值表达式右端的结果根据无符号数除法的规则得到的结果是无符号数2184132位因为赋值表达式左侧的intA和常数3都是32位然后将右侧表达式的值赋值给32位有符号整数变量intA但由于此时32位无符号数21841的最高位为0被解释为正数所以最后intA得到的结果还是21841。intA-4d12/3;赋值表达式左端的intA和右端常数3均为32位所以无符号常数4d12首先被补0拓展至32位000...01100然后首先执行取负运算符运算结果为32位无符号数111...101004294967284即然后运算无符号数除法/3得到右端表达式结果为32位无符号数1431655761。然后将右侧表达式的值赋值给32位有符号整数变量intA但由于此时32位无符号数1431655761的最高位为0被解释为正数所以最后intA得到的结果还是1431655761。regA-12/3;此时右端两个常数均被当做32位有符号数然后执行有符号数除法最后得到的结果为有符号数-4的32位补码111...11100然后将值赋给16位无符号寄存器变量regA高16位被直接截断包括符号位低16位被赋值给regA且被解释为无符号数即regA得到的1111111111111100即65532。regS-12/3;右端运算同上所述最后将值赋给16位无符号寄存器变量regS高16位被直接截断包括符号位低16位被赋值给有符号寄存器变量regS且被解释为有符号数即regS得到的1111111111111100即-4。regS-4sd12/3;赋值表达式右侧的3位32位有符号数所以有符号数12被符号拓展为32位有符号数111...11100然后执行取负运算符运算结果为有符号数4的32位补码000...00100然后执行有符号数除法结果为32位有符号数1将其赋值给有符号寄存器变量regSregS的值仍然是1。以上的关键在于符号拓展是在所有运算开始前就确定的否则你会疑惑为什么-4sd12是先被符号拓展至32位111...11100再被取负为000...00100而不是先取负为0100再符号拓展至32位000...00100。关于位宽问题更深入的讨论可以看下面的文章。Verilog基础表达式位宽的确定位宽拓展_verilog位宽_日晨难再的博客-CSDN博客我们可以首先找到被加入上下文环境的操作数a和b作为操作符的操作数是上下文决定的(ab)作为整体位与移位操作符的左边也是上下文决定的(ab)1作为整体是操作符的右操作数也是上下文决定的因此answer因为ab因为三层上下文嵌套都被加入上下文环境中这三个变量的位宽都是一样的所以他们三个在运算前不会有拓展。因此首先执行ab根据规则结果为16位进位被丢失然后再右移一位最高位补0最后赋值给同为16位的answer。很多时候方法很简单。改成ab17b0;_verilog位宽https://blog.csdn.net/weixin_45791458/article/details/128772558?spm1001.2014.3001.5501

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询