前不久一位朋友发来一道验证题,虽然题目不是很复杂,但是琢磨了下感觉其中需要掌握的内容还是很多的,正所谓麻雀虽小五脏俱全。下面将对此题涉及的一些内容进行挖掘和示例,与大家分享下。
【问题描述】
如下一段Verilog代码,请根据代码的描述,并结合已知的clk和rst的波形图,画出对应信号的波形。
通过仿真工具得到对应的仿真波形如下。
【仿真波形】
【知识点挖掘】
0.reg和wire都采用的四值逻辑
reg变量在未进行赋值时,其默认值为x,wire默认为z,上图中cnt_nxt之所以仿真开始时为不定态,主要是因为它是由cnt进行运算后得到的,而cnt刚开始就是个x。
1.变量和线网声明时初始化
线网在声明的同时进行赋值操作实际上完成的是一种隐含的连续赋值操作(implicit continuous assignment),即相当于该线网从声明的时候就开始采用了连续赋值操作,此时如果有其他对于该线网的赋值操作,将会导致多驱动;与之相对应的是变量在声明时的初始化,实际上仅仅完成了对于该变量真正的初始化操作,后续对该变量的赋值操作将会覆盖声明时初始化的值。
2.缩减操作符
3.阻塞赋值与非阻塞赋值区别
4.+:和-:位选操作
如果base_expr和width_expr经过位选后超过d本身的位宽,那么读取超出部分将获得不定态表示。其中base_expr是可以在仿真运行过程中按照需要变化的,但是width_expr是必须是确定的。
【示例】
【仿真结果】
5.wire和reg分别在什么时候使用
wire常用于连续赋值语句(连续赋值语句左侧信号)、模块端口(input、output、inout,其中注意output默认为wire),reg常用于过程性赋值语句(当然也可以位于连续赋值语句的右侧)。
6.异步复位、同步复位和异步复位同步撤销
复位主要用于将数字电路中的触发器置为一个确定的初始值上,例如可以是状态机工作于初始状态。而触发器一般情况下分为两种:一种是有复位引脚的,一种是没有复位引脚的,带有复位的触发器占用的面积比没有复位引脚的触发器大一些。一般情况下,处于数据路径上的触发器的初始值无关紧要,此时可以使用不带复位引脚的触发器,以降低芯片的面积。两者之间的优缺点如下。
【同步复位】
l抗干扰性强,可以容忍一定的毛刺,但是前提是这个毛刺不要出现在setup和hold违例区间;
l利于后端人员进行STA分析;
l触发器的复位信号完全同步于时钟源,确保时钟和复位作用下的逻辑电路的一致性;
l复位信号要确保大于时钟周期,避免没有被采样到;
l因为触发器本身不带复位引脚,综合后会增加很多其他的逻辑资源;
l如果时钟信号出现问题,可能会影响到复位;
【异步复位】
相较于同步复位,异步复位有以下特点。
l复位信号不依赖于时钟;
l大多数库提供的触发器都是自带异步复位的触发器;
l异步复位不管产生或撤销复位信号,都是一个异步过程,但是撤销时就出现了问题,如果异步复位在触发器时钟有效沿附近释放,触发器的输出就会进入亚稳态,因此导致复位状态丢失;
l毛刺容易对电路造成干扰,导致不期望的复位产生;
l异步复位需要满足时序要求(recover time、remove time,类似于setup和hold);
为了综合两种复位的优缺点,提出了一种异步复位同步释放的方式,就是指在复位信号到来的时候不受时钟信号的同步,而是在复位信号释放的时候受到时钟信号的同步,即用一个同步器来将异步复位信号转换为同步的复位信号,从而确保复位操作的可控性和稳定性。。其典型结构图如下。
其操作过程如下为当复位信号rst_async_n有效时,第一个D触发器的输出是低电平,第二个D触发器的输出rst_sync_n也为低电平,此时驱动后级方框中的异步复位端口有效,其输出被复位。复位撤销时,rst_async_n经过两级触发器同步后得到的rst_sync_n是与时钟同步的,从而可以实现复位的同步撤销。假设rst_async_n在clk的上升沿时撤除,那么第一个大黄框中的第一级触发器处于亚稳态,但是由于两级触发器的同步作用,第二级触发器的输入为clk到来前第一级触发器的输出,即为低电平。因此,此时第二级触发器的输出一定是稳定的低电平,方框左中触发器此时还处于复位状态。在第二个clk到来时,第一级触发器的输出已经是稳定的高电平了,故rst_sync_n已经是稳定的高电平,此时复位释放,也就是同步释放。
7.~和!区别
首先条件判断语句根据根据判断其关键字后的条件判断表达式结果的真假(非零的结果被认为"真",零的结果对应为"假")来选择不同的条件分支,即可以将条件表达式分为两步来实现:第一步计算条件表达式,第二步判断条件表达式结果;其次,在Verilog中"!"的意思为逻辑非,"~"为按位操作符, "!"主要是对操作数进行逻辑非操作,其预算结果只能为"0"(假)或者"1"(真),"~"主要是对操作数进行按位运算,即对操作数的每一位进行取反操作.但是这里需要注意的是对于一位数据来说,两种操作的结果是一样的,但是如果操作数为多位数据,那么两个操作的运算结果将会不一样.使用逻辑操作符"!",在进行位运算时使用按位运算符"
【示例】
【仿真结果】
从上例仿真结果可以观测到,代码10行没有执行,13行执行。代码中9行的条件判断语句"if(!sig_1)"中的"!sig_1"计算结果为"0",条件表达式对应的分支不会执行,所以仿真过程中并没有显示对应的消息;12行的"if(~sig_2)"中的"~sig_2"计算结果为"2'b10",为非零值,即条件表达式判断的条件为真,所以对应的分支被有效执行;17和20行两个条件表达式都为真,所以对应的分支都被有效执行,但是这时需要注意两个条件表达式的具体计算结果并不相同,17行"!sig_1"计算结果为"1",而20行"~sig_2"计算结果为"2'b11",两者的相同点是均为非零值,所以对于条件语句来说都是为真的条件,所以对应的分支会被执行.在具体使用这两种操作符的时候,一般情况下推荐进行逻辑判断时~"。
作者:nanoty
文章来源:硅芯思见
推荐阅读
- IC设计:ram的应用-使用bitmap实现数据压缩
- Chisel相较于verilog有哪些优势?有哪些开源chisel项目?
- 标准延迟文件和时序报告中的delay value的一致性研究
- 老李带你看菜谱— stx_cookbook 之 加法器 (二)
- 老李带你看菜谱— stx_cookbook 之 加法器 (一)
更多IC设计干货请关注IC设计专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。