单比特信号跨时钟域

目录

 

问题:Signal_a是clka(300M)时钟域的一个单时钟脉冲信号,如何将其同步到时钟域clkb(100M)中,并产生出Signal_b同步脉冲信号。请用Verilog代码描述,并画出对应的时序波形图说明图。(大疆FPGA逻辑岗A卷)

一、单比特信号从慢时钟域到快时钟域

二、单比特信号从快时钟域到慢时钟域

三、RTL代码

四、TB代码

五、仿真结果

六、RTL图


问题:Signal_a是clka(300M)时钟域的一个单时钟脉冲信号,如何将其同步到时钟域clkb(100M)中,并产生出Signal_b同步脉冲信号。请用Verilog代码描述,并画出对应的时序波形图说明图。(大疆FPGA逻辑岗A卷)

一、单比特信号从慢时钟域到快时钟域

(1)矩形脉冲的“0”变“1”、“1”变“0”不是立刻变化的,有一个变化的过程,运放里叫压摆率(SR)。

如果时钟采样时信号正好在变化的过程,数据传输的过程就不满足建立时间和保持时间,触发器的输出会处于不确定的状态,不等于稳定的输入值,存在“亚稳态”的问题。

(2)解决办法:

“打两拍法”,数据进来后首先打一拍,通过第一级寄存器;第一级寄存器的输出再通过第二级寄存器,第二级寄存器的输出就是相对稳定的0/1。

PS:亚稳态震荡时间(Tmet)与器件工艺、温度、环境等很多因素有关。

二、单比特信号从快时钟域到慢时钟域

(1)也存在“亚稳态”的问题

(2)还可能存在采不到的问题:

单比特信号跨时钟域_第1张图片

 

 

(3)解决办法:

在clka的时钟域下延长第一个Signal_a到第二个Signal_a,延长第三个Signal_a到第四个Signal_a。。。即在clka时钟下检测到Signal_a为高时,令Signal_a_L取反。

单比特信号跨时钟域_第2张图片

加上亚稳态的处理方法——“打两拍”,在clkb时钟域上得到Signal_a_L1和Signal_a_L2。

单比特信号跨时钟域_第3张图片

最后使用边沿检测的方法检测Signal_a_L2(L2的数据是稳定的,L1可能不稳定)的上升沿和下降沿还原脉冲Signal_b。

单比特信号跨时钟域_第4张图片

三、RTL代码

module One_bit_fast2slow(
input wire clka,
input wire Rsta_N,
input wire Signal_a,
input wire clkb,
input wire Rstb_N,

output wire Signal_b
);

//在clka时钟下检测到Signal_a为高时,令Signal_a_L取反
reg Signal_a_L = 1'b0;
always@(posedge clka or negedge Rsta_N)
begin
	if(!Rsta_N)
		Signal_a_L <= 1'b0;
	else if(Signal_a)
		Signal_a_L <= ~Signal_a_L;
end

//打三拍,加上亚稳态的处理方法——“打两拍”,边沿检测打一拍
reg Signal_a_L1 = 1'b0;
reg Signal_a_L2 = 1'b0;
reg Signal_a_L2r = 1'b0;
always@(posedge clkb or negedge Rstb_N)
begin
	if(!Rstb_N)
	begin
		Signal_a_L1 <= 1'b0;
		Signal_a_L2 <= 1'b0;
		Signal_a_L2r <= 1'b0;
	end
	else
	begin
		Signal_a_L1 <= Signal_a_L;
		Signal_a_L2 <= Signal_a_L1;
		Signal_a_L2r <= Signal_a_L2;		
	end
end

//边沿检测
wire Signal_b_pose,Signal_b_nege;
assign Signal_b_pose = Signal_a_L2 && (!Signal_a_L2r);	//上升沿
assign Signal_b_nege = (!Signal_a_L2) && Signal_a_L2r; //下降沿
assign Signal_b 	 = Signal_a_L2^Signal_a_L2r;			//上升沿和下降沿

endmodule

四、TB代码

 

`timescale 1ns/1ps
`define clk_period 3.333	//300M
`define clk_period2 10	   //100M

module One_bit_fast2slow_tb();

reg clka;
reg Rsta_N;
reg Signal_a;
reg clkb;
reg Rstb_N;
wire Signal_b;

 One_bit_fast2slow One_bit_fast2slow_U1(
	.clka(clka),
	.Rsta_N(Rsta_N),
	.Signal_a(Signal_a),
	.clkb(clkb),
	.Rstb_N(Rstb_N),

	.Signal_b(Signal_b)
);

	initial clka = 1;
	always #(`clk_period/2)clka = ~clka;

	initial clkb = 1;
	always #(`clk_period2/2)clkb = ~clkb;
	
	initial begin
	Rsta_N = 0;Rstb_N = 0;Signal_a = 0;
	#(`clk_period2*20 + 1);
	Rsta_N = 1;Rstb_N = 1;
	#(`clk_period2*20 );
	
	Signal_a = 1;
	#(`clk_period);
	Signal_a = 0;
	#(`clk_period*5);
	Signal_a = 1;	
	#(`clk_period);
	Signal_a = 0;
	
	#100;
	Signal_a = 1;
	#(`clk_period);
	Signal_a = 0;
	#(`clk_period*5);
	Signal_a = 1;	
	#(`clk_period);
	Signal_a = 0;	
	
	#10_000;			
	end

endmodule

五、仿真结果

 

单比特信号跨时钟域_第5张图片

 

六、RTL图

单比特信号跨时钟域_第6张图片

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(FPGA,单比特信号跨时钟域,fpga)