单bit信号跨时钟域传输,慢到快和快到慢。
一、慢时钟域传递到快时钟域
慢到快很简单,可以直接打两拍同步,也不存在脉冲展宽的问题。
代码实现:
module clk_cross_slow2fast(
input clk_slow,
input clk_fast,
input rst_n,
input data_slow,
output data_fast
);
reg [1:0] sig_fast_r;
always@(posedge clk_fast or negedge rst_n)begin
if(!rst_n)begin
sig_fast_r <= 2'b0;
end
else begin
sig_fast_r <= {sig_fast_r[0],data_slow};
end
end
assign data_fast = sig_fast_r[1];
endmodule
测试波形
二、快时钟域传递到慢时钟域
快时钟到慢时钟要稍微麻烦一些,在快时钟下输入数据,输出pulse_slow单脉冲信号和data_slow信号
基本思路:
1、快时钟检测到输入,赋值给有效信号signal_fast
2、慢时钟下将有效信号signal_fast赋值给signal_slow
3、慢时钟下完成输出
4、慢时钟的输出信号对快时钟的反馈,控制快时钟下signal_fast_r拉低,表示一次传输完成
代码实现:
module clk_cross_fast2slow(
input clk_slow,
input clk_fast,
input rst_n,
input data_fast,
output pulse_slow,
output data_slow
);
reg sig_fast;
reg sig_slow;
reg [1:0] sig_fast_r;
reg [1:0] sig_slow_r;
always@(posedge clk_fast or negedge rst_n)begin // 快时钟下保持
if(!rst_n)begin
sig_fast <= 0;
end
else if(data_fast)begin
sig_fast <= 1;
end
else if(sig_fast_r[1])begin
sig_fast <= 0;
end
else begin
sig_fast <= sig_fast;
end
end
always@(posedge clk_slow or negedge rst_n)begin // 传递给慢时钟域
if(!rst_n)begin
sig_slow <= 0;
end
else begin
sig_slow <= sig_fast;
end
end
always@(posedge clk_slow or negedge rst_n)begin // 慢时钟下保持
if(!rst_n)begin
sig_slow_r <= 2'b0;
end
else begin
sig_slow_r <= {sig_slow_r[0],sig_slow};
end
end
assign data_slow = sig_slow_r[1];
assign pulse_slow = ~sig_slow_r[1] & sig_slow_r[0];
always@(posedge clk_fast or negedge rst_n)begin // 慢时钟对快时钟的反馈
if(!rst_n)begin
sig_fast_r <= 2'b0;
end
else begin
sig_fast_r <= {sig_fast_r[0],sig_slow_r[1]};
end
end
endmodule
测试波形