文章目录
- 前言
- 一、竞争和冒险
- 1、定义
- 2、判断方法
- 3、消除方法
- 4、滤除毛刺的方法
- 二、延时语句分类
- 1、阻塞赋值左侧延时
- 2、阻塞赋值右侧延时
- 3、非阻塞赋值左侧延时
- 4、非阻塞赋值右侧延时
- 三、比较及举例说明
- 1、阻塞右侧延时和非阻塞右侧延时的区别
- 2、举例
- 三、timescale 时间单位/时间精度
- 1、作用范围
前言
2023.8.10
2023.9.8
一、竞争和冒险
1、定义
竞争
:由于信号经不同路径达到同一点的时间有先后顺序冒险
:由于竞争现象的存在导致输出发生瞬间的错误
有竞争不一定有冒险,有冒险一定有竞争
2、判断方法
- 卡诺图:卡诺图相切处没有其他卡诺圈
- 代数法:存在相反变量就有可能存在竞争和冒险
- 实验法:通过示波器进行观察
3、消除方法
- 修改逻辑设计,增加冗余项
- 输出端并联电容进行滤波
- 使用格雷码
- 信号同步处理
-
信号延迟
:延迟较小的支路加上毛刺宽度的延迟可以进行消除
4、滤除毛刺的方法
- 小于一个周期的毛刺:把信号打两拍,把打一拍后的和两拍后信号相或
- 一个周期到两个周期之间的毛刺:打三拍,把打拍后的信号相或
二、延时语句分类
1、阻塞赋值左侧延时
在10ns后,把10ns时刻的b+c值赋值给a,a拿到的是b+c的最新值
always@(*)
#10 a = b + c;
2、阻塞赋值右侧延时
先把0时刻的b+c值暂存起来,在10ns后,把0时刻的b+c值赋值给a
always@(*)
a = #10 b + c;
等效于
always@(*)
temp = b + c;
#10 a = temp;
如果0-10ns之间b、c的值发生了改变,那么不会影响a的值
3、非阻塞赋值左侧延时
在10ns后,把10ns时刻的b+c值赋值给a,a拿到的是b+c的最新值(和第一种情况相同)
always@(*)
#10 a <= b + c; //拿到的是最新值
4、非阻塞赋值右侧延时
只要b或c发生改变,引起always触发,就会把当前触发时刻的b+c赋值给a
如果b和c在0-10ns之间发生改变,改变也会体现在从改变时刻开始往后的10ns
也就是输出会随着输入变化
,只是有10ns的延时
always@(*)
a <= #10 b + c;
三、比较及举例说明
1、阻塞右侧延时和非阻塞右侧延时的区别
前者会忽略中间变量的改变,后者输入随输出改变
2、举例
第一个:
a = 0;
b = 0;
q = 0;
#5 a <= 1;
b <= 1;
q <= a & b;
在5ns时刻,三个非阻塞赋值并行运行,q的值为0
如果改成如下方式,则6ns时刻,q的值为1
#1 q <= a & b;
第二个:
前者会分别暂存此刻的a和b,等到5ns后再分别赋值给a和b
后者则在5ns分别给a和b赋值,会发生竞争冒险
fork
a = #5 b;
b = #5 a;
join
fork
#5 a = b;
#5 b = a;
join
三、timescale 时间单位/时间精度
- 时间精度要小于时间单位
- 两者都必须为整数,1,10,100等数值
- 单位是s、ms、us、ns、ps、fs
1、作用范围
声明之后会影响后面所有模块的延时值
例1:时间单位1ns,延迟时间可以是三位小数的实数
如#1.5565,就会变成1.557ns
`timescale 1ns/1ps
例2:10us/100ns=100,延迟时间可表示为两位小数的实数
`timescale 10us/100ns