1.序言
实现单个脉冲信号,由快时钟域传输到慢时钟域。
2.思路
慢时钟域很难采样到快时钟域脉冲(特别是频率相差很大时),所以我们将输入的脉冲信号变换为电平信号,当快时钟域输入脉冲到来时,状态发生翻转,慢时钟域就将检测脉冲信号改换为了检测电平变换。
3.例子(牛客网VL49脉冲同步电路)
(1)题目描述
(2)实现
A 首先在快时钟域将输入的脉冲信号,变换为脉冲到来时,状态发生反转的电平信号:
//将脉冲信号转换为电平信号
reg data_in_reg;
always@(posedge clk_fast or negedge rst_n)begin
if(!rst_n)
data_in_reg <= 1'b0;
else
data_in_reg <= data_in?(!data_in_reg):data_in_reg;
end
B 电平信号跨时钟域传输到慢时钟域(慢时钟域时钟打两拍)
//跨时钟域数据传输
reg data_in_mid;
reg data_in_slow;
always@(posedge clk_slow or negedge rst_n)begin
if(!rst_n)begin
data_in_mid <= 1'b0;
data_in_slow <= 1'b0;
end
else begin
data_in_mid <= data_in_reg;
data_in_slow <= data_in_mid;
end
end
C 慢时钟域的脉冲检测电路,此时通过电平翻转检测实现,包括数据打一拍和翻转检测两部分实现
//慢时钟域数据状态变换检测
reg data_in_slow_reg;
always@(posedge clk_slow or negedge rst_n)begin
if(!rst_n)
data_in_slow_reg <= 1'b0;
else
data_in_slow_reg <= data_in_slow;
end
assign dataout = ((data_in_slow_reg&&(!data_in_slow))||(((!data_in_slow_reg)&&data_in_slow)));
(3)完整代码
`timescale 1ns/1ns
module pulse_detect(
input clk_fast ,
input clk_slow ,
input rst_n ,
input data_in ,
output dataout
);
//将脉冲信号转换为电平信号
reg data_in_reg;
always@(posedge clk_fast or negedge rst_n)begin
if(!rst_n)
data_in_reg <= 1'b0;
else
data_in_reg <= data_in?(!data_in_reg):data_in_reg;
end
//跨时钟域数据传输
reg data_in_mid;
reg data_in_slow;
always@(posedge clk_slow or negedge rst_n)begin
if(!rst_n)begin
data_in_mid <= 1'b0;
data_in_slow <= 1'b0;
end
else begin
data_in_mid <= data_in_reg;
data_in_slow <= data_in_mid;
end
end
//慢时钟域数据状态变换检测
reg data_in_slow_reg;
always@(posedge clk_slow or negedge rst_n)begin
if(!rst_n)
data_in_slow_reg <= 1'b0;
else
data_in_slow_reg <= data_in_slow;
end
assign dataout = ((data_in_slow_reg&&(!data_in_slow))||(((!data_in_slow_reg)&&data_in_slow)));
endmodule