马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x

时钟切换分成两种方式,普通切换和去毛刺无缝切换。

普通切换,就是不关心切出的时钟是否存在毛刺,这种方式电路成本小。如果时钟切换时,使用此时钟的模块电路处于非工作状态,或者模块内电路被全局复位信号reset住的,即使切出毛刺也不会导致DFF误触发,这样的模块可以选择用此种切换方式。写法很简单 assign clk_o = sel_clkb ? clkb : clka ,当sel_clkb为1时选择clkb,否则选择clka。不过在实际设计中,建议直接调用库里的MUX单元并set_dont_touch,不要采用这里的assign写法,因为这种写法最后综合得到的可能不是MUX而是复杂组合逻辑,给前后端流程的时钟约束和分析带来不便。

无缝切换,就是切换时无毛刺时钟平稳过渡。在时钟切换中,只要出现比clka或者clkb频率更高的窄脉冲,不论是窄的高电平还是窄的低电平,都叫时钟毛刺。工作在切换后时钟clk_o下的电路模块,综合约束是在max{clka,clkb}频率下的,也就是说设计最后signoff的时候,只保证电路可以稳定工作的最高频率是max{clka,clkb},如果切换中出现更高频的时钟毛刺,电路可能出现无法预知的结果而出错。无缝切换,一般用在处于工作状态的模块需要调频或者切换时钟源,比如内部系统总线,cpu等。你刚用手机打完游戏后马上关屏听音乐,这两种场景中,CPU在满足性能前提下为了控制功耗,其工作频率会动态地从很高调至较低,此时就可能是在CPU一直处于工作状态下,通过无缝切换时钟源头实现的。

在无缝切换电路中,切换信号sel_clkb可以是任意时钟域下的信号,包括但不限于clka或者clkb域,但是sel_clkb必须是一个DFF输出信号;clka与clkb的频率大小相位关系可以任意。无缝切换需要解决两个问题,一是异步切换信号的跨时钟域同步问题,这里需要使用《verilog基本电路设计之一》里的同步电路原理消除亚稳态;二是同步好了的切换信号与时钟信号如何做逻辑,才能实现无毛刺。

下面写出无缝切换电路的主体部分,忽略了内部信号的定义声明等。

module clk_switch (

rst_n          , //

clka            , //

clkb            , //

sel_clkb      , //

clk_o            //

);

//assign clka_n = ~clka;

//assign clkb_n = ~clkb;

// part1

//always @ (posedge clka_n or negedge rst_n)

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

// part2

//always @ (posedge clka_n or negedge rst_n)

always @ (posedge clka 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

// part3

//always @ (posedge clkb_n or negedge rst_n)

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

// part4

//always @ (posedge clkb_n or negedge rst_n)

always @ (posedge clkb 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// part5

clk_gate_xxx clk_gate_a ( .CP(clka), .EN(sel_clka_dly1), .Q(clka_g)  .TE(1'b0) );

clk_gate_xxx clk_gate_b ( .CP(clkb), .EN(sel_clkb_dly1), .Q(clkb_g)  .TE(1'b0) );

//assign clka_g = clka & sel_clka_dly1 ;

//assign clkb_g = clkb & sel_clkb_dly1 ;

assign clk_o = clka_g | clkb_g ;

endmodule

上面是我认为比较合理的无缝切换电路,其他切换方式跟这个会有些许出入,但基本大同小异原理是一样的。有几点说明:

1、抛开注释掉的电路不看,由于part5部分直接调用库里的clock gating cell,使得整个切换电路全部只需要用到时钟上升沿,无需额外定义反向时钟,精简了DC综合的时钟约束;直接调用gating cell的 另一个好处是,前后端工具会自动检查gating cell的CP信号与EN信号的setup/hold时间,使得gating后的Q时钟输出无毛刺尖峰。TE端可以根据实际需要接上scan测试模式信号。如果使用part5部分的gating cell实现,前面的part1,2,3,4全部替换成注释掉的反相时钟也是没有问题。

2、part2和part4部分,具体需要多少级DFF,甚至完全不要也是可以的,这就回到了《Verilog基本电路设计之一》里讨论的到底多少级DFF消除亚稳态才算合理的问题。时钟频率很低可能无所谓,如果时钟频率达到GHz,这部分建议至少保留三级DFF,因为三级DFF延时也仅仅只有3ns的时间裕度。没必要为了省这么几个DFF降低电路可靠性,在复杂IP以及大型SOC系统中,你会发现多几十个DFF,面积上可以忽略,系统可靠性和稳定性才是首要的。

3、如果part5部分希望使用注释掉的两行“与”逻辑实现时钟gating,此时part1与part3使用正相或者反相时钟都可以,但是必须把part2和part4部分改为注释掉的反相时钟实现,目的是初步从RTL设计上避免“与”逻辑的毛刺,同时还需要后端配合,因为很多后端工具对时钟“与”逻辑的clock gating check未必会检查。用clk下降沿拍出的en信号,再跟clk做与逻辑得到的门控时钟,在RTL仿真阶段看到的一定不会有毛刺,但是布线完成后,如果clk相对en后移,那与逻辑得到的门控时钟就有毛刺了。这就是用与逻辑做门控的缺点,由于后端工具可能不会去检查这个与门的时序关系而导致出错。但直接调用库里的gating cell,工具天然就会去检查这个时序,免去人工确认的后顾之忧。

最后,请大家仔细看看sel_clka_d0 <= (~sel_clkb) & (~sel_clkb_dly3)  和sel_clkb_d0 <= sel_clkb & (~sel_clka_dly3) 这两处逻辑,按理说,sel_clkb跟sel_clka_dly3以及sel_clkb_dly3之间相互都是异步的,而按照异步信号同步处理原则,两个不同时钟域下的信号是不允许直接做组合逻辑的,为什么这里可以这样使用?

verilog时钟翻转怎么写_Verilog基本电路设计之二(时钟无缝切换)相关推荐

  1. verilog时钟翻转怎么写_verilog实时可调时钟代码

    module clock(clk,out,reset,cin,ocom,count,countmin,tgm,tdm,tgs,tds); output[3:0] ocom; output[7:0] o ...

  2. verilog设计一个分,秒定时器电路:输入时钟1KHZ进行分秒计数

    verilog设计一个分,秒定时器电路:输入时钟1KHZ进行分秒计数 目标 实现分秒计数 问题分析 首先要求1KHZ的时钟,周期为1*10e-3s,达成1秒需要1000个周期,因为没有提到占空比就偷懒 ...

  3. AM335x kernel4.4.12 LCD 时钟翻转设置记录

    TI AM335x kernel 4.4.12 LCD display 时钟翻转记录 因为公司硬件上已经确定LCD 转LVDS 转换芯片上确认以上升沿时钟为基准,所以只能在软件上调整相关东西. 入口在 ...

  4. 时钟翻转事件_开发人员和时钟翻转

    时钟翻转事件 Let's party like it's 1999! 让我们狂欢吧,就像1999年一样! You have probably written programs with a bug r ...

  5. verilog中数组的定义_verilog数组定义及其初始化

    这里的内存模型指的是内存的行为模型.Verilog中提供了两维数组来帮助我们建立内存的行为模型.具体来说,就是可以将内存宣称为一个reg类型的数组,这个数组中的任何一个单元都可以通过一个下标去访问.这 ...

  6. css3实现时钟翻转

    虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 非常想念各位 ...

  7. 【数字IC基础】降动态功耗(降时钟翻转频率):门控时钟(clock gating)

    文章目录 十五.门控时钟(clock gating)!!! 15.1.概念 15.2.锁存时钟与门控电路 15.3.锁存时钟或门控电路 15.4.寄存时钟与门控电路 15.5.时钟门控的RTL代码编写 ...

  8. DIY小四轴之电路设计(二)

    DIY小四轴之电路设计(二) 上次我分析了四轴电源的电路,这次我们来看电机驱动与传感器电路. 三.空心杯电机驱动电路 一般的小型四轴都选用空心杯电机来驱动旋翼,空心杯电机不仅节能而且灵敏,是一种比较理 ...

  9. sdram 时钟相位_零基础学FPGA (二十五)必会! 从静态时序分析到SDRAM时序收敛(下篇)...

    七.SDRAM工作时钟相位偏移计算本文引用地址:http://www.eepw.com.cn/article/279083.htm 从上篇文章中我们知道,我们的数据是要经过一定的延时才会到达目标器件的 ...

最新文章

  1. 元素的子元素_从暂元里取出子元素 | Stata编程
  2. 动态代理-JDK_proxycglib
  3. Django学习之数据库与ORM
  4. 第五章 Python数据结构
  5. 调查称HTML5获多数开发者支持 亚太最高
  6. Wizard of Orz CodeForces - 1467A
  7. 如何使用python批量压缩图片_python利用Guetzli批量压缩图片
  8. 微信公众号支付开发(java)实例详解
  9. wincc7.5系统语言切换功能(C脚本)
  10. Python华氏摄氏度的转换
  11. web前端知识——常见布局方案、文章排版、图片排版、某宝列表
  12. VSCode 插件Code Runner 中文提示乱码
  13. git clone报错Could not resolve proxy : proxy-szn
  14. html css3滤镜,CSS滤镜之Glow属性_css
  15. 区块链技术应用到现实场景中,是个什么样?
  16. mysql 立方根函数_Java实现牛顿迭代法求解平方根、立方根
  17. 移动通信网络规划:干扰隔离要求
  18. 专家教你10个秘诀 70%癌症都能预防
  19. kali_上传_腾讯云_搭建kali
  20. Python 遍历List三种方式

热门文章

  1. 1. 人工智能(AI)概述
  2. EPICS记录参考--模拟输出记录(ao)
  3. c1欧洲语言标准是什么水平,CEFR 为什么会成为全球语言标准体系?
  4. 苹果退款_苹果 App Store 里自动订阅续费的应用可以退款吗?
  5. 华为云认证有什么用?怎么考?
  6. 记华为云服务器配置mysql-Navicat连接
  7. 深入浅出系列之 -- kafka消费者的三种语义模型
  8. 易基因 | 学科前沿:靶向甲基化测序揭示维生素C可防止孕期吸烟引发的后代DNA甲基化改变
  9. Ubuntu 安装 SSH 服务
  10. linux服务器集群群发邮件,爱博邮件群发服务器(Linux版本)