verilog 基础设计11-glitch free 无毛刺的时钟切换

目录

1、毛刺的危害

2、无毛刺的处理

(1) 相关时钟的glitch free 处理

(2)不相关时钟的无毛刺切换


1、毛刺的危害

普通的时钟切换电路,通常由一个选择器构成,存在产生毛刺的危害,如下图所示

其波形图如下

     由于sel信号可能在任意时刻变化,所以 ,如上如所示,当sel由0跳变为1时,选通的信号由clk0切换成clk1,出现一个glitch。

2、无毛刺的处理

(1)相关时钟的glitch free 处理

  (2)   不相关时钟的glitch free 处理

 (1) 相关时钟的glitch free 处理

            保证时钟切换时,只发生在时钟下降沿   ,并且只有在前一个时钟输出失效时另一个时钟选择端才会被选通

verlilog 实现

//相关时钟无毛刺切换
module glitch_free(
    input wire clk0,
    input wire clk1,
    input wire sel,
    output wire clkout
);

reg ff0_q;
wire ff0_qfei;
reg ff1_q;
wire ff1_qfei;

wire sel0;
wire sel1;

wire clkout0;
wire clkout1;

assign sel0 = sel & ff1_qfei;
assign sel1 = ~sel & ff0_qfei;

assign ff0_qfei = ~ff0_q;
assign ff1_qfei = ~ff1_q;

always @(negedge clk0) begin
    ff0_q <= sel0;
end

always @(negedge clk1) begin
    ff1_q <= sel1;
end 

assign clkout0 = ff0_q & clk0;
assign clkout1 = ff1_q & clk1;

assign clkout = clkout0 | clkout1;

endmodule 

tb文件

`timescale 1ns/1ps
module tb_glitch_free;

reg clk0;
reg clk1;
reg sel;
wire clkout;

initial begin
    clk0 =0;
    clk1 =0;
    sel =0;
    #995
    sel=1;
    #500
    sel =0;
end

always #5 clk0 = ~clk0;
always #20 clk1 = ~clk1;



glitch_free glitch_free_inst(
    .clk0(clk0),
    .clk1(clk1),
    .sel(sel),
    .clkout(clkout)
);


endmodule 

仿真结果:

 

        clkout 为时钟输出,可以看出无毛刺完成时钟切换 

(2)不相关时钟的无毛刺切换

                这种情况下,每个通道都加一个上升沿采样的寄存器

verilog实现

//不相关时钟无毛刺切换
module glitch_free(
    input wire clk0,
    input wire clk1,
    input wire sel,
    output wire clkout
);

reg ff0_q;
wire ff0_qfei;
reg ff1_q;
wire ff1_qfei;

wire sel0;
wire sel1;

wire clkout0;
wire clkout1;


reg syn_ff0q;
reg syn_ff1q;

assign sel0 = sel & ff1_qfei;
assign sel1 = ~sel & ff0_qfei;

assign ff0_qfei = ~ff0_q;
assign ff1_qfei = ~ff1_q;

//多了一级寄存器
always @(posedge clk0) begin
    syn_ff0q <= sel0;
end

always @(posedge clk1) begin
    syn_ff1q <= sel1;
end

always @(negedge clk0) begin
    ff0_q <= syn_ff0q;
end

always @(negedge clk1) begin
    ff1_q <= syn_ff1q;
end 

assign clkout0 = ff0_q & clk0;
assign clkout1 = ff1_q & clk1;

assign clkout = clkout0 | clkout1;

endmodule 

仿真结果图:

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值