门控时钟
将控制信号与时钟进行同步有效解决上升沿之间或下降沿之间时间变短(Tcycle减小,不满足建立时间保持时间)
always@(negedge clk)begin
if(!clk)begin
EN_LAT<=EN;
end
end
assign Q=EN_LAT&clk;
时钟切换(例:cpu切换主频,前提要保证正常工作---不产生glitch)
产生glitch,上升沿到上升沿之间不满足一个时钟周期(不满足建立保持时间)
原因:secelt没有在时钟沿上生效
设计思路
1、先通过译码器将两路输入in[1:0]译码位三路信号sel1、sel2、sel3
2、每个sel用各自clk打三拍,三拍及当前输入均为0,则说明该信号不在使用,in_used=0,否则为1
3、当其他两个时钟均in_used==0时,才给另外一个时钟使能,使能信号经过门控时钟送到输出
三级同步
always@(posedge clk0 or negedge rst_n)begin
if (!rst_n)begin
sel0_syn_0 <= 0;
sel0_syn_1 <= 0;
sel0_syn_2 <= 0;
end
else begin
sel0_syn_0 <= sel0;
sel0_syn_1 <= sel0_syn_0;
sel0_syn_2 <= sel0_syn_1;
end
end
调用门控时钟
clk_gating clk_gating_inst0 (
.en (en0),
.clk (clk0),
.clk_out (clk_out_0)
);
生成使能信号
assign in_used_0 = sel0_syn_0 | sel0 | sel0_syn_1 |sel0_syn_2;
assign in_used_1 = sel1_syn_0 | sel1 | sel1_syn_1 |sel1_syn_2;
assign in_used_2 = sel2_syn_0 | sel2 | sel2_syn_1 |sel2_syn_2;
assign en0 = ~in_used_1&&~in_used_2;
assign en1 = ~in_used_0&&~in_used_2;
assign en2 = ~in_used_0&&~in_used_1;
调用门控时钟
clk_gating clk_gating_inst0 (
.en (en0),
.clk (clk0),
.clk_out (clk_out_0)
);
输出
assign clk_out=clk_out_0|clk_out_1|clk_out_2;