RTL设计(9)- 脉冲同步器

脉冲同步器

由于脉冲在快时钟域传递到慢时钟域时,慢时钟有时无法采样的信号,因此需要对信号进行处理,可以让慢时钟采样到脉冲信号。
在这里插入图片描述

注意:
(1)快时钟域的脉冲都是单周期脉冲
(2)快时钟域中相邻两个脉冲的间隔时间要至少是慢时钟域的2个周期才能保证输出的同步脉冲是正确的。

程序实例

pulseSynchronizer.v

`timescale 1ns / 1ps

// Company: 
// Engineer: 
// 
// Create Date: 2020/12/19
// Author Name: Sniper
// Module Name: pulseSynchronizer
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 


module pulseSynchronizer(
    input rst_n,
    //clock domain 1
    input clk1,
    input pulse_in,
    //clock domain 2
    input clk2,
    output pulse_out
);

reg reverse_reg;
always @(posedge clk1 or negedge rst_n)
    if(!rst_n)
        reverse_reg <= 1'b0;
    else if(pulse_in)
			reverse_reg <= ~reverse_reg;


reg [2:0] buff_reg;
always @(posedge clk2 or negedge rst_n)
    if(!rst_n)
        buff_reg[2:0] <=3'b000;
    else
        buff_reg[2:0] <={
    
    buff_reg[1:0],reverse_reg};


assign pulse_out = buff_reg[2]^buff_reg[1];


endmodule

tb_pulseSynchronizer.v

`timescale 1ns / 1ps

// Company:
// Engineer:
//
// Create Date: 2020/12/19
// Author Name: Sniper
// Module Name: tb_pulseSynchronizer
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//


module tb_pulseSynchronizer;

//input
reg rst_n;
reg clk1;
reg pulse_in;
reg clk2;


//output
wire pulse_out;



initial
begin
    rst_n = 0;
    clk1 = 0;
    pulse_in = 0;
    clk2 = 0;

	#100;
    rst_n = 1;

    repeat(5) @(posedge clk1);
    @(posedge clk1);
    pulse_in <= 1;
    @(posedge clk1);
    pulse_in <= 0;

    repeat(2) @(posedge clk1);
    @(posedge clk1);
    pulse_in <= 1;
    @(posedge clk1);
    pulse_in <= 0;

    repeat(10) @(posedge clk1);
    @(posedge clk1);
    pulse_in <= 1;
    @(posedge clk1);
    pulse_in <= 0;

    repeat(10) @(posedge clk1);
    @(posedge clk1);
    pulse_in <= 1;
    @(posedge clk1);
    pulse_in <= 0;
    @(posedge clk1);
    pulse_in <= 1;
    @(posedge clk1);
    pulse_in <= 0;

    repeat(10) @(posedge clk1);
    @(posedge clk1);
    pulse_in <= 1;
    @(posedge clk1);
    pulse_in <= 1;
    @(posedge clk1);
    pulse_in <= 0;

end

//clock
always #5 clk1 = ~clk1;
always #12 clk2 = ~clk2;



//DUT
pulseSynchronizer DUT
(
    .rst_n(rst_n),
    .clk1(clk1),
    .pulse_in(pulse_in),
    .clk2(clk2),
    .pulse_out(pulse_out)
);

initial
begin
    $dumpfile("tb_pulseSynchronizer.vcd");
    $dumpvars(0,tb_pulseSynchronizer);
end

initial #1000 $finish;

endmodule

仿真结果

vcs -R pulseSynchronizer.v tb_pulseSynchronizer.v

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/meng1506789/article/details/111407708