glitch free mux(2)

`timescale  1ns/10ps
module  clock_mux (
    // OUTPUTs
    //=========
    output         clk_out,        // Clock output
 
    // INPUTs
    //=========
    input          clk_in0,        // Clock input 0
    input          clk_in1,        // Clock input 1
    input          reset,            // Reset
    input          select_in       // Clock selection
);
 
//==================================================================================================================//
// 1)  CLOCK MUX                                                                                                    //
//==================================================================================================================//
//                                                                                                                  //
// The following (glitch free) clock mux is implemented as following:                                               //
//                                                                                                                  //
//                                                                                                                  //
//                                                                                                                  //
//                                               dff0a        dff0b                                                 //
//                                +-----.     +--------+   +--------+                                               //
// select_in >>----+-------------O|          |        |   |        |          +-----.                              //
//                 |              |       |---| D    Q |---| D    Q |--+-------|                                   //
//                 |     +-------O|      /    |        |   |        |  |       |       |O-+                         //
//                 |     |        +-----'     |        |   |        |  |   +--O|      /   |                         //
//                 |     |                    |   /   |   |   /   |  |   |   +-----'    |                         //
//                 |     |                    +--+--+--+   +--+--+--+  |   |              |                         //
//                 |     |                        O            |       |   |              |                         //
//                 |     |                        |            |       |   |              |  +-----.                //
//    clk_in0 >>----------------------------------+------------+-----------+              +--|                     //
//                 |     |                                             |                     |       |----<< clk_out//
//                 |     |     +---------------------------------------+                  +--|      /               //
//                 |     |     |                                                          |  +-----'                //
//                 |     +---------------------------------------------+                  |                         //
//                 |           |                 dff1a        dff1b    |                  |                         //
//                 |           |  +-----.     +--------+   +--------+  |                  |                         //
//                 |           +-O|          |        |   |        |  |       +-----.    |                         //
//                 |              |       |---| D    Q |---| D    Q |--+-------|         |                         //
//                 +--------------|      /    |        |   |        |          |       |O-+                         //
//                                +-----'     |        |   |        |      +--O|      /                             //
//                                            |   /   |   |   /   |      |   +-----'                              //
//                                            +--+--+--+   +--+--+--+      |                                        //
//                                                O            |           |                                        //
//                                                |            |           |                                        //
//    clk_in1 >>----------------------------------+------------+-----------+                                        //
//                                                                                                                  //
//                                                                                                                  //
//==================================================================================================================//
 
//----------------------------------------
//  Regs declare
//----------------------------------------
 
reg   dff0a,dff0b;
reg   dff1a,dff1b;
 
wire  clk_in0_inv = ~clk_in0;
wire  clk_in1_inv = ~clk_in1;
 
//----------------------------------------
//  clk_in0 path
//----------------------------------------
 
// negedge of clk_in0
always @(posedge clk_in0_inv or posedge reset)
  if(reset)   dff0a <=  1'b1;
  else      dff0a <=  !select_in & !dff1b;
 
always @(posedge clk_in0 or posedge reset)
  if(reset)   dff0b <=  1'b1;
  else      dff0b <=  dff0a;
 
wire  clk_in0_gate  = ~(~clk_in0 & dff0b);
 
//----------------------------------------
//  clk_in1 path
//----------------------------------------
// negedge of clk_in1
always @(posedge clk_in1_inv or posedge reset)
  if(reset)   dff1a <=  1'b0;
  else      dff1a <=  select_in & !dff0b;
 
always @(posedge clk_in1 or posedge reset)
  if(reset)   dff1b <=  1'b0;
  else      dff1b <=  dff1a;
 
wire  clk_in1_gate  = ~(~clk_in1 & dff1b);
 
//-----------------------
//  clock mux out
//-----------------------
assign  clk_out = clk_in0_gate & clk_in1_gate;
 
endmodule
 
 
  1. 《verilog编程艺术》中的时钟切换电路
 
 
`timescale  1ns/1ns
module  clk_switch
  (
    input   clk_a,
    input   clk_b,
    input   select,
    output  out_clk
  );
 
reg q1,q2,q3,q4;
wire  or_one,or_two,or_three,or_four;
 
always @(posedge clk_a)
  if(clk_a==1'b1) begin
    q1  <=  q4;
    q3  <=  or_one;
  end
 
always @(posedge clk_b)
  if(clk_b==1'b1)  begin
    q2  <=  q3;
    q4  <=  or_two;
  end
assign  or_one  = (!q1) | (select == 1'b1);
assign  or_two  = (!q2) | (select == 1'b0);
 
assign  or_three  = (q3) | (clk_a);
assign  or_four = (q4) | (clk_b);
 
assign  out_clk = or_three & or_four;
 
endmodule
 
module  clk_switch_tb;
reg clk_a,clk_b;
reg select;
wire  out_clk;
 
clk_switch  clk_switch(clk_a,clk_b,select,out_clk);
 
initial begin
  clk_a = 0;
  forever #50 clk_a = !clk_a;
end
initial begin
  clk_b = 0;
  forever #10 clk_b = !clk_b;
end
 
initial begin
  select  = 0;
  #1000;
  select  = 1;
  #1000;
  select  = 0;
  #1000;
  select  = 1;
  #1000;
  $finish;
end
 
endmodule
 

原文地址:https://www.cnblogs.com/yylei/p/12584872.html