SystemVerilog系列教程--简介

声明:本教程翻译自asci-world

1995版的Verilog在数字设计市场占有的相当长的一段时间。后来IEEE又扩充了Verilog 1995,发布了Verilog 2001, 但是设计和验证的分离并并没有使新的版本流行起来。后来的SystemVerilog集中了连个语言的优点,能够同时支持设计平台和验证平台而逐渐流行。

SystemVerilog的一些新的特性如下:

  • 拥有C语言的数据类型,比如int, typedef, struct, union, enum
  • 动态数据类型: 结构体,类,动态队列和动态数组
  • 新的操作符和内建方法
  • 更为完善的流程控制foreach, return, break, continue
  • 面向对象编程
  • 支持断言
  • 支持覆盖率测试
  • VPI扩展等等

新的SystemVerilog对于有C++和面向对象基础的编程人员非常友好,实际上SystemVerilog和C++非常相似。

Verilog 基础

在介绍SystemVerilog之前,我们先来看看数字设计的一个基本流程:

  1. 制定设计规范
  2. 顶层设计
  3. 底层模块设计
  4. RTL实现
  5. 验证
  6. 综合实现

首先我们来看看规范的制定:所谓规范就是我们在设计中要遵守的一些限制和设计需求,比如我们来设计一个仲裁器,我们可以制定如下的规范:

  1. 两个代理的输入
  2. 高有效的异步复位
  3. 固定优先级
  4. 来请求的时候立即授权

依照传统的设计方法,我们需要设计一个状态机,为状态转换设计真值表,画Karnugh图优化设计,对于小型的电路,这种设计方法还可以,但是对于大型的设计,这种流程就过于复杂了。

aribiter_signal.gif

那我们来看看Verilog是怎么实现这个设计的,首先我们来看看系统的输入输出有哪些信号,下图是我们当前设计的一个状态转换图:

aribiter_fsm.gif

这个图中每个圆圈代表一个状态,每个状态都有一个输出,箭头代表状态转换的路径,比如最左边的表示如果当前在状态GNT0,这时收到一个!req_0信号,那么状态机就会转换到IDLE状态,所有的输出信号也会转换成IDLE的输出,现在已经有了基本的逻辑,我们就可以用Verilog来实现这个过程了。

模块代码

现在我们可以从框图上看到整个系统有一个名字"arbiter",几个输入和输出信号(req0, req_1, gnt_0, gnt_1),所以现在我们可以定义一个模块来实现我们需要的功能了。下面就是我们的Verilog代码,简单起见,这里用了2001标准,将输入输出直接定义在端口列表:

module arbiter (
    input clock,
    input reset,
    input req_0,
    input req_1,
    output gnt_0,
    output gnt_1
);

这里只用到了输入输出两种驱动类型,实际还支持三态的inout类型和向量类型

inout read_enable;
inout [7:0] address; // address is bidirectional
inout [0:7] data; // big endian, not usually used

数据类型

在硬件电路设计中有两种不同的驱动,所谓的driver是指可以直接驱动负载的,也就是可以输出或者输入电荷。

  • 可以保存数值的驱动,比如Flip-Flop
  • 不能保存数值,只是连接两个点,比如连线wire

第一种在verilog中称之为寄存器,第二种就是线网。

操作符

这里的操作符和C语言里面的比较类似:

类型符号操作
算术+ - * \加减乘除
%取模
逻辑!
-&&
-||
比较> < >= <= == !=大于 小于 大于等于 小于等于 等于 不等于
Reduction~ ~& ~| ^ ^~ ~^bitwise nand or nor xor xnor xnor
移位<< >>左移 右移
连接{}连接
条件条件

本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

发表新评论