SOC設計——多時鐘源切換MUX設計

在數字電路設計中,模塊的運行時鐘切換時,需要考慮到是否會產生毛刺,小小的毛刺有可能導致電路運行的錯誤。所以時鐘切換時需要特別的處理。

1.主要的結構框圖:

在這裏插入圖片描述

2.觸發器關鍵部分源碼:

在這裏插入圖片描述

3. 源碼

module gf_ckmux #(
    parameter SRC_CLK_NUM = 2  //support 2/4/8
)
(
    input                                    rstn        ,
    input   [           (SRC_CLK_NUM-1):0]   i_clk       ,
    input   [((`GLOG(SRC_CLK_NUM-1))-1):0]   sel         ,
    output  [     (SRC_CLK_NUM-1):0]         dbg         ,
    output                                   o_clk
);
  wire [(SRC_CLK_NUM-1):0]  src_clk_lb, clk_en ;
  reg  [(SRC_CLK_NUM-1):0]  n_en_reg           ;
  reg  [(SRC_CLK_NUM-1):0]  n_en_reg_dly       ;
  wire [(SRC_CLK_NUM-1):0]  sync_clken_out     ;

  wire [(SRC_CLK_NUM-1):0]  src_clk_inv        ;

  wire [(SRC_CLK_NUM-1):0]  out_clk_and        ;

  genvar index;


  generate for(index=0;index<SRC_CLK_NUM;index=index+1)
    begin
      stsoc_ckbuf donttouch_ckbuf_lb(
          .i_clk (i_clk[index]),
          .o_clk (src_clk_lb[index])
       );

      stsoc_ckinv donttouch_ckinv(
          .i_clk (i_clk[index]),
          .o_clk (src_clk_inv[index])
       );

     if(index==0)
     begin
       stsoc_sync_l3_wrapper_def_high donttouch_sync_clk_en (
         .ck   (src_clk_lb[index]),
         .clb  (rstn),
         .d    (clk_en[index]),
         .o    (sync_clken_out[index])
       );
      end
     else
     begin
       stsoc_sync_l3_wrapper donttouch_sync_clk_en (
         .ck   (src_clk_lb[index]),
         .clb  (rstn),
         .d    (clk_en[index]),
         .o    (sync_clken_out[index])
       );
      end

      always @(posedge src_clk_inv[index] or negedge rstn)
        if(!rstn)
        begin
          if(index==0)
            begin
              n_en_reg[index]     <= 1'b1  ;
              n_en_reg_dly[index] <= 1'b1  ;
            end
          else
            begin
              n_en_reg[index]     <= 1'b0     ;
              n_en_reg_dly[index] <= 1'b0     ;
            end
        end
        else
          begin
            n_en_reg[index] <= sync_clken_out[index]  ;
            n_en_reg_dly[index] <= n_en_reg[index] ;
          end

      stsoc_ckand donttouch_clk_and(
        .i_clk(i_clk[index]),
        .d    (n_en_reg[index]),
        .o_clk(out_clk_and[index])
      );

      assign dbg[index] = n_en_reg_dly[index];
    end
  endgenerate

  generate case(SRC_CLK_NUM)
     2 : begin
           assign clk_en[0] = ~sel & (!n_en_reg_dly[1]) ;
           assign clk_en[1] =  sel & (!n_en_reg_dly[0]) ;
           stsoc_ckor u_donttouch_ckout (.i0_clk(out_clk_and[0]), .i1_clk(out_clk_and[1]), .o_clk(o_clk));
         end
     4 : begin 
           assign clk_en[0] = (sel==2'h0) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[3]);
           assign clk_en[1] = (sel==2'h1) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[3]);
           assign clk_en[2] = (sel==2'h2) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[3]);
           assign clk_en[3] = (sel==2'h3) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[2]);

           wire o_0_clk;
           wire o_1_clk;

           stsoc_ckor donttouch_l0_ckout (.i0_clk(out_clk_and[0]), .i1_clk(out_clk_and[1]), .o_clk(o_0_clk));
           stsoc_ckor donttouch_l1_ckout (.i0_clk(out_clk_and[2]), .i1_clk(out_clk_and[3]), .o_clk(o_1_clk));
           stsoc_ckor donttouch_ckout    (.i0_clk(o_0_clk       ), .i1_clk(o_1_clk       ), .o_clk(o_clk  ));
         end
     8 : begin
           assign clk_en[0] = (sel==3'h0) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[3]) & (!n_en_reg_dly[4]) & (!n_en_reg_dly[5]) & (!n_en_reg_dly[6]) & (!n_en_reg_dly[7]);
           assign clk_en[1] = (sel==3'h1) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[3]) & (!n_en_reg_dly[4]) & (!n_en_reg_dly[5]) & (!n_en_reg_dly[6]) & (!n_en_reg_dly[7]);
           assign clk_en[2] = (sel==3'h2) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[3]) & (!n_en_reg_dly[4]) & (!n_en_reg_dly[5]) & (!n_en_reg_dly[6]) & (!n_en_reg_dly[7]);
           assign clk_en[3] = (sel==3'h3) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[4]) & (!n_en_reg_dly[5]) & (!n_en_reg_dly[6]) & (!n_en_reg_dly[7]);
           assign clk_en[4] = (sel==3'h4) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[3]) & (!n_en_reg_dly[5]) & (!n_en_reg_dly[6]) & (!n_en_reg_dly[7]);
           assign clk_en[5] = (sel==3'h5) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[3]) & (!n_en_reg_dly[4]) & (!n_en_reg_dly[6]) & (!n_en_reg_dly[7]);
           assign clk_en[6] = (sel==3'h6) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[3]) & (!n_en_reg_dly[4]) & (!n_en_reg_dly[5]) & (!n_en_reg_dly[7]);
           assign clk_en[7] = (sel==3'h7) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[2]) & (!n_en_reg_dly[3]) & (!n_en_reg_dly[4]) & (!n_en_reg_dly[5]) & (!n_en_reg_dly[6]);

           wire o_0_clk;
           wire o_1_clk;
           wire o_2_clk;
           wire o_3_clk;
           wire o_00_clk;
           wire o_11_clk;

           stsoc_ckor donttouch_l0_ckout  (.i0_clk(out_clk_and[0]), .i1_clk(out_clk_and[1]), .o_clk(o_0_clk));
           stsoc_ckor donttouch_l1_ckout  (.i0_clk(out_clk_and[2]), .i1_clk(out_clk_and[3]), .o_clk(o_1_clk));
           stsoc_ckor donttouch_l2_ckout  (.i0_clk(out_clk_and[4]), .i1_clk(out_clk_and[5]), .o_clk(o_2_clk));
           stsoc_ckor donttouch_l3_ckout  (.i0_clk(out_clk_and[6]), .i1_clk(out_clk_and[7]), .o_clk(o_3_clk));

           stsoc_ckor donttouch_l00_ckout (.i0_clk(o_0_clk       ), .i1_clk(o_1_clk    ), .o_clk(o_00_clk));
           stsoc_ckor donttouch_l11_ckout (.i0_clk(o_2_clk       ), .i1_clk(o_3_clk    ), .o_clk(o_11_clk));
           stsoc_ckor donttouch_ckout     (.i0_clk(o_00_clk      ), .i1_clk(o_11_clk   ), .o_clk(o_clk  ));
         end
     16 : begin
           assign clk_en[ 0] = (sel==4'h0) &                      (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 1] = (sel==4'h1) & (!n_en_reg_dly[0])                      & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 2] = (sel==4'h2) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1])                       & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 3] = (sel==4'h3) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2])                       & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 4] = (sel==4'h4) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3])                       & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 5] = (sel==4'h5) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4])                       & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 6] = (sel==4'h6) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5])                       & (!n_en_reg_dly[ 7])
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 7] = (sel==4'h7) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6])                     
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 8] = (sel==4'h8) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])
                                                                & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]);
           assign clk_en[ 9] = (sel==4'h9) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])  
                                           & (!n_en_reg_dly[8])                      & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]); 
           assign clk_en[10] = (sel==4'ha) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])  ;
                                          // & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9])                       & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]); 
           assign clk_en[11] = (sel==4'hb) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])  
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10])                       & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]); 
           assign clk_en[12] = (sel==4'hc) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])  
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11])                       & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]); 
           assign clk_en[13] = (sel==4'hd) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])  
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12])                       & (!n_en_reg_dly[14]) & (!n_en_reg_dly[15]); 
           assign clk_en[14] = (sel==4'he) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])  
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13])                       & (!n_en_reg_dly[15]); 
           assign clk_en[15] = (sel==4'hf) & (!n_en_reg_dly[0]) & (!n_en_reg_dly[1]) & (!n_en_reg_dly[ 2]) & (!n_en_reg_dly[ 3]) & (!n_en_reg_dly[ 4]) & (!n_en_reg_dly[ 5]) & (!n_en_reg_dly[ 6]) & (!n_en_reg_dly[ 7])  
                                           & (!n_en_reg_dly[8]) & (!n_en_reg_dly[9]) & (!n_en_reg_dly[10]) & (!n_en_reg_dly[11]) & (!n_en_reg_dly[12]) & (!n_en_reg_dly[13]) & (!n_en_reg_dly[14]) ; 


           wire o_0_clk;
           wire o_1_clk;
           wire o_2_clk;
           wire o_3_clk;
           wire o_00_clk;
           wire o_11_clk;

           stsoc_ckor donttouch_l0_ckout  (.i0_clk(out_clk_and[0]), .i1_clk(out_clk_and[1]), .o_clk(o_0_clk));
           stsoc_ckor donttouch_l1_ckout  (.i0_clk(out_clk_and[2]), .i1_clk(out_clk_and[3]), .o_clk(o_1_clk));
           stsoc_ckor donttouch_l2_ckout  (.i0_clk(out_clk_and[4]), .i1_clk(out_clk_and[5]), .o_clk(o_2_clk));
           stsoc_ckor donttouch_l3_ckout  (.i0_clk(out_clk_and[6]), .i1_clk(out_clk_and[7]), .o_clk(o_3_clk));

           stsoc_ckor donttouch_l00_ckout (.i0_clk(o_0_clk       ), .i1_clk(o_1_clk    ), .o_clk(o_00_clk));
           stsoc_ckor donttouch_l11_ckout (.i0_clk(o_2_clk       ), .i1_clk(o_3_clk    ), .o_clk(o_11_clk));
           stsoc_ckor donttouch_l_ckout   (.i0_clk(o_00_clk      ), .i1_clk(o_11_clk   ), .o_clk(o_l_clk  ));

           stsoc_ckor donttouch_h0_ckout  (.i0_clk(out_clk_and[ 8]), .i1_clk(out_clk_and[ 9]), .o_clk(o_4_clk));
           stsoc_ckor donttouch_h1_ckout  (.i0_clk(out_clk_and[10]), .i1_clk(out_clk_and[11]), .o_clk(o_5_clk));
           stsoc_ckor donttouch_h2_ckout  (.i0_clk(out_clk_and[12]), .i1_clk(out_clk_and[12]), .o_clk(o_6_clk));
           stsoc_ckor donttouch_h3_ckout  (.i0_clk(out_clk_and[14]), .i1_clk(out_clk_and[13]), .o_clk(o_7_clk));
                                
           stsoc_ckor donttouch_h00_ckout (.i0_clk(o_4_clk       ), .i1_clk(o_5_clk    ), .o_clk(o_22_clk));
           stsoc_ckor donttouch_h11_ckout (.i0_clk(o_6_clk       ), .i1_clk(o_7_clk    ), .o_clk(o_33_clk));
           stsoc_ckor donttouch_h_ckout   (.i0_clk(o_22_clk      ), .i1_clk(o_33_clk   ), .o_clk(o_h_clk  ));

           stsoc_ckor donttouch_ckout   (.i0_clk(o_l_clk      ), .i1_clk(o_h_clk   ), .o_clk(o_clk  ));


         end

     default: assign o_clk=1'b0;
    endcase
  endgenerate
endmodule

歡迎關注下面公衆號,每週精選一篇原創文章!!!

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章