crazybird

【原创】FPGA设计中的一个小分析

0
阅读(2856)

    在我看过的很多代码中,发现许多人在对变量赋初始值(或常量值)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仿真结果:

2

很显然,在例化子模块时对位宽大于32的变量赋0时其实只对低32位赋了0值。

那么这样的代码风格对设计实现有没有影响呢?接着对设计进行综合后出现以下警告(也提示只对低32位赋了值):

1

最后对设计进行分配引脚、实现以及生成bit文件并将bit文件下载到红色飓风开发板上验证一下,发现led亮了(高电平点亮的),呵呵,一个不定值居然让led亮了,我不知道硬件是怎么实现的。

(3)第三种:a <= {(DATA_WIDTH){1’b0}}; 其中DATA_WIDTH是经过定义的参数:parameter DATA_WIDTH = 64;对于第三种代码风格我是极力推荐的,因为它既实现参数化设计,又不会出现第二种代码风格的情况,具体呢,大家可以亲自验证下,哈哈!