优秀的verilog代码风格

2021-04-26  本文已影响0人  Alliawell

1.参数化

案例:下图是光纤接收的代码实例,系统中有5根光纤,每个光纤上传感器数据的个数和ID都不同,例如:

1)光纤0上传输ID=8'h10~8'h13的 4 种数据;

2)光纤1上传输ID=8'h14~8'h17的 4 种数据;

3)光纤2上传输ID=8'h18~8'h1B的 4 种数据;

4)光纤3上传输ID=8'h20~8'h24的 5 种数据;

5)光纤4上传输ID=8'h00的 1 种数据。

上述5根光纤接收逻辑的功能一样,仅仅是处理的ID个数不同。下图采用参数化的编码风格,把ID(SENSOR_BASE_ID)和个数(SENSOR_NUM)进行参数化,一个.v文件就可以处理上述5种光纤数据,很方便。

反之,如果不用参数化的方式,就需要给每根光纤写一个.v文件,增加了写代码、维护代码的工作量。

图1.参数化

上层实例化时,通过改变参数来实现各个光纤通道的特定功能,如下图所示。

图2.上层实例化时改变参数

2.用generate-for循环简化代码

用generate-for循环可以一次实例化多个模块,如下图所示,1次实例化了18个FIFO,极大减少了代码量。

图3.用generate-for循环实例化18个FIFO

3.调试开关的统一管理

在使用VisualStudio或QT等IDE时,可以设置全局的宏定义,极大的方便代码调试。

Vivado和Quartus等FPGA开发的IDE没有上述功能,但我们可以手动实现。

例如我们创建一个debug_switch.vh的头文件,在里面定义各种调试宏定义,如下图所示。

图4.头文件里的集中宏定义

然后在fiber_rx_64bit.v中`include该头文件,如图1所示。

在fiber_rx_64bit.v中用generate-if语句进行判断,如下图所示,当`DEBUG_RX_DATA==1时,开启代码;否则屏蔽代码,实现VS或QT相同全局宏定义的功能。

图5.用generate-if语句实现代码的开关控制 图6. 按位进行模块的使能

4.结构体风格的编程

用generate语句可以实现C语言中结构体风格的编程,如下图所示,定义了一个类似结构体数组的变量:rx_fiber[0]~rx_fiber[4]。

用类似结构体的风格可以更好地组织代码。

图7.结构体风格的编程示例 图8.结构体风格的编程示例(代码在generate-for循环里,i是循环变量)
上一篇下一篇

猜你喜欢

热点阅读