Loading

[数字IC手撕verilog]时钟无毛刺切换

[数字IC手撕verilog]时钟无毛刺切换

img

module clk_glitch_free
(
    input clk1,
    input clk2,

    input rst_n,

    input en,

    output clk_out
);

    reg clk1_q1, clk1_q2;
    reg clk2_q1, clk2_q2;

    always @(posedge clk1 or negedge rst_n)begin
        if(!rst_n)
            clk1_q1 <= 1'b0;
        else
            clk1_q1 <= en & ~clk2_q2;
    end

    always @(negedge clk1 or rst_n)begin
        if(!rst_n)
            clk1_q2 <= 1'b0;
        else
            clk1_q2 <= clk1_q1;
    end

    always @(posedge clk2 or negedge rst_n)begin
        if(!rst_n)
            clk2_q1 <= 1'b0;
        else
            clk1_q1 <= ~en & ~clk1_q2;
    end

    always @(negedge clk2 or rst_n)begin
        if(!rst_n)
            clk2_q2 <= 1'b0;
        else 
            clk2_q2 <= clk1_q1;
    end

    assign clk_out = (clk1 & clk1_q2) || (clk2 & clk2_q2);
endmodule

testbench

`timescale 1ns/1ps
module tb;

	reg clk1, clk2;
	
	reg en, rstn;
	wire clk_out;
	initial begin
		clk1 = 1'b0;
		#5 clk1 = 1'b1;
		forever clk1 = ~clk1;
	end
	
	initial begin
		clk2 = 1'b0;
		#12 clk2 = 1'b1;
		forever clk2 = ~clk2;
	end
	
	initial begin
		rstn = 1'b0;
		#25 rstn = 1'b1;
	end
	
	initial begin
		en = 1'b0;
		
		#80 en = 1'b1;
		#120 en = 1'b0;
		#60 en = 1'b1;
		#50 $finish;
	end
	
	
	clk_glitch_free inst 
	(clk1, clk2, rstn, clk_out);
	
endmodule
posted @ 2022-08-04 14:55  pu1se  阅读(147)  评论(0)    收藏  举报