verilog glitch_free两个时钟切换电路

1.glitch free的两个时钟切换电路

参考openMSP430 ipcore中的时钟切换电路

  • 切换电路首先想到就是多路选择器,切换时钟在不考虑glitch的通常写法会是:
    assign clk_o = sel ? clk1:clk2;
    但是由于sel,clk1,clk2 都是不同步的。在实现任意时刻切换时钟时候,就有一定的一定的概率产生glitch,一旦glitch被采用会对结果照成影响。
    时钟切换逻辑避免产生glitch的原理
    不管关闭还是使能,都必须保证当前时钟或目标时钟的使能信号的跳变都分别在时钟为低电平期间进行的,防止产生时钟glitch。
    因此通常需要进行4个步骤:
    1.打开选择信号。2.在clk1为低电平时关掉clk1的选择端。3.在clk2为低电平时打开clk2的选择端。4.完成切换。
    因此在进行时钟切换通常需要考虑两个问题。
  • 跨时钟域的同步问题。
  • 同步好的切换信号如何处理与时钟信号,才能消除glitch
    verilog glitch_free两个时钟切换电路_第1张图片
    代码
`timescale 1ns/1ps
module glitch_free(
						input clk0,
						input clk1,
						input reset,
						input sel,
						output clko
					);
	reg dff01,dff02;
	reg dff11,dff12;
	 
	wire clk0_inv = ~clk0;
	wire clk1_inv = ~clk1;
//clk0
always @ (posedge clk0_inv or posedge reset)
	if(reset)
		dff01 <= 1'b1;
	else
		dff01 <= !sel & !dff12;
always @ (posedge clk0 or posedge reset)
	if(reset)
		dff02 <= 1'b1;
	else 
		dff02 <= dff01;
wire clk0_gate = ~(~clk0 & dff02);

//clk1
always @ (posedge clk1_inv or posedge reset)
	if(reset)
		dff11 <= 1'b0;
	else
		dff11 <= sel & !dff02;
always @ (posedge clk0 or posedge reset)
	if(reset)
		dff12 <= 1'b0;
	else 
		dff12 <= dff11;
		
wire clk1_gate = ~(~clk1 & dff12);
//mux
assign clko = clk1_gate & clk0_gate;
endmodule

RTL级
verilog glitch_free两个时钟切换电路_第2张图片
仿真结果
verilog glitch_free两个时钟切换电路_第3张图片
github
https://github.com/zsylov/verliog-study/edit/master/2019.5.13glitchfree.md
后续进行3个时钟信号切换的研究

你可能感兴趣的:(verilog,仿真)