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之前,我们先来看看数字设计的一个基本流程:
- 制定设计规范
- 顶层设计
- 底层模块设计
- RTL实现
- 验证
- 综合实现
首先我们来看看规范的制定:所谓规范就是我们在设计中要遵守的一些限制和设计需求,比如我们来设计一个仲裁器,我们可以制定如下的规范:
- 两个代理的输入
- 高有效的异步复位
- 固定优先级
- 来请求的时候立即授权
依照传统的设计方法,我们需要设计一个状态机,为状态转换设计真值表,画Karnugh图优化设计,对于小型的电路,这种设计方法还可以,但是对于大型的设计,这种流程就过于复杂了。
那我们来看看Verilog是怎么实现这个设计的,首先我们来看看系统的输入输出有哪些信号,下图是我们当前设计的一个状态转换图:
这个图中每个圆圈代表一个状态,每个状态都有一个输出,箭头代表状态转换的路径,比如最左边的表示如果当前在状态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 |
移位 | << >> | 左移 右移 |
连接 | {} | 连接 |
条件 | ? | 条件 |
最后更新于 2018-12-27 08:09:57 并被添加「」标签,已有 2986 位童鞋阅读过。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。