脉冲同步器
由于脉冲在快时钟域传递到慢时钟域时,慢时钟有时无法采样的信号,因此需要对信号进行处理,可以让慢时钟采样到脉冲信号。
注意:
(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