您的位置:首页 > 其它

pulse_synchronizer(异步信号处理)程序理解

2010-12-14 20:10 302 查看
本地地址:E:/FPGA/NetFPGA/project_top/src_for_graduate/big_fpga/gemac_group/pulse_synchronizer.v
///////////////////////////////////////////////////////////////////////////////

// $Id: pulse_synchronizer.v 1887 2007-06-19 21:33:32Z grg $

//

// Module: pulse_synchronizer.v

// Project: UNET-SWITCH4-64bit-wbs

// Description: transforms a pulse(脉冲) from one domain(领域,范围,范畴) into a pulse in another domain

// note that the arriving pulses should be separated by around 5 cycles

// in each domain.

//

///////////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module pulse_synchronizer

( input pulse_in_clkA, //输入脉冲A

input clkA, //输入时钟A

output pulse_out_clkB, //输出脉冲

input clkB, //输入时钟B

input reset_clkA, //输入时钟A复位信号

input reset_clkB //输入时钟B复位信号

);

reg ackA; //

reg ackB; //

reg ackA_synch;

reg ackA_clkB;

reg ackB_synch;

reg ackB_clkA;

reg pulse_in_clkA_d1;

reg ackA_clkB_d1;

reg ackB_d1;

/* detect rising edges in clkA domain, set the ackA signal

* until the pulse is acked from the other domain */

always @(posedge clkA) begin

if(reset_clkA) begin

ackA <= 0;

end

else if(!pulse_in_clkA_d1 & pulse_in_clkA) begin //捕捉在clkA中的脉冲的上升沿。在后仿真时,clkA_d1的赋值比较clkA的慢,会出现很短的clkA_d1为低,clkA为高

ackA <= 1; //的情况,是ackA置位。。

end

else if(ackB_clkA) begin //ackB_clkA比ackB慢一个clkA的时钟,因此当ackB_clkA为低时xx

ackA <= 0;

end

end // always @ (posedge clkA)

/* detect the rising edge of ackA and set ackB until ackA falls */

always @(posedge clkB) begin

if(reset_clkB) begin

ackB <= 0;

end

else if(!ackA_clkB_d1 & ackA_clkB) begin //

ackB <= 1;

end

else if(!ackA_clkB) begin

ackB <= 0;

end

end // always @ (posedge clkB)

/* detect rising edge of ackB and send pulse */

assign pulse_out_clkB = ackB & !ackB_d1;

/* synchronize the ack signals */

always @(posedge clkA) begin

if(reset_clkA) begin

pulse_in_clkA_d1 <= 0;

ackB_synch <= 0;

ackB_clkA <= 0;

end

else begin

pulse_in_clkA_d1 <= pulse_in_clkA; //clkA时钟下的脉冲寄存器

ackB_synch <= ackB; //ackB的同步信号

ackB_clkA <= ackB_synch; //ackB慢一个clkA周期的信号

end

end

/* synchronize the ack signals */

always @(posedge clkB) begin

if(reset_clkB) begin

ackB_d1 <= 0;

ackA_synch <= 0;

ackA_clkB <= 0;

ackA_clkB_d1 <= 0;

end

else begin

ackB_d1 <= ackB; //仿真波形不一致??

ackA_synch <= ackA; //ackA的同步信号

ackA_clkB <= ackA_synch; //ackA在clkB的一个周期的延迟信号

ackA_clkB_d1 <= ackA_clkB; //ackA在clkB的两个周期的延迟信号

end

end

endmodule // pulse_synchronizer



第二次仿真:
always #10 clkA = ~clkA;

always #20 clkB = ~clkB;

initial begin

// Initialize Inputs

pulse_in_clkA = 0;

clkA = 0;

clkB = 0;

reset_clkA = 0;

reset_clkB = 0;

// Wait 100 ns for global reset to finish

#10 reset_clkA = 1;

#10 reset_clkA = 0; reset_clkB = 1;

#10 reset_clkB = 0;

#100 pulse_in_clkA = 1;

#100 pulse_in_clkA = 0;



第三次仿真:
将#100 pulse_in_clkA = 1;改为#110 pulse_in_clkA = 1;



波形分析:
ackA的置位:捕捉在pluse_in_clkA中的脉冲的上升沿。在后仿真时,pluse_in_clkA_d1的赋值比较pluse_in_clkA的慢,会出现很短的pluse_in_clkA_d1为低,pluse_in_clkA为高的情况,是ackA置位
ackA_synch的上升沿:在clkB的上升沿时,进行采集信号,延迟有所不同,比如第三次仿真整整满了一个clkB的周期,而第二次仿真则没有到一个clkB的周期。
ackA_clkB的上升沿:比ackA_synch慢一个clkB的周期
ackA_clkB_d1的上升沿:比ackA_clkB慢一个clkB的周期
ackB的上升沿:以clkB为参照时钟,捕捉在!ackA_clkB_d1 & ackA_clkB时,产生上升沿。
pluse_in_clkA_d1的下降:根据clkA的上升沿进行捕捉。第三次仿真慢了半个clkA的周期
ackB_synch的上升沿:根据clkA的上升沿判断,捕捉ackB信号。
总体信号间的影响关系图:
pluse_in_clkA上升沿 =》 pluse_in_clkA_d1的上升沿 =》ackA 的上升沿 =》 ackA_synch的上升沿 =》 ackA_clkB的上升沿 =》 ackA_clkB_d1的上升沿 =》ackB的上升沿 =》ackB_synch的上升沿 =》ackB_clkA的上升沿
=》ackA的下降沿=》 ackA_synch的下降沿 =》 ackA_clkB的下降沿 =》 ackA_clkB_d1的下降沿 =》ackB的下降沿 =》ackB_synch的下降沿 =》ackB_clkA的下降沿
(注:红色的为以clkA作为参照,蓝色的为以clkB作为参照)
最后是assign pulse_out_clkB = ackB & !ackB_d1;将输出信号提取出来。
上面的仿真是将快时钟域中的信号向慢时钟域信号转变,进行扩充。



这个是慢时钟域的信号向快时钟域中的信号转变。
备注:每次转变时都要求是快的时钟信号先复位,然后慢的时钟在复位。(自己仿真的结果,不知道为什么)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐