最近在用modelsim对设计进行仿真的过程中发现了一个非常有趣的问题。接下来,让我们跟随着一个设计的仿真来发现问题的原因所在。首先,以调用基于IP核的加法器为例。加法器IP核的参数设置如下:
设计代码如下:
/**********************************************版权申明*************************************************
** 版权归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
仿真结果如下:
仔细分析仿真数据,就可以发现设计已经出现问题了。有一段时间是输不出正确结果的。究竟是什么原因造成的呢?一开始我也挺郁闷的,想了几分钟后,我把问题定位在最下面的“GSR”信号上,在它的高电平期间,输出被置为0了;只有在它的低电平期间,输出才有效。于是修改测试文件,使其在“GSR”低电平(即延迟100ns后)时才输入激励。测试代码如下:
/**********************************************版权申明*************************************************
** 版权归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
测试结果如下:
好像我的猜想是对的。但为了完全验证猜想的正确性,还要考虑另外两种情况。第一,基于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
仿真结果如下:
通过测试,我对本设计做出总结:基于IP核的时序逻辑电路的输出受“GSR”的影响,只有在“GSR”为低电平时输出才有效;纯逻辑时序电路不受“GSR”的影响。
呵呵,好像对这个简单的问题讲太多了,不过还是希望大家有用啦!*^_^*