赞
踩
简单来讲,“跨时钟域处理”即:
①输入和输出的参照时钟不同。
②中间过程的多个步骤会由不同的时钟控制。
跨时钟域处理一般涉及“打拍”,即输入和输出中间空几个时钟周期作为缓冲,其目的在于:
打拍(缓冲)可以减小亚稳态概率。
打拍的经验原则:
一般的,在时钟切换的时候,依照后来的时钟打两拍。
(如由clk_a切换到clk_b,那么需要clk_b先空打两拍,再进行别的操作。)
【详细了解:CDC:跨时钟域处理】
在data_en为高期间,data_in将保持不变,data_en为高至少保持3个B时钟周期。表明,当data_en为高时,可将数据进行同步。data_in端数据变化频率很低,相邻两个数据间的变化,至少间隔10个B时钟周期。
时钟clk_a负责:
① 数据data_in输入时,参照时钟a。(打一拍)
② 使能信号data_en输入时,参照时钟a。(打一拍)
时钟clk_b负责:
① 使能信号data_en延时打两拍,即过两个D触发器。这个过程参照时钟b。
② 数据最终输出dataout,输出时参照时钟b。
1. 时钟域clk_a: data_in和data_en寄存。(打一拍)
//clk_a打一拍接受数据和接受使能信号en
reg [3:0] data_reg;
always@(posedge clk_a or negedge arstn)
begin
if(!arstn) data_reg <= 0;
else data_reg <= data_in;
end
reg en_data_reg;
always@(posedge clk_a or negedge arstn)
begin
if(!brstn) en_data_reg <= 0;
else en_data_reg <= data_en; //存入
end
2. 时钟域clk_b: en信号打两拍 + dataout输出
//clk_b负责使能信号en的打拍 reg en_clap_one; //1 reg en_clap_two; //2 always@(posedge clk_b or negedge brstn) begin if(!brstn) en_clap_one <= 0; else en_clap_one <= en_data_reg; //第一拍 end always@(posedge clk_b or negedge brstn) begin if(!brstn) en_clap_two <= 0; else en_clap_two <= en_clap_one; //第二拍 end //clk_b负责输出 always@(posedge clk_b or negedge brstn) begin if(!brstn) dataout <= 0; else dataout <= (en_clap_two) ? data_reg : dataout; end
完整代码:
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 ); /* 跨时钟域传输:输入和输出的参照时钟不同。中间过程的多个步骤会由不同的时钟控制。 本题:clk_a接受数据--->clk_b延时两拍,然后数据才输出。 */ //clk_a打一拍接受数据和接受使能信号en reg [3:0] data_reg; always@(posedge clk_a or negedge arstn) begin if(!arstn) data_reg <= 0; else data_reg <= data_in; end reg en_data_reg; always@(posedge clk_a or negedge arstn) begin if(!brstn) en_data_reg <= 0; else en_data_reg <= data_en; //存入 end //clk_b负责使能信号en的打拍 reg en_clap_one; //1 reg en_clap_two; //2 always@(posedge clk_b or negedge brstn) begin if(!brstn) en_clap_one <= 0; else en_clap_one <= en_data_reg; //第一拍 end always@(posedge clk_b or negedge brstn) begin if(!brstn) en_clap_two <= 0; else en_clap_two <= en_clap_one; //第二拍 end //clk_b负责输出 always@(posedge clk_b or negedge brstn) begin if(!brstn) dataout <= 0; else dataout <= (en_clap_two) ? data_reg : dataout; end endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。