最近在用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”低电平时才输入激励。测试代码如下:
/**********************************************版权申明************************************************* ** 版权归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”的影响。
呵呵,好像对这个简单的问题讲太多了,不过还是希望大家有用啦!*^_^*