随着各种应用场景的限制,芯片在运行时往往需要在不同的应用下切换不同的时钟源,例如低功耗和高性能模式就分别需要低频率和高频率的时钟。两个时钟源有可能是同源且同步的,也有可能是不相关的。直接使用选择逻辑进行时钟切换大概率会导致分频时钟信号出现毛刺现象,所以时钟切换逻辑也需要进行特殊的处理。
直接采用选择逻辑对时钟进行切换的电路图如下所示。


在两个电平相反的时候切换时钟,肯定有毛刺;电平相同的时候,即使不产生毛刺,时钟切换后的第一个时钟的周期或占空比也不是理想的。所以,为避免毛刺的产生,需要在两个时钟都为低电平的时候进行时钟切换。
一种典型的时钟切换电路如下所示。
该电路利用时钟下降沿对时钟选择信号 sel_clk1 进行缓存。同时一个时钟选择信号对另一个时钟进行反馈控制,保证同一时刻只能有一路时钟有效。最后采用"或操作"将两路时钟合并,完成时钟切换的过程。

采用上述电路完成时钟切换(clk1->clk2)的波形示意图如下所示。
由图可知,clk1 向 clk2 切换时,先关闭 clk1, 然后打开 clk2。由于时钟选择信号被同步到时钟下降沿,所以切换过程中不会出现毛刺。

clk2 向 clk1 切换的波形示意图如下所示。

考虑到选择信号有可能是异步信号,需要在时钟选择信号的缓存触发器之前加两级触发器进行同步处理,来减少亚稳态的传播,结构图如下。该时钟切换电路更具有普遍性。

普遍且安全的时钟切换逻辑描述如下。
module clk_switch(
input rstn ,
input clk1,
input clk2,
input sel_clk1 , // 1 clk1, 0 clk2
output clk_out
);
reg [2:0] sel_clk1_r ;
reg [1:0] sel_clk1_neg_r ;
reg [2:0] sel_clk2_r ;
reg [1:0] sel_clk2_neg_r ;
//使用3拍缓存,同步另一个时钟控制信号与本时钟控制信号的"与"逻辑操作
always @(posedge clk1 or negedge rstn) begin
if (!rstn) begin
sel_clk1_r <= 3'b111 ; //注意默认值
end
else begin
//sel clk1, and not sel clk2
sel_clk1_r <= {sel_clk1_r[1:0], sel_clk1 & (!sel_clk2_neg_r[1])} ;
end
end
//在下降沿,使用2拍缓存时钟选择信号
always @(negedge clk1 or negedge rstn) begin
if (!rstn) begin
sel_clk1_neg_r <= 2'b11 ; //注意默认值
end
else begin
sel_clk1_neg_r <= {sel_clk1_neg_r[0], sel_clk1_r[2]} ;
end
end
//使用3拍缓存,同步另一个时钟控制信号与本时钟控制信号的"与"逻辑操作
always @(posedge clk2 or negedge rstn) begin
if (!rstn) begin
sel_clk2_r <= 3'b0 ; //注意默认值
end
else begin
//sel clk2, and not sel clk1
sel_clk2_r <= {sel_clk2_r[1:0], !sel_clk1 & (!sel_clk1_neg_r[1])} ;
end
end
//在下降沿,使用2拍缓存时钟选择信号
always @(negedge clk2 or negedge rstn) begin
if (!rstn) begin
sel_clk2_neg_r <= 2'b0 ; //注意默认值
end
else begin
sel_clk2_neg_r <= {sel_clk2_neg_r[0], sel_clk2_r[2]} ;
end
end
//时钟逻辑运算时,一般使用特定的工艺单元库。
//这里用 Verilog 自带的逻辑门单元代替
wire clk1_gate, clk2_gate ;
and (clk1_gate, clk1, sel_clk1_neg_r[1]) ;
and (clk2_gate, clk2, sel_clk2_neg_r[1]) ;
or (clk_out, clk1_gate, clk2_gate) ;
endmodule
testbench 描述如下,主要产生异步时钟的选择信号。
`timescale 1ns/1ps
module test ;
reg clk_100mhz, clk_200mhz ;
reg rstn ;
reg sel ;
wire clk_out ;
always #(2.5) clk_200mhz = ~clk_200mhz ;
always @(posedge clk_200mhz)
clk_100mhz = #1 ~clk_100mhz ;
initial begin
clk_100mhz = 0 ;
clk_200mhz = 0 ;
rstn = 0 ;
sel = 1 ;
#11 rstn = 1 ;
#36.2 sel = ~sel ;
#119.7 sel = ~sel ;
end
clk_switch u_clk_switch(
.rstn (rstn),
.clk1 (clk_100mhz),
.clk2 (clk_200mhz),
.sel_clk1 (sel),
.clk_out (clk_out));
initial begin
forever begin
#100;
if ($time >= 10000) $finish ;
end
end
endmodule
仿真结果如下,可见时钟相互切换时没有产生毛刺,但是存在延迟。

我正在从erb文件切换到HAML。我将hamlgem添加到我的系统中。我创建了app/views/layouts/application.html.haml文件。我应该只删除application.html.erb文件吗?此外,仍然有/public/index.html文件被呈现为默认页面。我想创建自己的默认index.html.haml页面。我应该把它放在哪里以及如何使系统呈现该文件而不是默认索引文件?谢谢! 最佳答案 是的,您可以删除任何已转换为HAML的View的ERB版本。至于你的另一个问题,删除public/index/h
目录一、inout在设计文件中的使用方法1.1、inout的第一种使用方法1.2、inout实现的第二种使用方法1.3、inout使用总结 二、inout在仿真测试中的使用方法一、inout在设计文件中的使用方法在FPGA的设计过程中,有时候会遇到双向信号(既能作为输出,也能作为输入的信号叫双向信号)。比如,IIC总线中的SDA信号就是一个双向信号,QSPIFlash的四线操作的时候四根信号线均为双向信号。在Verilog中用关键字inout定义双向信号,这里总结一下双向信号的处理方法。1.1、inout的第一种使用方法 实际上,双向信号的本质是由一个三态门组成的,三态门可以输出高电平,低电
我的Rails应用程序在rails4.0.2上,我在使用locale变量和params[:locale]切换翻译时遇到问题官方railsguide.我在mysite有一个单页网站.我的国际化路线:scope"(:locale)",locale:/en|de/do#myrouteshereend我的应用程序Controllerbefore_filter:set_localedefset_localeI18n.locale=params[:locale]||I18n.default_locale#Rails.application.routes.default_url_options[:l
我目前从prototype切换到jquery主要是为了支持简单的ajax文件上传。我使用:https://github.com/indirect/jquery-rails95%的javascript代码是由railshelper编写的,例如:-remote_function-render:updatedo|page|-page.replace_html'id',:partial=>'content'-page['form']['name']=something-page.visual_effect:highlight,'head_success'...我知道我必须为Jquery重写5%
FPGA时钟和时钟域时钟树所谓时钟树为FPGA内部资源,分:全局时钟树,区域时钟树,IO时钟树原则上优先使用全局时钟树,在GT接口上使用IO时钟树,一般工具也会对GT时钟加以限制;时钟树使用方式正确的物理连接FPGA会由物理管脚专门用于全局时钟设置,通过查询数据手册可以在PCB设计阶段进行确认,当外部时钟接入此管脚时,工具会自动占有全局时钟树资源,当接入普通信号时不会分配时钟树资源;恰当的代码描述原语的使用,即BUFG的使用,可以将PLL的输出等内部时钟进行全局时钟资源的分配;IO时钟资源需要参考相应接口手册,以ultrascale的GTH为例,其JESD204的时钟方案针对不同的子类会由不同
在开发微信小程序的时候,我们可能需要开发环境和测试环境,或者其他环境,下面是切换环境的方法。首先需要明确的是:前端的页面代码是不区分环境的,环境的区分指的是云函数、云数据库、云存储这些。1、更改云函数的使用云环境这里我们从cloud1更改为test-cloud,这个改完是没有用的,因为在前端代码指定了使用的云环境。cloudfunctions文件和miniprogram文件虽然都在一个目录下,但是这两个没有直接联系。2、在evList.js中添加自己云环境evList.js存储了云环境列表,这里把test-cloud加到这个列表里,需要填写envId和alias,参照cloud1写就行。3、更
我有一个操作可以简单地将#active属性切换到相反的bool状态:如果@blog.active==true然后更新它到非事件如果@blog.active==false然后更新它到事件我在Controller中获得了以下自定义操作,但必须有一些Rails方法才能更优雅地执行此操作:classBlogsController是否有一种Rails方法可以将bool属性更新为相反的bool状态? 最佳答案 ActiveRecord具有执行此操作的toggle和toggle!方法。请记住,toggle!方法会跳过验证检查。classBlogs
在RSpec中我可以使用这样的代码切换到弹出窗口,link,我怎么能在cucumber步骤中做这样的事情?login_window=page.driver.find_window('PPA_identity_window')main_window=page.driver.find_window('')#Weusethistoexecutethenextinstructionsinthepopupwindowpage.within_window(login_window)do#Normallyfillintheformandloginfill_in'email',:with=>""fil
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、设计原理1.DS1302介绍2.闹钟音乐播放原理二、程序设计1.DS1302.h2.ds1302.c3.music.h4.main.c三、电路图四、运行结果1.proteus仿真2.开发板实验五、总结六、附件提示:以下是本篇文章正文内容,下面案例可供参考一、设计原理1.DS1302介绍DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。该芯片采用普通32.768kHz晶振,DS1302工作时功耗很
我们在服务器管理中有以下模式-所有用户都有自己的用户,但部署完全由特殊部署用户执行,没有直接登录的可能性。我们在Capistrano2.x中使用了这个方法:default_run_options[:shell]="sudo-udeploybash"$capstagedeploy-suser=thisisme我知道Capistrano3.x有直接切换用户的方法:task:installdoonroles(:all)doas:deploydoexecute:whoamiendendend但是这段代码会填充所有任务,默认任务不会继承deploy用户。是否可以直接设置登录用户而无需将此代码拖到