首页 > 其他分享 >Verilog 符号问题

Verilog 符号问题

时间:2023-02-26 14:35:12浏览次数:46  
标签:符号 signed 问题 确定 Verilog assign 表达式 op

此贴是我在某讨论区某提问下的回答,现作存档用。

翻了教程中有符号数的处理方法一节,我才发现自己对Verilog中表达式符号的处理的理解仍浮于表面,遂找了IEEE的标准文本研读,现将个人理解分享如下:


首先我们要了解,一个表达式由操作数(Operand)、运算符(Operator)组成,且可以递归定义(详见教程-有符号数的处理方法)。

针对符号,表达式的最终计算主要有两步:①符号确定向内传播

首先根据IEEE 1364-2005Verilog语言标准第5.1节、第5.5节可以了解到,存在如下一些特殊的运算符(包括但不限于),它们的符号仅由其中部分操作数确定:

  • 移位运算符(<<、>>、>>>等)生成的表达式(形如i >>> j)的符号i的符号决定,j恒视作无符号且不参与该表达式的符号确定。
  • 三目运算符生成的表达式(形如i ? j : k)中的i不参与该表达式的符号确定。

其次,各类常量的符号性也在标准文本中定义:

Decimal numbers are signed.

Based_numbers are unsigned, except where the s notation is used in the base specifier (as in
"4'sd12").

比如0等常量是有符号的,而4b'02'd0等给定基数形式的常量是无符号的(形如4'sd12的除外,为有符号常量,其中s即表示Signed)。

再看标准文本对符号确定的解释:

— For nonself-determined operands, the following rules apply:

    — If any operand is unsigned, the result is unsigned, regardless of the operator.

    — If all operands are signed, the result will be signed, regardless of operator, except when
specified otherwise.

个人对其理解为:如果一个表达式在排除不参与其符号确定的操作数后,剩下的子表达式中任意一个被确定为无符号,那么整个表达式都被确定为无符号,否则有符号(与向内传播相反,符号确定这一过程是由内向外的)。一句话,就是Verilog偏爱无符号。


看完了第①步符号确定,现在开始向内传播,依然是标准文本:

— Propagate the type and size of the expression (or self-determined subexpression) back down to the
context-determined operands of the expression. In general, any context-determined operand of an
operator shall be the same type and size as the result of the operator.

— When propagation reaches a simple operand as defined in 5.2 (a primary as defined in A.8.4), then
that operand shall be converted to the propagated type and size. If the operand must be extended,
then it shall be sign-extended only if the propagated type is signed.

这部分与教程解释一致:在确定整体表达式的符号性后,将确定好的符号性由外向内地传递给上下文决定的子表达式(自决定的子表达式不受影响)。类似递归的过程,遇到原子表达式则强制转换原子表达式的符号。


如果你还是觉得难以理解,那就直接通过一个例子来感受一下:

1 ? $signed(a)>>>b : 4'b0

首先Verilog不存在表达式短路这样的优化(至少ISE仿真时没有),所以我们不能把该表达式进一步简化成$signed(a)>>>b,仍然要看整体。

符号确定:首先1不参与符号确定,排除;$signed(a)>>>b4'b0,其中4'b0显然无符号,$signed(a)>>>b符号由$signed(a)决定,是有符号的;则表达式1 ? 有符号 : 无符号,根据Verilog对无符号的偏爱,表达式整体无符号。

向内传播:首先1不受影响,排除;原子表达式4'b0本就是无符号,无需转换;$signed(a)>>>bb不受影响,再次递归进入$signed(a),是有符号原子表达式,强制转化成无符号,即$unsigned($signed(a))

最终表达式等价a >> b,相当于仍对a进行逻辑右移。

太长不看省流速通版:

一眼定真法(用于确定给定表达式的结果):扫描表达式中不在$signed()中也不属于不受影响的无符号原子操作数,找到一个则直接鉴定整个表达式无符号。如果这些操作数一个都找不到,恭喜,直接按正常思维就能算对表达式;如果鉴定为无符号,那么就要把表达式中所有不属于不受影响(几乎就是所有)的有符号原子操作数强制转化成无符号再计算。

狂暴括号法(不推荐,用于自己写代码):如果你不能确定到底哪些会变成无符号,那就尽一切办法阻止它

assign a = ((b + c) >>> d) + e;  // 原式
assign a = $signed($signed($signed($signed(b) + $signed(c)) >>> $signed(d)) + $signed(e));  // 狂暴法
assign a = (($signed(b) + $signed(c)) >>> d) + $signed(e); // 温和法

此外还有分离变量、自己实现易出问题的部分等方法(见教程,都用于自己写代码)。


最后提一嘴$signed(),与$unsigned()一样是一类系统函数,不仅能强制转换符号性,还能起到类似屏障的作用,函数内部的表达式是单独计算的,既不影响函数外部符号的确定,外部符号向内传播时也不会进入函数内部,这点与教程推荐的分离变量的作用一致。因此可以把$signed(a+b)看成一个原子表达式或变量/常量,但其本身依然有可能受到向内传播的影响,被转换成无符号形式,失去转换效果,但能保住其内部的表达式的计算结果
比如下面的例子(修改自教程):

// wrong !!!
assign out = op == 0? in_a + in_b:
             op == 1? in_a - in_b:
             op == 2? in_a >> in_b:
             $signed(in_a) >>> in_b;
/*
 * 比起给每个变量都加一层$signed()的方法,
 * 分离变量法与用$signed包裹敏感的中间量
 * 是更优的选择。
 */
// correct 分离变量法
wire [WIDTH-1:0] shift;
assign shift = $signed(in_a) >>> in_b;
assign out = op == 0? in_a + in_b:
             op == 1? in_a - in_b:
             op == 2? in_a >> in_b:
             shift;
// correct 用$signed包裹敏感中间量
assign out = op == 0? in_a + in_b:
             op == 1? in_a - in_b:
             op == 2? in_a >> in_b:
             $signed($signed(in_a) >>> in_b);
// correct 你甚至可以用$unsigned
assign out = op == 0? in_a + in_b:
             op == 1? in_a - in_b:
             op == 2? in_a >> in_b:
             $unsigned($signed(in_a) >>> in_b);


个人总结能力有限,如有不当、遗漏之处还请谅解或指出。

标签:符号,signed,问题,确定,Verilog,assign,表达式,op
From: https://www.cnblogs.com/coder014/p/17014591.html

相关文章

  • 关于iView手动清除Select选择器内容的问题
    this.$refs.refName.clearSingleSelect()以上可以看出如果要生效清楚事件就必须设置好那个clearClose按钮tooltip:以上的方法会触发当前选择器的change事件,所以在监听c......
  • 解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not fou
    org.apache.ibatis.binding.BindingException:Invalidboundstatement(notfound)问题,即在mybatis中dao接口与mapper配置文件在做映射绑定的时候出现问题,简单说,就是接口......
  • 上上签文件手动签自动签盖章失败问题
    前言调用上上签SDK,发起文件合同手动签,盖章后失败,无印章,自动签后,依然无印章,下载合同预览长这样,可以看出实际上改了章,但是就是没有矢量图电子签章原因一个非常细微的问题,文件......
  • 【FPGA】Verilog:实现十六进制七段数码管显示 | 7-Segment Display
    写在前面:本章主要内容为理解七点数码管显示的概念,并使用Verilog实现。生成输入信号后通过仿真确认各门的动作,通过FPGA检查在Verilog中实现的电路的操作。Ⅰ.前置知识......
  • 【Java】“com.alibaba.fastjson.JSONObject cannot be cast to“报错问题
    【Java】修复"com.alibaba.fastjson.JSONObjectcannotbecastto"报错问题报错如下:java.lang.ClassCastException:com.alibaba.fastjson.JSONObjectcannotbecasttoc......
  • pat乙级链表问题
    链表题目:一开始以为要按照链表那样一个一个搞,看完这个后思路清晰:1025链表一连a三题链表题。在输入完链表之后,遍历链表使用另一个数组(可以是指针数组也可以是节点数组)记录......
  • uni app 问题记录 Cannot read property 'state' of undefined
    一、当我在调用store时报错:Cannotreadproperty'state'ofundefined具体代码如下图 解决过程:各种尝试有点无计可施,感谢网友哪种分享,给了我解决的思路,所以我把我......
  • 解决d3dcompiler_33.dll找不到的问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或者损......
  • 一些概率相关的问题
    一:\(n\)个随机整数\(a_i\in[1,w]\),且\(a_i\neqa_j\),求第\(c\)大数的期望\[\begin{aligned}E(a_c)\sum_{k=1}^w\dbinom{k-1}{c-1}\dbinom{w-k}{n-c}&=\sum_{k=1......
  • jupyter notebook的设置问题
    jupyternotebook的设置问题更改主题、字体等在命令行中输入pipinstalljupyterthemes安装主题安装和更新成功以后,可以查看可用主题:jt-l设置主题,字体,字体大小,宽......