在數字電路設計中,模塊的運行時鐘切換時,需要考慮到是否會產生毛刺,小小的毛刺有可能導致電路運行的錯誤。所以時鐘切換時需要特別的處理。
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
歡迎關注下面公衆號,每週精選一篇原創文章!!!