跨时钟域处理总结
1、跨时钟域处理总结
网上资源太乱且杂,或缺少方法,或缺少代码,或缺少仿真,故在此特意总结一下方便学习,会持续更新
更新时间说明:
2024.12.15确定总结
2024.12.16更新
2、单bit信号跨时钟域处理
2.1 慢时钟到快时钟
频率相差2倍以上,快时钟采样不会丢失,不用考虑,使用两级触发器同步也就是电平同步器。但为了避免快时钟多次采样到有效信号,使用边沿检测同步器。
频率相差2倍以上,为了避免快时钟多次采样到有效信号,快时钟域对信号进行边沿检测,使用边沿检测同步器。
频率相差2倍以下,为避免快时钟采样丢失,需要进行握手的同步处理。
2.1.1 两级触发器
module slow_fast(
input a_clk,
input a_rst_n,
input a_data,
input b_clk,
input b_rst_n,
output b_data
);
reg [1:0]r_data;
reg [1:0]r_data1;
always@(posedge a_clk or negedge a_rst_n)begin
if(!a_rst_n)begin
r_data <= 'd0;
end else begin
r_data <= {r_data[0],a_data};
end
end
always@(posedge b_clk or negedge b_rst_n)begin
if(!b_rst_n)begin
r_data1 <= 'd0;
end else begin
r_data1 <= {r_data1[0],r_data[1]};
end
end
assign b_data = r_data1[1];
endmodule
Testbennth代码
module tb_slow_fast(
);
reg a_clk ;
reg a_rst_n ;
reg a_data ;
reg b_clk ;
reg b_rst_n ;
wire b_data ;
slow_fast slow_fast(
.a_clk (a_clk ),
.a_rst_n(a_rst_n),
.a_data (a_data ),
.b_clk (b_clk ),
.b_rst_n(b_rst_n),
.b_data (b_data )
);
initial a_clk = 1'b1 ;
always#10 a_clk = ~a_clk ;//a_clk 50MHZ
initial b_clk = 1'b1 ;
always#2.5 b_clk = ~b_clk ;//b_clk 200MHZ
initial begin
a_rst_n = 0;b_rst_n = 0;a_data = 0;#8 ;
a_rst_n = 1;b_rst_n = 1;a_data = 0;#20;
a_data = 1;#20;
a_data = 0;#20;
a_data = 1;#20;
a_data = 0;#20;
a_data = 1;#20;
a_data = 0;#20;
$stop;
end
endmodule
2.1.2 边沿检测同步器
module slow_fast(
input a_clk,
input a_rst_n,
input a_data,
input b_clk,
input b_rst_n,
output b_data
);
reg [1:0]r_data;
reg [1:0]r_data1;
always@(posedge a_clk or negedge a_rst_n)begin
if(!a_rst_n)begin
r_data <= 'd0;
end else begin
r_data <= {r_data[0],a_data};
end
end
always@(posedge b_clk or negedge b_rst_n)begin
if(!b_rst_n)begin
r_data1 <= 'd0;
end else begin
r_data1 <= {r_data1[0],r_data[1]};
end
end
assign b_data = !r_data1[1] & r_data1[0];
endmodule