verilog基础设计5-单bit信号跨时钟域处理(快时钟域到慢时钟域)

本文探讨了为何需要处理跨时钟域信号,特别是快到慢的转换问题。通过实例解释了直接打拍方法的局限,并介绍了使用握手信号进行数据同步的方法,包括脉冲展宽的Verilog实现和基于握手的解决方案。仿真结果展示了正确处理的重要性。
摘要由CSDN通过智能技术生成

今天看了跨时钟域信号处理,就总结一下,今天主要写一下快时钟域到慢时钟域的处理,因为慢到快的比较简单,就通过常规的打拍操作就可完成。

1、为什么对跨时钟域信号进行处理?

        跨时钟域信号,容易造成亚稳态,对设计危害较大。

2、为什么不能直接和慢到快这种情况一样采用两级寄存器打拍的方式?

        快时钟域信号变化快,慢时钟域信号采样时容易造成采样丢失,或者直接采不到,例如对快时钟域的脉冲检测。如果不经特殊处理,极有可能就采不到信号。

        正如下图所示,由于aclk信号宽度较窄,使得bclk采样时,正好采到adat的下降沿上,容易造成亚稳态,如果aclk的频率再快一点,就会出现bclk采样不到的现象。

3、如何处理这种跨时钟的单bit信号?

  •      对脉冲进行展开,通常遵循三时钟沿”要求,也就是要持续3个时钟沿以上(上升沿和下降沿都算)。这个被称为:“三时钟沿”要求。
  •     通过“握手”的方式来保证数据被采样到

             如下图发送端信号会在任何时刻发生变化,接收端采样时,会出现采不到或者不满足时序要求,出现亚稳态,因此采用握手信号避免这种问题。

  • 下图就是采用握手信号的方式

           

            只需要对双方的握手信号(req和ack)分别使用脉冲检测方法进行同步。在具体实现中,假设req、ack、data总线在初始化时都处于无效状态,发送域先把数据放入总线,随后发送有效的req信号给接收域。接收域在检测到有效的req信号后锁存数据总线,然后回送一个有效的ack信号表示读取完成应答。发送域在检测到有效ack信号后撤销当前的req信号,接收域在检测到req撤销后也相应撤销ack信号,此时完成一次正常握手通信。此后,发送域可以继续开始下一次握手通信,如此循环。

            该方式能够使接收到的数据稳定可靠,有效的避免了亚稳态的出现,但控制信号握手检测会消耗通信双方较多的时间

4、脉冲展宽的verilog实现及仿真结果

module cdc(
	input wire clka,
	input wire rst_n,
	input wire pulse_a,//a 时钟域的脉冲信号
	input wire clkb,
	output wire out_pulse,//b时钟域检测到的脉冲输出
	output wire singal_out
	);

reg ext_pulse_a;
reg [1:0] ext_pulse_b;
reg [1:0] ext_pulse_a_b;
reg [1:0] pos_pulse_b;//检测同步过来的pulse_b的上升沿

assign singal_out = pos_pulse_b[1];

//在a时钟域下对脉冲信号进行展宽
always @(posedge clka or negedge rst_n)
	if(!rst_n)
		ext_pulse_a <= 1'b0;
	else if(pulse_a)
		ext_pulse_a <= 1'b1;
	else if(ext_pulse_a_b[1])
		ext_pulse_a <= 1'b0;
	else 
		ext_pulse_a <= ext_pulse_a;


//将展宽信号同步到b时钟域
always @(posedge clkb or negedge rst_n) begin
	if (!rst_n) 
		ext_pulse_b <= 2'b0;
	else
		ext_pulse_b <= {ext_pulse_b[0],ext_pulse_a}; 
end

//将ext_pulse_b同步回a
always @(posedge clka or negedge rst_n) begin
	if (!rst_n) 
		ext_pulse_a_b <= 2'b0;
	else
		ext_pulse_a_b <= {ext_pulse_a_b[0],ext_pulse_b[1]};
end



//检测ext_pulse_b上升沿
always @(posedge clkb or negedge rst_n) begin
	if (!rst_n) 
		pos_pulse_b <= 2'b0;
	else
		pos_pulse_b <= {pos_pulse_b[0],ext_pulse_b[1]}; 
		
end

assign  out_pulse = (pos_pulse_b[0] & ~pos_pulse_b[1]);

endmodule

脉宽展开的tb文件

`timescale 1ns/1ps
module tb_cdc();

reg clka;
reg clkb;
reg pulse_a;
wire out_pulse;
reg rst_n;
wire singal_out;

initial begin
	clka =0;
	clkb =0;
	rst_n =0;
	pulse_a =0;
	#100
	rst_n =1;
	# 100;
	pulse_a =1'b1;
	#10;
	pulse_a = 1'b0;	
	#100;
	pulse_a =1'b1;
	#10;
	pulse_a = 1'b0;	

end

always #5 clka =~clka;
always #10 clkb = ~clkb;


cdc cdc_inst(
	.clka(clka),
	.rst_n(rst_n),
	.pulse_a(pulse_a),//a 时钟域的脉冲信号
	.clkb(clkb),
	.out_pulse(out_pulse),//b时钟域检测到的脉冲输出
	.singal_out(singal_out)
	);


endmodule

仿真结果:

5、基于握手信号的verilog实现及仿真  

             今天先写到这吧,改天补充

 

  • 7
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值