二、Verilog 语言结构到门级的映射,verilog在综合时常用技巧及注意事项

  • Verilog 编码效率的高低是综合后电路性能高低的决定性因素,两种不同风格的编码, 即使它们所表达的逻辑功能一下,也会产生出大不一样的综合结果。就算综合工具运用的再 好,也不能完全依赖它把一段编码很差的代码综合出一个像样的电路来。本节将通过大量的 实例介绍综合时 Verilog 的各种语言结构(always 、if、case 、loop 等等)到门级的映射。这些 语言结构是在编写 Verilog 代码的时候经常用到的一些基本结构,希望通过分析他们与门级 网表之间的对应关系,大家能够对什么样的语句能生成什么样的具体电路有个初步的认识。
  • 编写用于综合的 HDL 代码的三个原则——
  • 编写代码的时候注意代码综合后大概的硬件结构,不写不可综合的语句
  • 编写代码的时候注意多用同步逻辑,并将异步和同步逻辑分开处理
  • 编写代码的时候注意代码的抽象层次,多用 RTL 级的描述

企鹅号3270516346,交流及获取资料联系

2.1 always 语句的综合

always 语句用来描述电路的过程行为(procedural behavior), 表示当事件列表中的状态发 生变化时,执行语句体中的语句。下面是一个包含过程赋值的 always 语句的例子。
在这里插入图片描述
电路综合后的网表如下图所示——
在这里插入图片描述
使用 always 语句描述组合电路要注意的是:在该语句中读入的所有变量都需要出现在 事件列表中(对 Verilog 语言而言是指”@”符号之后的信号) ,否则可能会得不到用户期望的结 果。

2.2 If 语句的综合

if 语句用于描述受条件控制的电路,下面是一个例子——
在这里插入图片描述

在这里插入图片描述
如果在使用 if 语句时,没有指出条件判断的所有可能情况,则会在电路中引入锁存器 (Latch),如下例所示——
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面的电路中,当条件 Marks 的值为小于 5 时,电路的输出 Grade 的值为 FAIL ,如果 Marks 的值为 5 到 10 之间,那么 Grade 的值为 PASS ,由于没有指定 Marks 的值大于 10 的 时候Grade 的值,于是产生的电路中引入了锁存器保存原来Grade 的值。
由于锁存器和触发器两种时序单元共存的电路会增大测试的难度,因此,在综合的时候尽 量只选用一种时序单元,为了不在电路中引入锁存器,可以在使用该语句时设置缺省的状态,即在 判断条件之前先对输出赋值,或者使用 if…else if…else 的语句结构。

上面的例子经过改动后可以得到下面的例子——
在这里插入图片描述
if 语句条件补全消除 Latch
在这里插入图片描述

2.3 case 语句的综合

2.3.1 条件互斥的 case 语句

对于条件互斥(mutually exclusive)的 case 语句来说,它不存在优先级的概念。

先看一个 case 语句的简单实例——
在这里插入图片描述
综合后的电路:
在这里插入图片描述
从条件互斥的 case 的行为来看,它有点像 if…else if…else 这种结构的 if 语句,也就是 说 case 表达式(Op)先同case 的第一个case 项(ADD) ,如果不匹配的话再同第二个(SUB)比较, 依次类推。与上例等价的 if 语句如下所示——
在这里插入图片描述

2.3.2 Casex 语句

在 casex 语句中,case 项中的 x 或者 z 的值表示不关心(don’t-care) 。从综合的角度看, 这些值不能作为 case 表达式的一部分。
下面是一个用 casex 语句描述优先级编码器的例子——
在这里插入图片描述
综合后用 casex 描述的优先级编码电路:
在这里插入图片描述
上述的 casex 语句所表达的电路与下面的 if 语句一样——
在这里插入图片描述
可见 casex 所描述的电路是具有优先级的。如果我们将上例中的 casex 用 case 语句代替 (同时将 case 项中的 x 用 0 代替), 则综合出来的电路将不具有优先级。

2.3.3 隐含 Latch 的 case 语句

与 if 语句类似,如果没有指出 case 项的所有可能情况,则会在电路中引入锁存器 (Latch),下面是一个例子——
在这里插入图片描述
case 语句条件不全引入 Latch:
在这里插入图片描述
上例中的 Zip 信号没有在所有可能情况下赋值,故在 Toggle=0 或 3 时,NextToggle 保 持原有的值,从而产生 Latch 。避免产生 latch 的一个方法是给被赋值信号(NextToggle)赋初 值。一种方法是加在 case 的最后加入一种 default 的情况(如下)
在这里插入图片描述
或者在 case 语句之前就对被赋值信号加上一个初值(如下)
在这里插入图片描述

2.3.4 Full case

从 2.3.3 的例子我们知道,如果条件不全,case 综合之后会产生 latch 。如果设计者知道 除了列出的一些 case 项之外不会再有其他的条件出现,也就是说 Toggle 的值除了 2’b01 和 2’b 10 之外不会有其他的值,而且又不想让电路产生latch ,那么他就需要把这种情况告诉综 合工具,这里就可以通过一条综合指令(synthesis directive)——synopsys full_case 来传达。综 合指令是 HDL 语言中的一类特别的代码,它负责向综合工具传递额外的信息; 由于综合指令是以注释的形式存在于HDL 代码中的,它对Verilog 语言本身没有其他影响。
加入综合指令之后,电路如下所示——
在这里插入图片描述
在这里插入图片描述
加入 full_case 后的综合结果:
在这里插入图片描述
可见在加入 full_case 综合指令后,综合的结果不存在 Latch 。但是要注意的是:

  • 加入综合指令会使代码的结果依赖于所用的综合工具,从而降低代码的可移植性。
  • 加入综合指令后产生的电路网表会和当初的 Verilog 建模有出入,导致验证的复杂

2.3.5 Parallel case

从 2.3.3 节可以看出,casex 语句是具有优先级的,与 if…else if …else 语句相当。那么 假如我们知道 case 项是互斥的该怎么办呢?(在互斥的情况下,case 将平行的检查 case 项中 所有可能的情况,而不是先检查第一个然后第二个⋯ ⋯ ) 。这时,我们需要将互斥的信息传 达给综合工具,这就是 parallel_case 的综合指令。当加上这条指令后,Design Compiler 能够理解 case 项是互斥的,这样就不会产生带优先级的电路,而是平行的译码结构。

加入综合指令后的电路如下所示——

在这里插入图片描述
加入parallel_case 后的综合结果:
在这里插入图片描述
与上面的 casex 语句对应的 if 语句如下——
在这里插入图片描述
由于
parallel_case
full_case 一样都是综合指令语句,在应用 parallel_case 的时候也要 考虑到可移植性和提高验证复杂度的问题。

2.3.6 case 项不是常数的 case 语句

前面讨论的 case 项都是常数,实际上我们也会遇到 case 项不是常数的情况,如下例—
在这里插入图片描述
case 项不是常数的优先级译码:
在这里插入图片描述
这里加入 full_case 指令是相当必要的,否则综合后会引入 latch(Pbus 全不为 1 的情况没 有考虑) 。另外,也可以通过赋初值的办法避免 latch 的产生。

值得注意的是,case 项不是常数与 case 项是常数不同,它综合后的电路是带优先级的。

2.4 loop 语句的综合

在 Verilog 语法中,一共有四种 loop 语句——while-loop, for-loop,forever-loop 以及 repeat-loop 。其中 for-loop 使用的最多,也是一种典型的可以被综合的 loop 语句。For-loop 语句综合的基本原则就是将里面的所有语句进行展开,下面举一个例子——
在这里插入图片描述
在这里插入图片描述

loop 语句的综合:
在这里插入图片描述
将 loop 语句展开之后,可以得到下面的 if 语句——
在这里插入图片描述
使用 loop 语句值得注意的地方是:不要在循环体内加入一些延时或面积较大的单元(例如 加法器)。由于loop 语句综合时需要展开循环体,所以相当于把循环体内的单元复制出来,循环多少次则复制多少次,这样势必会造成综合后的网表面积和延时很大,影响性能。

2.5 触发器的综合

触发器是组成时序电路的一个基本元件,也是 Design Compiler 作静态时序分析的要素 之一,当一个信号(变量)在通过 always 语句在时钟边沿(上升沿或下降沿)赋值时,触 发器就可以推断出来。

先看下面的一个例子——
在这里插入图片描述

2-bit 加法器的综合:
在这里插入图片描述
上面的 always 语句说明,每当 ClockA 出现一次上升延跳变,信号 Counter 就加 1 。由 于 Counter 是受时钟上升沿控制的,那么它综合以后会出现上升沿的触发器。

描述时序电路要注意一点:如果一个信号既要在 always 内部赋值也要在 always 语句之外赋 值,那在 always 内部赋值时需要用非阻塞赋值语句,如上例中的 Counter<=Counter + 1 。这样 可以准确的反映时序电路的行为。

在读入 Verilog 文件的时候,Design Compiler 能够分析出代码中的时序元件(触发器和锁 存器) ,并将结果报告出来。
DC 报告时序元件:
在这里插入图片描述
如图 所示的 Q_reg ,Design Compiler 推断出是一个一位宽的异步复位(AS) 触发 器。

2.6 算术电路的综合

DC 在综合遇到运算符的时候,会在 DesignWare 中选取合适的逻辑电路来实现该运算 符。DesignWare 是集成在 DC 综合环境中的可重用电路的集合,主要包括‘+’‘-’‘×’ 等算术运算符和‘< ’‘> ’,‘<= ’‘>= ’等逻辑运算符。针对同一种运算符,DesignWare 可能 提供不同的算法,具体选择那一种是由给定的限制条件决定的。

DesignWare 分为 DesignWare Basic 与DesignWare Foundation ,DesignWare Basic 提供基 电路,DesignWareFoundation 提供性能较高的电路结构。

DW Foundation 与 DW Basic:

在这里插入图片描述
从上图的加法器可以看出,DW Foundation 除了具有 Carry Look-Ahead 和 Ripple Carry 两种结构的加法器外,还有另外四种结构,并且速度更快。

如果要 Foundation 的 DesignWare ,除了需要有 DesignWare Foundation 的 Licesen 之外 还需要在综合的时候设置 synthetic_library。

在这里插入图片描述
在 verilog 语言中,一个 reg 类型的数据是被解释成无符号数,integer 类型的数据是被 解释成二进制补码的有符号数,而且最右边是有符号数的最低位。

进行算术运算时,它也有各个运算符的优先级,运算按照由左至右进行,如下面的式子
在这里插入图片描述
它综合出来会是下面的样子——
在这里插入图片描述
显然这种结构的延时是很大的,我们可以通过交换运算次序和加入括号形成优化的结构
在这里插入图片描述

本节详细介绍了 Verilog 的各种语句和运算符的综合电路,本节的综合没有施加任何的 限制条件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chy_wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值