modelsim中一个神奇又容易忽视的问题

最近在用modelsim对设计进行仿真的过程中发现了一个非常有趣的问题。接下来,让我们跟随着一个设计的仿真来发现问题的原因所在。首先,以调用基于IP核的加法器为例。加法器IP核的参数设置如下:

1

设计代码如下:

/**********************************************版权申明*************************************************
**                                        版权归CrazyBird所有                                            
**              http://blog.chinaaet.com/crazybird, http://www.cnblogs.com/CrazyBirdLin
**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:     adder4_1.v
** 创建者:     CrazyBird         
** 创建日期:   2015-3-22  
** 版本号:     v1.0
** 功能描述:   两个4位无符号数相加    
**
*******************************************************************************************************/
// synopsys translate_off
`timescale 1ns / 1ps
// synopsys translate_on
module adder4_1
(
    input           clk,
    input           rst_n,
    input   [3:0]   InA,
    input   [3:0]   InB,
    output  [3:0]   Sum,
    output          Co          
);
//-----------------------------------------------
//两个4位无符号数相加
adder_ip u_adder_ip 
(
    .clk    (clk    ),  // input            clk
    .sclr   (~rst_n ),  // input            sclr
    .a      (InA    ),  // input  [3 : 0]   a
    .b      (InB    ),  // input  [3 : 0]   b
    .s      (Sum    ),  // output [3 : 0]   s
    .c_out  (Co     )   // output           c_out
);

endmodule

测试代码如下:

/**********************************************版权申明*************************************************
**                                        版权归CrazyBird所有                                            
**              http://blog.chinaaet.com/crazybird, http://www.cnblogs.com/CrazyBirdLin
**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:     adder4_1_tb.v
** 创建者:     CrazyBird         
** 创建日期:   2015-3-22  
** 版本号:     v1.0
** 功能描述:   两个4位无符号数相加的测试文件
**
*******************************************************************************************************/
// synopsys translate_off
`timescale 1ns / 1ps
// synopsys translate_on
module adder4_1_tb;
//-----------------------------------------------
//变量定义
reg             clk;
reg             rst_n;
reg     [3:0]   InA;
reg     [3:0]   InB;

wire    [3:0]   Sum;
wire            Co;

//-----------------------------------------------
//例化加法器模块adder4_1
adder4_1 u_adder4_1
(
    .clk    (clk    ),
    .rst_n  (rst_n  ),
    .InA    (InA    ),
    .InB    (InB    ),
    .Sum    (Sum    ),
    .Co     (Co     )
);
//-----------------------------------------------
//生成时钟
parameter   PERIOD = 10;

initial
begin
    clk = 0;
    forever #(PERIOD/2)
        clk = ~clk;
end
//-----------------------------------------------
//测试模块的激励
initial
begin
    rst_n = 0;
    repeat(2)@(negedge clk);
    rst_n = 1;
end

always @(negedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
        InA <= 4'b0;
        InB <= 4'b0;
        end
    else
        begin
        InA <= InA + 1'b1;
        InB <= InB + 1'b1;
        end
end

endmodule

仿真结果如下:

2

仔细分析仿真数据,就可以发现设计已经出现问题了。有一段时间是输不出正确结果的。究竟是什么原因造成的呢?一开始我也挺郁闷的,想了几分钟后,我把问题定位在最下面的“GSR”信号上,在它的高电平期间,输出被置为0了;只有在它的低电平期间,输出才有效。于是修改测试文件,使其在“GSR”低电平时才输入激励。测试代码如下:

/**********************************************版权申明*************************************************
**                                        版权归CrazyBird所有                                            
**              http://blog.chinaaet.com/crazybird, http://www.cnblogs.com/CrazyBirdLin
**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:     adder4_1_tb.v
** 创建者:     CrazyBird         
** 创建日期:   2015-3-22  
** 版本号:     v1.0
** 功能描述:   两个4位无符号数相加的测试文件
**
*******************************************************************************************************/
// synopsys translate_off
`timescale 1ns / 1ps
// synopsys translate_on
module adder4_1_tb;
//-----------------------------------------------
//变量定义
reg             clk;
reg             rst_n;
reg     [3:0]   InA;
reg     [3:0]   InB;

wire    [3:0]   Sum;
wire            Co;

//-----------------------------------------------
//例化加法器模块adder4_1
adder4_1 u_adder4_1
(
    .clk    (clk    ),
    .rst_n  (rst_n  ),
    .InA    (InA    ),
    .InB    (InB    ),
    .Sum    (Sum    ),
    .Co     (Co     )
);
//-----------------------------------------------
//生成时钟
parameter   PERIOD = 10;

initial
begin
    clk = 0;
    forever #(PERIOD/2)
        clk = ~clk;
end
//-----------------------------------------------
//测试模块的激励
initial
begin
    rst_n = 0;
    repeat(10)@(negedge clk);
    rst_n = 1;
end

always @(negedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
        InA <= 4'b0;
        InB <= 4'b0;
        end
    else
        begin
        InA <= InA + 1'b1;
        InB <= InB + 1'b1;
        end
end

endmodule

测试结果如下:

3

好像我的猜想是对的。但为了完全验证猜想的正确性,还要考虑另外两种情况。第一,基于IP核的组合逻辑加法器,但由于没有这种IP核,就先暂时跳过;第二,基于纯逻辑的加法器,设计代码如下:

/**********************************************版权申明*************************************************
**                                        版权归CrazyBird所有                                            
**              http://blog.chinaaet.com/crazybird, http://www.cnblogs.com/CrazyBirdLin
**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:     adder4_2.v
** 创建者:     CrazyBird         
** 创建日期:   2015-3-22 
** 版本号:     v1.0
** 功能描述:   两个4位无符号数相加    
**
*******************************************************************************************************/
// synopsys translate_off
`timescale 1ns / 1ps
// synopsys translate_on
module adder4_2
(
    input               clk,
    input               rst_n,
    input       [3:0]   InA,
    input       [3:0]   InB,
    output reg  [3:0]   Sum,
    output reg          Co          
);
//-----------------------------------------------
//两个4位无符号数相加
always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
        {Co,Sum} <= 5'b0;
        end
    else
        begin
        {Co,Sum} <= InA + InB;
        end
end

endmodule

测试代码如下:

/**********************************************版权申明*************************************************
**                                        版权归CrazyBird所有                                            
**              http://blog.chinaaet.com/crazybird, http://www.cnblogs.com/CrazyBirdLin
**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:     adder4_2_tb.v
** 创建者:     CrazyBird         
** 创建日期:   2015-3-22  
** 版本号:     v1.0
** 功能描述:   两个4位无符号数相加的测试文件
**
*******************************************************************************************************/
// synopsys translate_off
`timescale 1ns / 1ps
// synopsys translate_on
module adder4_2_tb;
//-----------------------------------------------
//变量定义
reg             clk;
reg             rst_n;
reg     [3:0]   InA;
reg     [3:0]   InB;

wire    [3:0]   Sum;
wire            Co;

//-----------------------------------------------
//例化加法器模块adder4_1
adder4_2 u_adder4_2
(
    .clk    (clk    ),
    .rst_n  (rst_n  ),
    .InA    (InA    ),
    .InB    (InB    ),
    .Sum    (Sum    ),
    .Co     (Co     )
);
//-----------------------------------------------
//生成时钟
parameter   PERIOD = 10;

initial
begin
    clk = 0;
    forever #(PERIOD/2)
        clk = ~clk;
end
//-----------------------------------------------
//测试模块的激励
initial
begin
    rst_n = 0;
    repeat(2)@(negedge clk);
    rst_n = 1;
end

always @(negedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
        InA <= 4'b0;
        InB <= 4'b0;
        end
    else
        begin
        InA <= InA + 1'b1;
        InB <= InB + 1'b1;
        end
end

endmodule

仿真结果如下:

4

通过测试,我对本设计做出总结:基于IP核的时序逻辑电路的输出受“GSR”的影响,只有在“GSR”为低电平时输出才有效;纯逻辑时序电路不受“GSR”的影响。

呵呵,好像对这个简单的问题讲太多了,不过还是希望大家有用啦!*^_^*

原文地址:https://www.cnblogs.com/CrazyBirdLin/p/4357210.html