相关阅读
Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482
一、强度建模基础
Verilog HDL提供了针对线网信号0、1、x、z的精准强度建模方式,这样可以允许将两个线网信号进行线与操作从而更加精确地描述出硬件行为。
强度建模可以在两个地方使用,一个是连续赋值语句,另一个是门级建模。一个强度由两部分组成,一部分表示信号0的强度,称为strength0;一部分表示信号1的强度,称为strength1。
strength0包括以下几种:supply0(供电级低电平),strong0(强驱动级低电平),pull0(上下拉级低电平),weak0(弱驱动级低电平)以及highz0(高阻级低电平)。
strength1包括以下几种:supply1(供电级高电平),strong1(强驱动级高电平),pull1(上下拉级高电平),weak1(弱驱动级高电平)以及highz1(高阻级高电平)。
需要特别注意的是,(highz0, highz1)以及它的等效表示(highz1, highz0)是非法的,原因也会很简单,这会导致输出永远是高阻。
尽管对强度进行了这种划分,但为了预测信号组合的结果,可以将强度视为几个连续区域的组合。表1就展示了强度的连续性,左侧列出了用于指定强度名。右侧给出了相关的强度水平。
表1 线网型信号的强度水平
强度名 | 强度等级 |
supply0 | 7 |
strong0 | 6 |
pull0 | 5 |
large0 | 4 |
weak0 | 3 |
medium0 | 2 |
small0 | 1 |
highz0 | 0 |
highz1 | 0 |
small1 | 1 |
medium1 | 2 |
weak1 | 3 |
large1 | 4 |
pull1 | 5 |
strong1 | 6 |
supply1 | 7 |
在表1中,有四类驱动强度: supply、strong、pull、weak,这些强度是门级建模的输出net信号和连续赋值语句的左值net信号所拥有的。
在表1中,还存在三类电荷储存强度:large、medium、small,只有在声明trireg线网型变量时能指定。
注意这里我们没有讨论highz类,这是因为其比较特殊,后面会进行详细说明。
可以将表1写成下面图1的比例尺形式,这也是后面讨论强度建模细节的方式。
图1 强度比例尺
如果net型信号拥有确定的值1,则其强度应该全部由strength1部分的强度水平组成(不能包括highz1)。如果net型信号拥有确定的值0,则其强度应该全部由strength0部分的强度水平组成(不能包括highz0)。如果一个net型信号的值是x,则其部分拥有strength0的强度,部分拥有strength1的强度,比如一个Stx信号指的是一个强度范围从strong0到strong1的信号。如果net型信号拥有值z,则代表其强度一定是highz类,至于是highz0还是highz1我们一般不做区分。另外还有两种特殊的信号值H和L,这会在后面进行说明。
二、门级建模和连续赋值语句引入的强度
在上一节,我们介绍了强度建模的引入方式,下面进行详细阐述。首先给出门级建模和连续赋值语句语法的BNF范式,如图2和图3所示。有关BNF范式的相关内容可以看笔者的以往文章。
图2 门级建模语法的BNF范式
图3 连续赋值语句语法的BNF范式
在图2和图3中我们可以看到驱动强度[drive_strength]是门级建模和连续赋值语句的可选项,如果不指定驱动强度[drive_strength],则默认驱动强度为(strong0, strong1)。还要注意的是,对于net声明连续赋值语句,同样可以使用驱动强度[drive_strength],这与普通的连续赋值语句没有区别。
有了语法的基础,下面就可以举例说明驱动强度的基本概念了。
wire a, b, c, d, e;
assign a = 1; //net型信号a拥有单个强度strong,拥有信号值1,用St1表示
assign (strong1, strong0) a = 1; //与上面的形式等价
assign (strong0, strong1) a = 1; //与上面的形式等价
assign (weak0, strong1) a = 0; //net型信号a拥有单个强度weak,拥有信号值0,用We0表示
assign b = 1'bx; //net型信号b拥有强度范围strong0到strong1,拥有信号值x,用Stx表示
assign (weak0, pull1) b = 1'bx; //net型信号b拥有强度范围weak0到pull1,拥有信号值x,用35x表示
assign c = 1'bz; //net型信号c拥有强度hignz,拥有信号值z,用HiZ表示
not (pull0, weak1) (d, 1'b0); //net型信号d拥有单个强度pull,拥有信号值0,用Pu0表示
wire (weak0, supply1) e = 1'b0; //net型信号e拥有单个强度weak,拥有信号值0,用We0表示
//尽管我们的例子全部是变量net,但是对于矢量net同样适用
这里要注意的是,不管是连续赋值的左值net型信号还是门级建模的输出信号,信号的值是由输出决定的,而和输入或指定的驱动强度无关,这很好理解,因为输入可以是没有驱动强度的variable型信号,比如reg型信号,而指定的强度相当于只是给结果附上了一个属性,而不影响结果的值,下面举例说明。
wire a, b;
assign (pull1, supply0) b =1'b0; //b的强度是supply,值是0,用Su0表示
assign (pull0, supply1) a = b; //a的强度是pull,值是0,用Pu0表示(a的强度与b的强度无关,a的值与b的值有关)