跨时钟域的信号由于处于不同的时钟域,其时钟频率和相位都可能不一样,触发器要求的建立时间和保持时间无法得到保证,接收域很容易出现亚稳态问题。需使用同步手段使发射域与接收域处于同一时钟域。
1) 边沿检测
对于异步时钟信号,通常需要使用本地时钟打拍子,生成一个周期的使能信号。
// 输入信号打拍子
reg in_r1, in_r2;
// 输入信号上升沿
wire in_pos;
// 输入信号下降沿
wire in_neg;
assign in_pos = ((in_r1) & (~in_r2));
assign in_neg = ((~in_r1) & (in_r2));
// 输入信号打拍子
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
in_r1 <= 1'b0;
in_r2 <= 1'b1;
end
else begin
in_r1 <= in;
in_r2 <= in_r1;
end
end
2) 握手处理
可使用请求/应答机制实现跨时钟域通信,原理如下:
发送域先将数据放到数据总线上,然后发起req信号,接收域通过边沿检测到该信号后进行数据锁存,然后发起ack信号,发送域通过边沿检测到该信号后,撤销req信号,接收域检测到req信号撤销后撤销ack信号。
3) 使用异步FIFO
异步FIFO有两套独立的控制总线,其内部有完善的同步机制,使用时只需要考虑各个时钟域的数据流处理即可。