【原创】IP核的输出细节
0赞
发表于 4/26/2015 9:39:07 AM
阅读(2563)
前段时间,在做毕设的过程中,有一个功能模块调用了乘法器IP核并用modelsim对其进行功能仿真,发现其输出结果不同步了。现在来看看究竟发生了什么?假设乘法器IP核的参数设置如下图所示:
其Verilog HDL例化代码如下所示:
`timescale 1ns / 1ps /******************************************************* Author : CrazyBird Filename : mult_top.v Data : 2015-4-26 Description : multiplier ********************************************************/ module mult_top( sys_clk, rst_n, dina, dinb, dout ); input sys_clk; input rst_n; input [ 7:0] dina; input [ 7:0] dinb; output [15:0] dout; mult u_mult( .clk ( sys_clk ), .sclr ( ~rst_n ), .a ( dina ), .b ( dinb ), .p ( dout ) ); endmodule
由乘法器IP核的参数设置及例化代码可知,当有效数据送进mult_top模块时,经过3个时钟上升沿后就应该有相应的结果从该模块中输出。其modelsim的功能仿真时序图如下图所示:
从其时序图看,其输出结果好像的确经过了3个时钟上升沿后输出,没什么问题。那对其进行放大看看,如下图所示:
发现结果是在时钟上升沿后0.1s处输出的,明明进行的是功能仿真,在该设计中本不应该带有延时的。难怪我在进行大数据处理并将结果导入文本时,其结果滞后一个时钟,原来是不同步导致的。为了解决这个问题,对乘法器IP核(其他IP核一样)的输出用寄存器打一拍进行同步。修改后的Verilog HDL代码如下:
`timescale 1ns / 1ps /******************************************************* Author : CrazyBird Filename : mult_top.v Data : 2015-4-26 Description : multiplier ********************************************************/ module mult_top( sys_clk, rst_n, dina, dinb, dout ); input sys_clk; input rst_n; input [ 7:0] dina; input [ 7:0] dinb; output [15:0] dout; reg [15:0] dout; wire [15:0] dout_w; mult u_mult( .clk ( sys_clk ), .sclr ( ~rst_n ), .a ( dina ), .b ( dinb ), .p ( dout_w ) ); always @(posedge sys_clk or negedge rst_n) begin if(rst_n==1'b0) dout <= 16'b0; else dout <= dout_w; end endmodule
这样,结果就变成了经过4个时钟上升沿后输出,其放大后时序图如下图所示:
很明显,该模块的输出已经同步了。
总结:对IP核的输出进行一级缓存可保证信号的同步化。
延伸:其实为了进行同步化设计,应该对从外部来的信号进行缓存一级(该设计没有涉及到)以及模块的结果进行寄存输出。