assign sync_sel_clk1 = latch1_1;
assign sync_sel_clk0 = latch1_0;
assign handshake_f1t0 = hs_latch_f1_t0_2nd;
assign handshake_f0t1 = hs_latch_f0_t1_2nd;
assign clk0_g = clk0_gating & async_clk0;
assign clk0_gating = (~sync_sel_clk0) & (~handshake_f1t0);
assign clk1_g = clk1_gating & async_clk1;
assign clk1_gating = (sync_sel_clk1 & handshake_f0t1);
assign clkout = clk0_g | clk1_g;
// 在clk1域内同步sel
always @(posedge async_clk1 or negedge rst_n) begin
if (rst_n == 0) begin
latch2_1 <= 1'b0;
latch1_1 <= 1'b0;
latch0_1 <= 1'b0;
end
else begin
latch2_1 <= latch1_1;
latch1_1 <= latch0_1;
latch0_1 <= sel;
end
end
// 在clk0域内同步sel
always @(posedge async_clk0 or negedge rst_n) begin
if (rst_n == 0) begin
latch2_0 <= 0;
latch1_0 <= 0;
latch0_0 <= 0;
end
else begin
latch2_0 <= latch1_0;
latch1_0 <= latch0_0;
latch0_0 <= sel;
end
end
// 将clk1中同步后的sel送到clk0域内再同步一下
always @(posedge async_clk0 or negedge rst_n) begin
if (rst_n == 0) begin
hs_latch_f1_t0_2nd <= 0;
hs_latch_f1_t0_1st <= 0;
end
else begin
hs_latch_f1_t0_2nd <= hs_latch_f1_t0_1st;
hs_latch_f1_t0_1st <= latch2_1;
end
end
// 将clk0中同步后的sel送到clk1域内再同步一下
always @(posedge async_clk1 or negedge rst_n) begin
if (rst_n == 0) begin
hs_latch_f0_t1_2nd <= 0;
hs_latch_f0_t1_1st <= 0;
end
else begin
hs_latch_f0_t1_2nd <= hs_latch_f0_t1_1st;
hs_latch_f0_t1_1st <= latch2_0;
end