购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.3 Verilog-2005标准改进说明

虽然用于描述硬件,但是Verilog HDL本质上还是一种高级程序设计语言,所以每次标准的更新都借鉴了当时一些优秀的编程思想。相比Verilog-1995,Verilog-2001有了很大改善,让Verilog HDL更加精简、高效。Verilog-2005发布时,由于已经发布了System Verilog,所以Verilog-2005本身并没有引入太多的优化。本节描述的特性有很多是在Verilog-2001中就已提出的,但为了统一,本节将它们描述为Verilog-2005的特性。

1.3.1 端口声明“三合一”

端口声明方式的改进见表1-1。

表1-1

在Verilog-1995中,同一个变量要在3个地方分别说明!Verilog-2005把这3个部分合而为一,不仅让代码更加简洁,还让代码编写过程中的误输入可能性大幅度降低。

1.3.2 敏感变量列表描述方式的改进

早期从事FPGA设计的人员对编码风格中要求的“敏感变量列表要描述齐全”可能印象深刻,因为在用always语句描述组合逻辑时,如果不小心遗漏了一个敏感变量列表,就会导致所描述的硬件结构成为一个锁存(Latch)结构,使设计结果与预期大相径庭。Verilog-2005中,在描述时序逻辑的敏感变量列表时,用逗号来代替关键字or;而在描述组合逻辑时,直接用星号来替代全部敏感变量列表,参考表1-2、表1-3的对比情况。

表1-2

表1-3

1.3.3 矢量位选择方式的改进

在Verilog HDL中声明一个变量时,如果没有指定变量的位宽,就把该变量当作只有一位的变量,也称为标量;而如果指定了该变量的位宽为多位,该变量被称为矢量。要从一个矢量中选择其部分连续数据位时,Verilog-2005在Verilog-1995的基础上也有许多改进,参考表1-4的对比情况。

表1-4

Verilog-2005引入了C语言的一些语法,10+:8表示从第10位开始往高位连续选择8位;17-:8表示从第17位开始往低位连续选择8位。用这两种方式都可选择信号sig_y的[17∶10]这8位。

1.3.4 parameter声明和值传递方式的改进

参数化设计是程序设计语言的重要思想。在Verilog-2005中,模块的parameter声明和值传递方式均比Verilog-1995简洁,参考表1-5的对比情况。

表1-5

Verilog-2005用#()的方式在端口列表声明前声明模块的parameter列表。

对于模块parameter的值传递方式,各个版本的Verilog标准都支持使用关键字defparam来传递parameter的值到例化模块中。除此之外,也可以在例化模块时直接用端口连接的方式传递参数,但是Verilog-1995只支持隐式参数传递,即各个parameter的值按照它们在模块声明时的顺序一一对应地传递。在Verilog-2005中,可以像端口信号一样只对指定parameter的值进行传递,即增加了显式参数传递机制,参考表1-6的对比说明。

表1-6

Verilog-2005改进后采用显式参数传递机制,不仅参数列表的顺序可以任意调换,还可以根据需要只更新部分参数的值,其他未传递的参数则采用模块声明时的默认值。

1.3.5 generate语句的使用

在Verilog-2005中,与generate同步引入的还有endgenerate、genvar等关键字。generate语句可以用在多种场景中。

一种场景是替换`define,即前面介绍的预编译指令。预编译指令的使用方式是用关键字`define定义预编译变量,然后用`ifdef…`else语句实现功能。使用generate语句也可以实现这样的功能:用genvar定义一个变量,根据该变量的实际值用generate if、generate case语句生成不同的硬件。

另一种场景是使用generate for的结构描述功能相同的多个硬件结构,这将极大简化代码量,参考表1-7的对比说明。

表1-7

1.3.6 矢量化方式例化模块

在需要多次例化同一个模块时,如前所述,可以使用generate语句。Verilog-2005还提供一种类似于矢量声明的方式,比使用generate语句更简洁,参考代码1-5。

代码1-5:矢量化方式例化参考代码
// 模块其他功能:略
// 例化 param_def 模块4 次
wire [7∶0] sig_in0 ;
wire [255∶0]sig_out0 ;
wire [7∶0] sig_in1 ;
wire [255∶0]sig_out1 ;
wire [7∶0] sig_in2 ;
wire [255∶0]sig_out2 ;
wire [7∶0] sig_in3 ;
wire [255∶0]sig_out3 ;
param_def   param_def_inst[3∶0] (
// 其他信号连接:略
.clk ( {4{clk}} ) , // clk ( clk )
.sig_in ({ sig_in3, sig_in2, sig_in1, sig_in0}) ,
.sig_out ({ sig_out3, sig_out2, sig_out1, sig_out0} )  );

使用param_def_inst[3∶0]的方式相当于例化了4个param_def模块,各个端口信号也相应地进行了扩展。如果所有例化模块的某个端口使用的是同一个信号,那么还可以简化。

比如在代码1-5中使用的是:

.clk ( {4{clk}} ) ,

这表明4个例化模块的clk端口连接的是同一个信号,此时可以替换为如下形式:

.clk ( clk ) , w3liFS91v6MexaKi+Lp8LnUg+0CVSqk3MuocYrxzC+5mxi3BcGRy8VkfhNy6Pyzd

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开