| 
 | 
 
 楼主 |
发表于 2016-9-29 17:46:50
|
显示全部楼层
 
 
 
回复 1# 杰克淡定  
 
发现有些同学都不去仔细看看文字说明部分,完全只看了RTL部分,就来说什么时钟上升沿啊下降沿啊之类的,没有懂得将原设计灵活变通。下面用大家更喜欢用的与逻辑实现gating重写一遍,下面设计不如原设计好,原因自己去看原文说明。 
    module clk_switch ( 
                rst_n          , // 
                clka            , // 
                clkb            , // 
                sel_clkb      , // 
                clk_o            // 
                ); 
 
assign clka_n = ~clka; 
assign clkb_n = ~clkb; 
 
always @ (posedge clka or negedge rst_n) 
begin 
    if (!rst_n) begin 
        sel_clka_d0 <= 1'b0; 
        sel_clka_d1 <= 1'b0; 
    end 
    else begin 
        sel_clka_d0 <= (~sel_clkb) & (~sel_clkb_dly3) ; 
        sel_clka_d1 <= sel_clka_d0 ; 
    end 
end 
 
always @ (posedge clka_n or negedge rst_n) 
begin 
    if (!rst_n) begin 
        sel_clka_dly1 <= 1'b0; 
        sel_clka_dly2 <= 1'b0; 
        sel_clka_dly3 <= 1'b0; 
    end 
    else begin 
        sel_clka_dly1 <= sel_clka_d1; 
        sel_clka_dly2 <= sel_clka_dly1 ; 
        sel_clka_dly3 <= sel_clka_dly2 ; 
    end 
end 
 
always @ (posedge clkb or negedge rst_n) 
begin 
    if (!rst_n) begin 
        sel_clkb_d0 <= 1'b0; 
        sel_clkb_d1 <= 1'b0; 
    end 
    else begin 
        sel_clkb_d0 <= sel_clkb & (~sel_clka_dly3) ; 
        sel_clkb_d1 <= sel_clkb_d0 ; 
    end 
end 
 
always @ (posedge clkb_n or negedge rst_n) 
begin 
    if (!rst_n) begin 
        sel_clkb_dly1 <= 1'b0; 
        sel_clkb_dly2 <= 1'b0; 
        sel_clkb_dly3 <= 1'b0; 
    end 
    else begin 
        sel_clkb_dly1 <= sel_clkb_d1   ; 
        sel_clkb_dly2 <= sel_clkb_dly1 ; 
        sel_clkb_dly3 <= sel_clkb_dly2 ; 
    end 
end 
 
assign clka_g = clka & sel_clka_dly3 ; 
assign clkb_g = clkb & sel_clkb_dly3 ; 
assign clk_o  = clka_g | clkb_g ; 
 
endmodule |   
 
 
 
 |