以单bit跨时钟域讲解说明
(多bits)跨时钟域有异步fifo或者异步双口RAM实现。
分为2种情况,以单Bit信号从慢时钟域到快时钟域和快时钟域到慢时钟域来说明。
1、慢时钟域到快时钟域
慢时钟域到快时钟域是经常遇到的,通常我们用寄存器打两拍就可以。
module bit_reg(
input wire clk,
input wire rst_n,
input wire in_bit,
output wire out_bit
);
reg[1:0] bit_buffer;
always@(posedge clk or negedge rst_n)
if(!rst_n)
bit_buffer <= 2'd0;
else
bit_buffer <= {bit_bffer[0],in_bit};
assign out_bit = bit_buffer[1];
endmodule
2、快时钟域到慢时钟域
快时钟域到慢时钟域就不能用慢时钟域的时钟直接打两拍了,如果快时钟域下存在1个时钟的高脉冲,很有可能慢时钟域就采集不到,所以导致信号丢失。
这样我们就先在快时钟域下将这个信号延长,然后再用慢时钟域的去采集。
module mul_clk(
input wire clk_a,
input wire clk_b,
input wire rst_n,
input wire in_bit,
output out_bit
);
reg reg_a,reg_b;//用来将输入信号进行扩展
reg[1:0] reg_a_r;
reg[1:0] reg_b_r;
always@(posedge clk_a or negedge rst_n)
if(!rst_n)
reg_a <= 1'b0;
else if(in_bit==1'b1)
reg_a <= 1'b1;
else if(reg_a_r[1]==1'b1) //这个信号是将reg_b在慢时钟下打两拍得到的信号
reg_a <= 1'b0;
//在慢时钟下对快时钟下的扩展信号进行同步
always@(posedge clk_b or negedge rst_n)
if(!rst_n)
reg_b <= 1'b0;
else
reg_b <= reg_a;
always@(posedge clk_b or negedge rst_n)
if(!rst_n)
reg_b_r <= 2'b00;
else
reg_b_r <= {reg_b_r[0],reg_b};
//在快时钟域下对慢时钟域下的同步信号进行同步,目的是为了清快时钟域下的扩展信号
always@(posedge clk_a or negedge rst_n)
if(!rst_n)
reg_a_r <= 2'b00;
else
reg_a_r <= {reg_a_r[0],reg_b_r[1]};
assign out_bit = ~reg_b_r[1] & reg_b_r[0];