表达式位长 对结果的影响

本文是学习魏家明老师的《Verilog 编程艺术》之后所记录的关于表达式的位长对结果的影响的笔记。

在程序中往往必不可免的需要用到简单的计算,简单的如+ - ,复杂的有**(幂运算)。

那么有时运算的结果却和理论不符,这是什么原因呢???很可能就是位长的原因。

且看以下几个例子:

1、中间结果因为位长不够而出现丢失:

    reg   [3:0]  a;
    reg   [3:0]  b;

    reg  [3:0]  c;
    reg  [3:0]  d;
    reg  [4:0]  e;

   always @(posedge clk )
     begin
        c = (a + b) >>1;
        d = (a + b +0) >>1;
        e = (a + b) >>1;
      end

     initial
       begin
          a = 0;
          b = 0;
          clk = 0;
          f <= 0;

          #(10*t)   a  = 6;

          #(10*t)   b  = 6;

          #(10*t)   a  = 2;

          #(10*t)   a  = 13;
          #(10*t)   b  = 10;
      end

则仿真图位:

结果可以看出当a+b < 16的时候c、d、e的结果都相同,但是当a+b > 15之后,c、d、e的结果就不怎么相同了?什么原因呢?

先来分析c的值,因为a和b都是4位(最大值为15),运算过程都按4位进行,多于4位的中间值的高位被舍弃,所以结果只与中间值的低4位有关,当a+b = 13+6 = 19(1 0011)时,中间值其实为4‘b0011,然后右移一位为4’b0001故结果为1;

而对于d来说,因为有0(未指明位数,默认32位)的参与,虽然没有改变中间值的大小但是改变了中间值的位数,所以中间值应为32bit,右移一位后还为32bit,然后取最后4bit,结果为4‘b1001;

最后对于e,因为位数为5位,比啊,a、b都多一位,所以中间值按照e的来存储,结果也是正确的。

总结:加法计算时,结果最好要比加数最多的位再多一位。中间值的位数由等式左边的和的位数和等式右边的最多位数的加数共同决定。

2、 显示命令的数据由算式中的最长位决定。

    reg   [3:0]  a;
    reg   [3:0]  b;
    reg   [4:0]  c;

   initial
      begin
          clk = 0;
          a = 1;
          b = 4‘d4;
          c = 5‘d19;

          #(10*t)  $display("answer = %b",a?b:c);

       end

从上面可以看出,answer的值肯定是b,而b是4bit,则结果是4’b0100吗??反正结果为:

结果是4,但是竟然有5位,这是怎么回事??因为a?b:c;中位数最多的是c,有5bit,所以结果也是5bit了。

另外:表达式的结果不仅与位数有关,还与表达式本身有关系。

时间: 2024-10-09 20:39:26

表达式位长 对结果的影响的相关文章

JAVA随机的32位长的字符串

CommonUtils类依赖的jar包:commons-beanutils.jar.commons-logging.jar uuid()方法 * 返回一个随机的32位长的字符串 * 用途: * 可以用来做id等各种不能重复的变量,数据库表中的主键不能重复的,它就是不重复的! @Test public void testUnid() { String s=CommonUtils.uuid(); System.out.println(s); } 作用:把一个map中的数据封装到javabean中 *

用python实现子网掩码地址与位长的相互转换

某日,使用centos7,发现网络配置时,子网掩码需要手动转换:因为centos7的网络配置方式为: nmcli connection enp4s0 modify ipv4.methord manual ipv4.address "192.168.1.120/24" ipv4.gateway "192.168.1.1" ipv4.dns "223.5.5.5" 其中没有子网掩码的配置项.于是,写一函数,实现子网掩码和位长的相互转换. 一:子网掩码

Json.NET特殊处理64位长整型数据

很多ASP.NET项目,尤其是使用了Ajax的项目,常常需要返回JSON格式的数据..NET框架从3.5版本开始提供了JSON的序列化和反序列化工具,不过个人感觉不太好用,后来找了第三方的Newtonsoft.Json来用.再后来,在MVC4中,微软已经默认使用Json.NET(Newtonsoft.Json)来处理JSON数据了. JavaScript数值精度是32位,如果整数数度超过32位,就会被当作浮点数处理.换句话说,如果从服务端生成的JSON,某个值是64位整数,传到前端JavaScr

linux源码分析之位长定义 -- bitsperlong.h

我们知道,在Linux内核中,不同CPU里面,不同CPU的字节序定义不同. 本节年内容主要是讲的是:不同CPU里面,各自的位长定义也是不同. 本次用于分析的 Linux 内核版本为: linux--3.0.0-12. arch/XXX/include/asm/bitsperlong.h:不同CPU(XXX)的位长定义 1)ARM(XXX=arm): #include <asm-generic/bitsperlong.h> (2)PowerPC(XXX=powerpc) #ifndef __AS

Delphi 串口通信数据位长度对传输数据的影响 转

针对串口通信,关于设置数据位长度对通信的影响,如图: 在串口数据通信中,会看到串口参数设置.其中“数据位”设置,共有四档选项,分别是8.7.6.5.那么改变这个参数会对数据的传输有什么影响呢? 我来做个试验,通过示波器观察通信过程,能够分析结果如下: 例如数据位设置为5.那么就相当于规定了每个传输字节只能由5个二进制位来表示,例如:11111,10110,01110等.也就是说,这个RS232口只能发送00000~11111这个范围内的数,如果发送一个比11111还大的数,例如11111+1,也

转载——串口通信数据位长度对传输数据的影响

本文来自:https://blog.csdn.net/petershina/article/details/8612357 针对串口通信,关于设置数据位长度对通信的影响,如图: 在串口数据通信中,会看到串口参数设置.其中"数据位"设置,共有四档选项,分别是8.7.6.5.那么改变这个参数会对数据的传输有什么影响呢? 我来做个试验,通过示波器观察通信过程,能够分析结果如下: 例如数据位设置为5.那么就相当于规定了每个传输字节只能由5个二进制位来表示,例如:11111,10110,0111

对于表达式比较长的 for 语句和 if 语句

对于表达式比较长的 for 语句和 if 语句,为了紧凑起见可以适当地去 掉一些空格,如 for (i=0; i<10; i++)和 if ((a<=b) && (c<=d)). 1 #include <iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<process.h> 5 /* run this program using the console

3DES,32位长秘钥加密

一般3des加密的秘钥是一个24位的字节数组,但是很多遇到32位字符串秘钥,不知道怎么去用,其实只是经过几步转化就可以了.希望这篇文章对大家有帮助或者带来灵感 比如: 秘钥:33333333333333333333333333333333 要加密内容:06111111FFFFFFFF 加密后内容:66322DAA27A95807 java代码 import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypt

Linux - Shell - 算数表达式 - 位运算

概述 shell 中基于 $(()) 的 位运算 背景 复习 shell 脚本 凑数吧 准备 环境 os centos7 1. 位运算 代码 #!/bin/bash # 位运算 arg1=2 arg2=8 # 位运算 # 1. << var1=$((arg1 << 2)) echo $var1 # 2. >> var2=$((arg1 >> 1)) echo $var2 # 3. & var3=$((arg1&arg2)) echo $var