回复 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 |