|  | 
 
 楼主|
发表于 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
 | 
 |