Verilog--CDC跨时钟域处理(快时钟域到慢时钟域)
今天先写单比特信号从快时钟域到慢时钟域的方法,后续继续填坑
CDC问题
单比特信号的跨时钟域问题
从快时钟域到慢时钟域
设计思想
从慢时钟域到快时钟域通常使用打两拍的方法,这也适用于从快时钟域到慢时钟域时,但是如果当单比特信号持续时间小于快时钟域的一个周期时,需要用展宽信号再打两拍的方法。
设计相关代码
module Sync_Pulse
(
input clka, //快时钟域
input clkb, //慢时钟域
input rst_n,
input pulse_ina, //脉冲或电平信号都可以
output pulse_outb, //脉冲信号
output signal_outb //电平信号
);
//--------------------------------------------------------
reg signal_a;
reg signal_a_r1;
reg signal_a_r2;
reg signal_b;
reg signal_b_r1;
//--------------------------------------------------------
//-- a时钟域生成展宽信号
//--------------------------------------------------------
always @(posedge clka or negedge rst_n)begin
if(!rst_n)begin
signal_a <= 1'b0;
end
else if(pulse_ina) begin //检测到脉冲
signal_a <= 1'b1; //拉高
end
else if(signal_a_r2) begin //同步到b后同步回a
signal_a <= 1'b0; //拉低,展宽使命完成
end
end
//--------------------------------------------------------
//-- 展宽信号同步到b时钟域再同步回a时钟域
//--------------------------------------------------------
always @(posedge clkb or negedge rst_n)begin
if(!rst_n)begin
signal_b <= 1'b0;
signal_b_r1 <= 1'b0;
end
else begin
signal_b <= signal_a;
signal_b_r1 <= signal_b;
end
end
always @(posedge clka or negedge rst_n)begin
if(!rst_n)begin
signal_a_r1 <= 1'b0;
signal_a_r2 <= 1'b0;
end
else begin
signal_a_r1 <= signal_b_r1;
signal_a_r2 <= signal_a_r1;
end
end
//--------------------------------------------------------
//-- 脉冲信号输出,上升沿检测
//--------------------------------------------------------
assign pulse_outb = ~signal_b_r1 & signal_b;
//--------------------------------------------------------
//-- 电平信号输出,b时钟域展宽信号
//--------------------------------------------------------
assign signal_outb = signal_b_r1;
endmodule
tb文件
`timescale 1ns/100ps
module tb_cdc_f2s ();
reg clka;
reg clkb;
reg rst_n;
reg pulse_ina;
wire pulse_outb;
wire signal_outb;
initial begin
clka = 0;
clkb = 0;
rst_n = 0;
#10
rst_n = 1;
end
initial begin
pulse_ina = 0;
#30
pulse_ina = 1;
#2
pulse_ina = 0;
#218
pulse_ina = 1;
#2
pulse_ina = 0;
end
always #10 clka = ~clka;
always #20 clkb = ~clkb;
cdc_f2s u_cdc_f2s(
.clka (clka),
.clkb (clkb),
.rst_n (rst_n),
.pulse_ina (pulse_ina),
.pulse_outb (pulse_outb),
.signal_outb (signal_outb)
);
endmodule
Modelsim仿真结果
从慢时钟域到快时钟域
多比特信号的跨时钟域问题
异步FIFO
可以看我这一篇
https://blog.csdn.net/weixin_44425619/article/details/115406095