《Verilog HDL高级数字设计》一书第5章

本章主要讲解了怎么用verilog做功能的行为建模。

5.1节 行为建模的概念;行为建模区别于门级(结构级)建模。纯门级建模的设计中只包含AOI(and or invert)基本门操作,简单    的功能尚可通过一定的布尔表达式进行编写,复杂的功能就比较困难。而且太执着于算法功能的门级映射会拖慢整个设计进度,也体现不出verilog HDL建模的优势。行为建模需要花费更多的时间加以综合。另外实际的设计中可能门级和行为级建模混合出现。

5.2节 verilog中变量的基本类型;不是所有的声明reg类型变量都会被综合成DFF(D-flip-flop,D触发器)或者Register。integer类型少32位。其他类型这里不赘述。

5.3节 用assign语句根据布尔表达式实现组合逻辑

5.4节 本节给出了一个数字逻辑设计的三大表现形式:电路原理图,真值表,布尔方程和verilog HDL建模元素的对应。电路原理图对应verilog的门级描述,真值表对应于用户定义原语(UDP),布尔方程对应连续赋值语句(其实还包括带电平敏感的always块)。另外本节给出了下面代码段的一种写法,即wire 类型声明时赋值。我们不建议这样写。会给阅读和维护带来困惑。

module(...)

wire #10 y1 = x1 & x2;

endmodule

5.5节 verilog条件赋值语句和assign语句实现简单锁存器;(注意FPGA主要资源 是DFF而没有Latch;CPLD里面的Latch较多,ASIC设计里也可以专门设计Latch,因设计不同而不同)。本节作者示范了一个不可综合的Latch如下代码段。如下:

assign q=set ~& q_inv;
assign q_inv=rst ~& q;

上面是完全按照基本锁存器的电路原理 与非门的交叉耦合 编写的verilog门级建模。但是这种写法却不能综合出来。要想可综合,要么按照真值表写原语,要么写成行为级。行为级建模Latch代码如下:

assign q=enable ? data : q;

行为级只关心你要实现的功能直接的样子是什么样,而不关心具体的门级映射是什么样的。

5.6节具体讲阻塞和非阻塞赋值

5.7节用always块建模边沿触发逻辑;这里作者说了一点:verilog语言允许在一个事件表达式中由电平敏感和边沿敏感的变量混合使用,但是它是不可综合的。因此请不要这样写,一般有这样的需求,还是所有的敏感变量都退化到电平敏感而不是边沿敏感。如果确定电平敏感的变量是单比特并且对某个存储器数据进行置位或清零,那么可以都提升到边沿敏感——因为这就是设计中常用的复位写法;

5.8节介绍什么是RTL(Register Transmit Level,寄存器传输级)。作者点明了RTL级设计的三个主要元素:寄存器,数据通道,控制器。其中寄存器用来存储数据,数据通道包括输入和能够引起内部状态发生变化的信号,控制器控制数据流怎么处理以及状态迁移:即数据在寄存器之间怎么流动变化,亦即数据的“寄存器传输”。本节还给了一个重要的例子,如下代码段所示:

//using verilog -2001 standard
module shift_reg
(
input E,clk,rst,
output A
)
reg B,C,D;
always @(posedge clk,posedge rst)
begin
    if(rst)
        begin
            A=0;
            B=0;
            C=0;
            D=0;
        end
    else
        begin
            A=B;
            B=C;
            C=D;
            D=E;
        end


end


endmodule

这个模块正确的实现了一个四位移位寄存器的电路,并且是可综合的,工作正常的。许多verilog初学者想笔者一样上来一看就会很纳闷,为啥边沿触发的always块里面使用阻塞赋值?首先要明确一点always块里不管什么敏感列表阻塞和非阻塞都可以写,但是不一定能实现你想要的功能哦。首先说电平触发过程块里用非阻塞,使用非阻塞和阻塞一般没有什么区别,并且都是可以综合的,如果将上面代码中的always块的敏感表换做是电平触发的,那么,在综合的时候会把B,C,D全部优化掉。而在边沿触发中,阻塞和非阻塞却大不相同,如果用阻塞来实现系统功能,你一定要想好信号的赋值顺序,稍微不慎,可能实现的功能就大不相同。例如上面的代码段实现的是一个时序电路:移位寄存。如果你更改ABCD四个信号人一个顺序,实现的电路就会大不相同。所以在这里总结一下:不管是电平触发还是边沿触发,里面都可以出现阻塞和非阻塞,到底用哪个更好我们从下面三个方面考虑:(1)可实现需求功能,如果不能实现你想要的功能肯定要切换成另一赋值类型;(2)实现的便宜性,比如你用上面的阻塞赋值虽然实现了移位寄存的功能,但是你却要小心翼翼的安排他们的赋值顺序,实现起来就不那么“便宜”。(3)可阅读性(可维护性)。所以大家一般是组合用阻塞,时序用非阻塞。因为本身阻塞和非阻塞就是用来建模一般的组合电路器件和时序电路器件的。

另外本节书中还讲解了算法级的建模,应该讲这是一个设计当中最高层的建模了。但是我们却不建议你什么设计都从 算法层面上来直接“随想随写”,因为我的导师告诉我一句话,直接用算法级建模,很可能的结果是你的资源不够用了,或者压根就不存在实现性。也就是说,如果设计的时候你想着可以采用硬件的思路去替代,去做优化,很可能同样的功能,RTL级实现可以比算法级省很多很多的资源。算法级的建模大多适合用来做前期的算法功能验证,然而实际上现在的高级算法仿真工具比较成熟,高级语言也比较多,所以算法的仿真,大多考虑用matlab,c,或者python。相比verilog的算法建模,这些高级语言构建算法更快更方便;

最后,在本节,书中还对比了一下门级,寄存器传输级,算法级实现的区别。

5.9节作者以多路复用,解复用器,译码器为例介绍他们的RTL建模

5.10节作者用LFSR为例来构建时序电路的RTL模型;

5.11介绍循环,以及利用循环和parameter来构建可配置参数的模块。作者还区别了循环和always(对于初学者这两点可能会搞混淆)。主要区别是always是并发,循环是顺次执行。还介绍了disable语句,disable语句不是一个100%可综合的语句,视综合工具而定。

5.12 多循环状态机。

5.13 函数与任务,关于这个话题可以参考笔者的另一篇博客或者在网上自己找一篇资料一看便很明了,不赘述

5.14ASM图;

5.15 ASMD图,对应了RTL建模的三个要素。

5.16计数器,移位寄存器,寄存器组的ASMD图。

5.17 去抖和亚稳态,以及异步信号怎么本地同步化。感觉作者对这个很重要的知识点没有讲清楚,阐述上(也可能是译者水平局限)给人一种“东一榔头西一棒追”的感觉。关于这点,我觉得有必要单独写一篇总结了。因为我觉亚稳态的消除是数字电路中设计中的最大关键,不管是想省面积也好还是提速也好,你发现究其根本总是绕不开这个亚稳态。整个数字电路的设计史不管是设计技巧也好还是器件工艺提升也好,我们一直在跟亚稳态做斗争。而且理解亚稳态背后的原因对 ”为啥一个设计要组合逻辑又要时序逻辑,时序设计的优点是什么” 这样的问题有一个清晰的答案。

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页