快时钟域到慢时钟域脉冲检测

程序:

//+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

仿真结果:

原文地址:https://www.cnblogs.com/weitter/p/14644692.html