【原创】FPGA设计中的一个小分析
0赞在我看过的很多代码中,发现许多人在对变量赋初始值(或常量值)0时的做法各种各样,现在来分析下这几种情况对设计的影响。以对64位变量a赋初始值0为例:
(1)第一种:a <= 64’d0; 对于这种指定变量具体位宽的代码风格,我是直接否定的,因为它不利于参数化设计;
(2)第二种:a <= 0;(或a <= (0);)而对于这种直接赋一个0的做法呢,一般情况下对设计是没有影响的,而且还能进行参数化设计,但是在另外一种情况下是要注意的,就是例化子模块时对位宽大于32的变量赋0,就会出现意想不到的情况。现在举个简单的例子来证实这种情况。假设在子模块中对一个64位的输入变量取反后进行输出,而在顶层模块中将子模块输出变量的第33位进行输出,用于硬件led的测试。
顶层模块:
/**********************************************版权申明************************************************* ** 电子技术应用网站, CrazyBird ** http://www.chinaaet.com, http://blog.chinaaet.com/crazybird ** **--------------------------------------------文件信息-------------------------------------------------- ** 文件名: led_top.v ** 创建者: CrazyBird ** 创建日期: 2015-8-2 ** 版本号: v1.0 ** 功能描述: 对变量直接赋0的测试 ** ********************************************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module led_top( led_data ); //****************************************************************************** // 输入/输出端口定义 //****************************************************************************** output led_data; //****************************************************************************** // 变量定义 //****************************************************************************** wire [63:0] dout; //****************************************************************************** // 模块例化 //****************************************************************************** led u_led( .din(0), .dout(dout) ); assign led_data = dout[32]; //****************************************************************************** endmodule //*********************************************文件结束*****************************************************
子模块:
/**********************************************版权申明************************************************* ** 电子技术应用网站, CrazyBird ** http://www.chinaaet.com, http://blog.chinaaet.com/crazybird ** **--------------------------------------------文件信息-------------------------------------------------- ** 文件名: led.v ** 创建者: CrazyBird ** 创建日期: 2015-8-2 ** 版本号: v1.0 ** 功能描述: 对64位的输入数据取反后输出 ** ********************************************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module led( din, dout ); //****************************************************************************** // 输入/输出端口定义 //****************************************************************************** input [63:0] din; output [63:0] dout; //****************************************************************************** // 取反输出 //****************************************************************************** assign dout = ~din; //****************************************************************************** endmodule //*********************************************文件结束*****************************************************
modelsim仿真结果:
很显然,在例化子模块时对位宽大于32的变量赋0时其实只对低32位赋了0值。
那么这样的代码风格对设计实现有没有影响呢?接着对设计进行综合后出现以下警告(也提示只对低32位赋了值):
最后对设计进行分配引脚、实现以及生成bit文件并将bit文件下载到红色飓风开发板上验证一下,发现led亮了(高电平点亮的),呵呵,一个不定值居然让led亮了,我不知道硬件是怎么实现的。
(3)第三种:a <= {(DATA_WIDTH){1’b0}}; 其中DATA_WIDTH是经过定义的参数:parameter DATA_WIDTH = 64;对于第三种代码风格我是极力推荐的,因为它既实现参数化设计,又不会出现第二种代码风格的情况,具体呢,大家可以亲自验证下,哈哈!