`timescale 1ns/1ns module mux( input clk_a , input clk_b , input arstn , input brstn , input [3:0] data_in , input data_en , output reg [3:0] dataout ); //MUX同步器 用于 多bit跨时钟域的处理 //关键在于当使能信号稳定的时候进行数据的传输 //步骤:将使能信号在本域打一拍 稳定信号 //然后在异域打两拍 减少亚稳态。 //然后再用一个二选一数据选择器 进行信号的选通。 reg data_en_a ; always@(posedge clk_a or negedge arstn)begin if(!arstn) data_en_a <= 1'b0 ; else data_en_a <= data_en ; end reg data_en_b ; reg data_en_b_r ; always@(posedge clk_b or negedge brstn)begin if(!brstn)begin data_en_b <= 1'b0 ; data_en_b_r <= 1'b0 ; end else begin data_en_b <= data_en_a ; data_en_b_r <= data_en_b ; end end always@(posedge clk_b or negedge brstn)begin if(!brstn) dataout <= 'd0 ; else if(data_en_b_r == 1'b1) dataout <= data_in ; else dataout <= dataout ; end endmodule
跨时钟域处理有多重处理方式:
1.单bit跨时钟域处理:
(1)慢时钟域转快时钟域 : 直接两级DFF打拍即可
(2)快时钟域转慢时钟域: 可能出现漏采 所以需要对快时钟域的脉冲进行拓宽。(握手机制)
处理流程: 将clk_fast 下的脉冲 在本域下进行拉高,生成data_a信号 将data_a信号进行跨时钟域处理(在clk_slow时钟域下打两拍) ,生成 data_b ,data_b_r信号 。data_b_r 信号为高代表慢时钟域已经接受到了这个脉冲。所以将data_b_r信号再跨时钟域处理(在clk_fast时钟域下再打两拍),生成data_a_r ,data_a_rr信号。使用data_a_rr ==1'b1 作为拓宽脉冲的拉低使能信号。
慢时钟域这边对data_b_r 打一拍 生成data_b_rr 信号 做上边沿检测 生成脉冲信号。
2.多bit跨时钟域处理:
(1)异步FIFO+格雷码
(2)握手协议
(3)DMUX选择器:在快时钟域转慢时钟域时 仍然需要对使能信号进行脉冲扩宽。