13hope:
个人理解,Verilog本身只是“建模”语言。具体到阻塞/非阻塞,只规定了两种赋值语句的行为。所以无论怎么写,仿真器和综合器都不会报错。但是存在两个问题,所描述的行为是否有物理电路与之对应;电路行为在仿真阶段和综合后是否一致。 像是电平敏感always快内使用多个多个非阻塞赋值就没有意义,仿真结果不可信
 
wjcdx:
> 个人理解,Verilog本身只是“建模”语言。
 
Verilog是个大杂烩(中性,非贬义),包含了支持验证、综合、测试的语法结构,比如:initial, repeat, forever, task等。
 
> 具体到阻塞/非阻塞,只规定了两种赋值语句的行为。所以无论怎么写,仿真器和综合器都不会报错。但是存在两个问题,所描述的行为是否有物理电路与之对应;电路行为在仿真阶段和综合后是否一致。
 
感谢提醒,可能就是与综合后电路一致的原因。Verilog发展历经了好多个版本,有可能是历史原因。
 
不过,最终要求的不是你建模的电路和综合后的电路一模一样,否则不是要写RTL代码,而是要画版图了。最终的要求是综合后的电路符合RTL描述的模型,行为一致。
 
RTL是一个抽象的建模层次,而不是物理的建模层次,无法与综合后的电路完全对应:比如+-x÷这些operators都不是使用电路描述的,但综合后却有电路,怎么对应呢?
 
还有综合器要对RTL的代码做优化,有一些电路不必要的会被优化掉,效率不高的会被优化成更高效的方式。
 
再有,很多时候使用的是工具提供的库里面的模块,这个是黑盒的,也不清楚里面的电路。
 
今天发现一个2001版本的新特性,可以佐证我的观点:
 
从这个里面可以看到,register不是物理的寄存器(DFF)。而是一个变量数据类型(variable data type).
但是又遗留了明显针对物理寄存器的非阻塞赋值,做的不彻底。NBA增加了学习的难度,进而在使用中也会产生问题。
 
建模方法(Modeling Methodology)应该尽量简单,把这部分工作放在综合器里面去做更合适。能写综合器的人,都是对电路特性更了解的人,出错的概率更小。
 
RTL层建模需要的只是对变量赋值(variable assignment),甚至连 连续赋值 和 过程赋值 都不需要区分。这样的区分有助于理解,却不是必须。
 
> 像是电平敏感always快内使用多个多个非阻塞赋值就没有意义,仿真结果不可信
 
这个链接里有很多NBA在一个always块内:
https://github.com/alexforencich/verilog-ethernet/blob/master/rtl/arp_64.v
  1. cache_query_request_ip_reg <= cache_query_request_ip_next;
  2. outgoing_eth_dest_mac_reg <= outgoing_eth_dest_mac_next;
  3. outgoing_arp_oper_reg <= outgoing_arp_oper_next;
  4. outgoing_arp_tha_reg <= outgoing_arp_tha_next;
  5. outgoing_arp_tpa_reg <= outgoing_arp_tpa_next;
wjcdx:
> 像是电平敏感always快内使用多个多个非阻塞赋值就没有意义,仿真结果不可信
昨天没看清楚,给的例子是边沿敏感。你说的是电平敏感。
 
其实,“电平敏感”这个词不准确,准确的说法是“电平变化敏感”:
  1. always @(a, b, c)
  2. begin
  3. if (a) begin
  4. end
  5. end
 
这个并不是只在a为1时执行,在a为0时也执行。所以不是对a的高电平敏感,而是对a的电平变化敏感。
 
always在Verilog里面没有区分,在SystemVerilog里面区分的就比较细。上面的always在SystemVerilog里面应该是always_comb, 而不是always_seq,综合出来是组合电路,里面使用的是wire,而不是reg.
 
对wire使用非阻塞赋值是不正确的。这也是我为什么说在RTL建模时把NBA这个概念拿掉的原因:理解时容易混淆,使用时容易出错。
 
13hope:
很细致的回复,基本都赞同。只是最后一点,GitHub上的代码是always @(posedge clk)内部,用了多个<=赋值当然没问题,综合后就是一堆DFF。
 
至于我说的“没意义”,比如下面代码,a “电平变化敏感” (双沿),首先,想描述的一定是组合逻辑。其次,语义上非阻塞赋值是在当前仿真step之后同时给temp和b赋值,也就是说a值改变触发该always,其第二条在对temp采样时,temp还未更新,所以b始终等于a上一次“变化前”的值。这个“行为”没有任何组合电路与之对应(组合电路没有记忆功能)。
  1. always @(a) begin
  2. temp <= a;
  3. b <= temp;
  4. end
 
至于综合后,b确实是一根wire直接连到a,temp可能被优化掉,但仿真结果与综合不一致。
Verilog非常容易写出仿真与综合行为不一致的电路,所以有很多guideline帮助构建可综合电路。
 
 
wjcdx:
如果不存在NBA,可能就不会存在这样的问题了。
如果不存在NBA,则continuous和procedural assignment都只是简单的使用等号“=”来表示。
 
1.
  1. always @(a) begin
  2. temp = a;
  3. b = temp;
  4. end
 
这样的写法意思是,如果a变化,则把a的值赋值给temp, 然后在把temp的值赋值给b。
这是简单的组合逻辑,可以化简为:
  1. assign b = a;
 
 
2. 如果想让b每次都取a上一次的值,则可以写成:
  1. always @(a) begin
  2. b = temp;
  3. temp = a;
  4. end
 
仿真和综合针对这个写法,不清楚是否一致?
 
仿真器想必不会出错,综合器如何决定这两条赋值语句能否调换顺序呢?要做数据流分析。
如果两条赋值语句各自的left hand side与对方的right hand side存在关联,或者反过来存在关联的话,就说明存在顺序关系。如果没有,则不存在顺序关系,两条赋值语句可以分开综合。
 
综合器把这个事情做了以后,就可以把建模人员解放出来,只关心值的传递这个核心问题即可,
而不用考虑仿真时值如何赋值,综合后电路如何赋值,这样的问题。
 
建模人员保证值传递的逻辑时正确的。仿真器保证仿真的正确性,综合器保证综合出的电路符合模型要求的值传递逻辑。
各司其职,正确的人做正确的事,专业的人做各自专业领域的事,这样可以减少出错。
 
当然,建模人员了解仿真器和综合器的工作原理是有益的。
 
回到这个例子上来,如果建模人员考虑的是变量之间的值如何传递,
而不是仿真时什么时候采样,什么时候赋值,出错的可能性就小多了。

非阻塞赋值(Non-blocking Assignment)是个伪需求(2)的更多相关文章

  1. 非阻塞赋值(Non-blocking Assignment)是个伪需求

    https://mp.weixin.qq.com/s/mH84421WDGRb7cuU5FEFIQ Verilog的赋值很是复杂,包括: 1. Continuous assignment; 2. Pr ...

  2. 【Verilog HDL】赋值语句之阻塞赋值方式与非阻塞赋值方式

    刚开始接触Verilog HDL语言时,这种硬件描述语言有一点与软件的程序设计语言直观上的最大区别大概就是这个赋值语句了(这里只是强调直观上的最大区别,事实上的最大区别并非如此). Verilog H ...

  3. FPGA之阻塞赋值与非阻塞赋值

    Verilog语言中讲的阻塞赋值与非阻塞赋值,但从字面意思来看,阻塞就是执行的时候在某个地方卡住了,等这个操作执行完在继续执行下面的语句,而非阻塞就是不管执行完没有,我不管执行的结果是什么,反正我继续 ...

  4. Verilog之阻塞赋值非阻塞赋值

    verilog设计进阶 时间:2014年5月6日星期二 主要收获: 1. 阻塞赋值与非阻塞赋值: 2. 代码测试: 3. 组合逻辑电路和时序逻辑电路. 阻塞赋值与非阻塞赋值: 1. 阻塞赋值" ...

  5. 07-阻塞赋值与非阻塞赋值原理分析——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线--普利斯队长精心奉献   实验目的:掌握阻塞赋值与非阻塞赋值的区别 实验平台:无 实验原理:     阻塞赋值,操作符为"=","阻塞"是指在进程语句( ...

  6. 阻塞赋值与非阻塞赋值(verilog篇)

    阻塞赋值与非阻塞赋值(verilog篇) 2017-09-30 竹海 相约电子ee 相信刚刚接触verilog的读者,多少对阻塞赋值和非阻塞赋值仍有一些困惑.笔者在这篇文章,带领大家深入的理解这两者的 ...

  7. 阻塞赋值-非阻塞赋值(LUT,FDC,BUF...)

    一.看RTL级综合网络 1.1 FDC FDPE FDRE FDSE均是XILINX FPGA片上资源中四种不同的触发器,具体功能可直接百度 1.2 LUT是实现组合逻辑功能的一张真值表,根据输入值直 ...

  8. stm32中阻塞模式和非阻塞模式 in blocking mode 与 in non-blocking mode区别

    阻塞模式和非阻塞模式...... 我的理解是:阻塞模式就像是一个延时函数,当这个函数没处理完那么,所有的按照流程需要执行的代码都不会被执行,要等到这个延时完成,类似 平时看书上写的LED灯闪烁,用的d ...

  9. verilog阻塞与非阻塞的初步理解(二)

    将阻塞模块改为下述代码: module blocking(clk,a,b,c); :] a; input clk; :] b,c; :] b,c; always @(posedge clk) begi ...

随机推荐

  1. CDH删除节点(安全)

    经过验证,最快最安全的删除CDH节点的方式,简单概括如下: 1.选中该机器,并停止该机器上的所有角色 2.去对应的服务中删除该机器中每一个角色 3.通过命令行,关闭该机器的的agent服务,并将该机器 ...

  2. 【Linux基础总结】Shell 基础编程

    Shell 基础编程 重启虚拟机遇到磁盘损坏如何解决 Shell编程中变量的声明.引用及作用域 Shell程序 概述 以文件形式存放批量的Linux命令集合,该文件能够被Shell解释执行,这种文件就 ...

  3. RHCSA 第一题 修改root密码

    题目要求 请修改系统的root帐号密码为redhat,确保能够使用root帐号登录系统.说明:server0 的IP为172.25.0.11/24desktop0的IP为172.25.0.10/24 ...

  4. Mysql常用sql语句(14)- 多表查询

    测试必备的Mysql常用sql语句,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1683347.html 前言 ...

  5. MATLAB1127(传递函数)

    sys=tf(400,[1,50,0]) sys = 400 ---------- s^2 + 50 s 其中,tf()函数的用法.   传递函数 dsys=c2d(sys,ts,'z') dsys ...

  6. 04JAVA基础数组

    概念 存储同一种数据类型的多种元素的容器 数组初始化 动态初始化 设定数组长度,系统自动分配默认值 int[] arr = new int[3]; 静态初始化 给定数组默认值,系统自动分配长度 int ...

  7. linux wc 的用法-linux 下统计行数、单词数、字符个数

    linux wc 的用法-linux 下统计行数.单词数.字符个数   wc : wc -l 统计有多少行 wc -w 统计有多少个单词 wc -c 统计有多少个字符

  8. PHP中面向对象特性实现

    PHP近些年来成为全球最流行的网页编程语言,该语言以弱类型.易兼容.门槛低.开发快.功能强著称,且听别人这么说,我在有了c和c#基础后学习PHP过程中也并不是很顺利,该语言的一些特殊的语法规则又是让我 ...

  9. java ->大的数据运算(BigInteger)

    大数据运算 BigInteger java中long型为最大整数类型,对于超过long型的数据如何去表示呢.在Java的世界中,超过long型的整数已经不能被称为整数了,它们被封装成BigIntege ...

  10. live2d web端加载moc3模型

    大佬博客链接:https://blog.csdn.net/weixin_44128558/article/details/104792345 照着大佬的博客做一下,可以先学会怎么生成bundle.js ...