verilog勘误系列之-->设计行为仿真和时序仿真不一致分析
描述
最近在vivado中设计一个计算器: 28bit有符号加减法,结果出现行为仿真和时序仿真不一致情况
原因
本篇是由于组合逻辑部分敏感信号使用错误导致
代码
r_a, r_b : 对计算数据a, b的寄存器存储, 也是计算器的数据输入
s_bit : 符号位
cout : 28bit计算器的进位输出 cout[27] : 最高位进位, 用来判断符号以及加法进位
always@(a, b) begin // 1
// always@(r_a, r_b) begin // 2
case({a[27], b[27]} // 1
case({r_a[27], r_b[27]}) // 2
2'b00: s_bit = 1'b0;
2'b01: s_bit = cout[27] ? 1'b0 : 1'b1;
2'b10: s_bit = cout[27] ? 1'b0 : 1'b1;
2'b11: s_bit = 1'b1;
default:s_bit = s_bit;
endcase
end
输出结果代码
always@(posedge clk or negedge rstn) begin
if(!rstn)
result <= 'd0;
else
result <= {s_bit, sum};
end
当条件为1时行为仿真错误,时序仿真正确, 如下

当条件为2时行为仿真和时序仿真均正确 , 如下

说明
此处的敏感信号列表只有当为r_a, r_b时结果才正确,其他情况均错误
分析

t0 : a0, b0 变化,cout0 = 0, case0 = 2'b00, s_bit0 = 0
t1 : r_a0, r_b0 变化并且开始进行计算,cout1 = 0, case1 = 2'b00, s_bit1 = 0
t2 : a1, b1 变化, cout1 = 0, case = 2'b01, s_bit = 1
t3 : r_a1, r_b1 变化开始进行计算, cout3 = 1, case = 2'b01, s_bit = 1
为什么会发生错误呢?
t0 : a, b变化, 但是此时的cout = 0, 并不是因为计算等于0 ,因为此时并未开始计算,所以s_bit也会错误
t1 : r_a, r_b 变化,开始计算,现在的cout是正确的,但是此时并不更新s_bit,因为敏感信号没有变化
t2 : a, b发生变化, 但是此时的cout却是上一个r_a, r_b计算的结果,但是我们在此时对s_bit进行赋值,还是会发生错误
t3 : 终于输出计算结果, 但是此时的s_bit是错误的, 因为cout与case并不同步, case超前于cout一个上升沿(而非一个clk)
所以,在设计的时候一定要分析好时序, 尽管s_bit使用的是组合逻辑, 但是,在仿真过程中出现了case选项和条件值不同步的情况
另外
代码块A
always@(a, b) begin
case({a[27], b[27]})
2'b00: s_bit = 1'b0;
2'b01: s_bit = cout[27] ? 1'b0 : 1'b1;
2'b10: s_bit = cout[27] ? 1'b0 : 1'b1;
2'b11: s_bit = 1'b1;
default:s_bit = 1'b0;
endcase
end
代码块B
always@(*) begin
case({a[27], b[27]})
2'b00: s_bit = 1'b0;
2'b01: s_bit = cout[27] ? 1'b0 : 1'b1;
2'b10: s_bit = cout[27] ? 1'b0 : 1'b1;
2'b11: s_bit = 1'b1;
default:s_bit = 1'b0;
endcase
end
代码块B 等价于 代码块A, 废话,肯定等价
我的意思是,always@(*) 会自动将case(a,b)变成敏感信号,从而变化为always@(a, b), 其他信号变化无用
如果你的控制变量是别的, 综合工具(此处是vivado)会将控制信号变为敏感信号.
本篇结束,大家设计代码一定要注意时序匹配
verilog勘误系列之-->设计行为仿真和时序仿真不一致分析的更多相关文章
- FPGA功能仿真,门级仿真,后仿真的区别
前言 分清楚各种仿真间的关系,工具采用quartus prime16.0,仿真工具采用modelsim10 ae版:项目:led_display; 流程 1.RTL行为级仿真:也叫功能仿真,这个阶段的 ...
- 基于Verilog HDL整数乘法器设计与仿真验证
基于Verilog HDL整数乘法器设计与仿真验证 1.预备知识 整数分为短整数,中整数,长整数,本文只涉及到短整数.短整数:占用一个字节空间,8位,其中最高位为符号位(最高位为1表示为负数,最高位为 ...
- FPGA Verilog HDL 系列实例--------步进电机驱动控制
[连载] FPGA Verilog HDL 系列实例 Verilog HDL 之 步进电机驱动控制 步进电机的用途还是非常广泛的,目前打印机,绘图仪,机器人等等设备都以步进电机为动力核心.那么,下面我 ...
- hdu-----(4514)湫湫系列故事——设计风景线(树形DP+并查集)
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- Hdu 4514 湫湫系列故事——设计风景线
湫湫系列故事--设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total ...
- HDU 4514 湫湫系列故事——设计风景线 树的直径
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4514 湫湫系列故事--设计风景线 Time Limit: 5000/2000 MS (Java/Ot ...
- HDU 4514 湫湫系列故事——设计风景线(并查集+树形DP)
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) To ...
- 一步步实现windows版ijkplayer系列文章之二——Ijkplayer播放器源码分析之音视频输出——视频篇
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- java基础解析系列(十)---ArrayList和LinkedList源码及使用分析
java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...
- 语法设计——基于LL(1)文法的预测分析表法
实验二.语法设计--基于LL(1)文法的预测分析表法 一.实验目的 通过实验教学,加深学生对所学的关于编译的理论知识的理解,增强学生对所学知识的综合应用能力,并通过实践达到对所学的知识进行验证.通过对 ...
随机推荐
- mybatis SQL in() 为什么要在 mapper.xml里 用 foreach
结论: 若存在 in () 语句,要使用 #{} 预编译入参的方式,需要在 mapper.xml里 使用 foreach ======================================= ...
- 永久解决 WSL vm.max_map_count 65530 is too low 的问题
问题 在使用基于 WSL 的 Docker 的时候,启动 ES 总是会出现 vm.max_map_count 65530 is too low 问题,导致容器无法启动,网上答案基本就两种,例如 sta ...
- 多线程系列(二) -Thread类使用详解
一.简介 在之前的文章中,我们简单的介绍了线程诞生的意义和基本概念,采用多线程的编程方式,能充分利用 CPU 资源,显著的提升程序的执行效率. 其中java.lang.Thread是 Java 实现多 ...
- NC19857 最后的晚餐(dinner)
题目链接 题目 题目描述 **YZ(已被和谐)的食堂实在是太挤辣!所以Apojacsleam现在想邀请他的一些好友去校外吃一顿饭,并在某酒店包下了一桌饭. 当Apojacsleam和他的同学们 ...
- MySQL树形结构表设计
两个字段: pid:父级ID parent_ids:所有经过的路径节点ID 这样设计有个好处是,可以查任意节点的所有子节点,从任意节点开始既可以向上查,也可以向下查 select * from ent ...
- STM32F103和STM32F401的ADC多通道采集DMA输出
使用STM32F103和STM32F401CCU6对双轴摇杆(两个电压通道)进行ADC采样并通过DMA读取数值 STM32 ADC(模数转换)工作模式 单次转换模式 In Single Convers ...
- 【Unity3D】发射(Raycast)物理射线(Ray)
1 前言 碰撞体组件Collider 中介绍了 2 个碰撞体之间的碰撞检测,本文将介绍物理射线与碰撞体之间的碰撞检测.物理射线由 Ray 定义,通过 Physics.Raycast / Physi ...
- 【C#】基于JsonConvert解析Json数据
1 解析字典 1)解析为 JObject private void ParseJson() { // 解析为JObject string jsonStr = "{'name': 'zha ...
- Java并发编程实例--2.获取和设置线程信息
常用线程属性 ID: 每个线程的唯一标识: Name: 线程名称: Priority: 线程优先级,从1-10,数字越大优先级越高:不推荐改变线程优先级: Status: 线程状态,包含6种状态:ne ...
- 为什么华为今年疯狂招od?
不知道的大家有没有发现 这两年市场不好公司用人需求紧缩 唯有华子疯狂招人 很多人都听过华为OD 但是具体是什么还是有很多人疑惑 总结以下三个部分: 1.为啥疯狂招od而不是之前的纯"外包&q ...