快时钟域到慢时钟域脉冲检测
程序:
//+FHEADER////////////////////////////////////////////////////// // Author : weitter // Email : weitter@qq.com // School : Fuzhou University // Date : 2021-04-11 // Filename : detect_pluse.v // Modulename : detect_pluse // //-------------------------------------------------------------- //输入变量: // input clk_fast , //输入的快时钟信号 // input clk_slow , //输入的慢时钟信号 // input reset_n , //输入的复位信号 //-------------------------------------------------------------- //输出变量: // output pluse_out_slow , //块时钟域输入的脉冲信号 // output signal_out_slow //输出检测有效信号 //-------------------------------------------------------------- //功能描述: //通过反馈结构,能够检测快时钟域到慢时钟域(和慢时钟域到块时钟域)的脉冲信号。 //-FHEADER////////////////////////////////////////////////////// module detect_pluse ( input clk_fast ,//输入的快时钟信号 input clk_slow ,//输入的慢时钟信号 input reset_n ,//输入的复位信号 input pluse_in_fast ,//块时钟域输入的脉冲信号 output pluse_out_slow ,//输出相应的慢时钟脉冲信号 output signal_out_slow //输出检测有效信号 ); reg signal_in_fast ; reg [1:0] signal_in_r ; always@(posedge clk_fast)begin//快时钟域 if(!reset_n)begin // reset signal_in_fast <= 1'b0; end else if(pluse_in_fast == 1'b1)begin//检测到脉冲的高电平 signal_in_fast <= 1'b1;//有效信号 end else if (signal_in_r[1] == 1'b1) begin//反馈回来拉低 signal_in_fast <= 1'b0; end else begin signal_in_fast <= signal_in_fast;//保持 end end reg signal_in_slow; always@(posedge clk_slow)begin//慢时钟域 if(!reset_n)begin // reset signal_in_slow <= 1'b0; end else begin signal_in_slow <= signal_in_fast;//快时钟域到慢时钟域 end end reg [1:0] signal_out_r; always@(posedge clk_slow)begin//慢时钟域 if(!reset_n)begin // reset signal_out_r <= 2'b00; end else begin signal_out_r <= {signal_out_r[0],signal_in_slow};//两级缓存 end end assign pluse_out_slow = (~signal_out_r[1]) & signal_out_r[0];//上升沿检测 assign signal_out_slow = signal_out_r[1];//有效信号输出 always@(posedge clk_fast)begin//快时钟域 if(!reset_n)begin // reset signal_in_r <= 2'b00; end else begin signal_in_r <={signal_in_r[0],signal_out_r[1]};//反馈回去 end end endmodule
测试程序:
`include "F:\\FPGA_code\\detect_pluse\\detect_pluse.v" `timescale 1ns/1ps module detect_pluse_tb ; reg clk_fast ; reg clk_slow ; reg reset_n ; reg pluse_in_fast ; wire pluse_out_slow ; wire signal_out_slow ; detect_pluse d1( .clk_fast(clk_fast) , .clk_slow(clk_slow) , .reset_n(reset_n) , .pluse_in_fast(pluse_in_fast) , .pluse_out_slow(pluse_out_slow) , .signal_out_slow(signal_out_slow) ); /////////////////////////////////////////////////////// // 产生块慢时钟 /////////////////////////////////////////////////////// initial begin clk_fast = 1'b0;//初始化 clk_slow = 1'b0; end always #5 clk_fast = ~clk_fast;//模拟块时钟 always #27 clk_slow = ~clk_slow;//模拟慢时钟 /////////////////////////////////////////////////////// // 产生同步复位信号 /////////////////////////////////////////////////////// initial begin reset_n = 1'b1;//初始化 #100 @(posedge clk_fast) begin reset_n = 1'b0; end repeat(5) @(posedge clk_fast); @(posedge clk_fast) begin reset_n = 1'b1; end #1000 $stop;//停止 end /////////////////////////////////////////////////////// // 产出脉冲信号 /////////////////////////////////////////////////////// initial begin pluse_in_fast =1'b0;//初始化 #500 @(posedge clk_fast) begin pluse_in_fast = 1'b1; end @(posedge clk_fast) begin pluse_in_fast = 1'b0; end end endmodule
仿真结果: