前置概念
- 晶振。**压电效应,用来产生高精度振荡频率的一种电子器件**
- RC 振荡器。电容可以充放电的特点,利用这一特性可以**输出振荡信号**。
Clock Source
- HSE(High Frequency Source external) 高速外部时钟:一般接晶振。一般在 4~24MHz。
- HSI(High Frequency Source Internal)高速内部时钟: RC 振荡器产生的,频率一般 8M 左右,不是很稳定。
- LSE(Low Frequency Source external)低速外部时钟: 接外部晶振的,频率为 32.768KHz。 为什么是这么一串奇怪的数字(并不, 32768 很整的好么)。它是 2 的 15 次方。分频 15 次恰好是 1HZ。1 秒 1 次。用于 RTC。
- LSI(Low Frequency Source Internal),低速内部时钟: 这个也是 RC 振荡器产生的,也可以给 RTC,时钟频率在 40KHz 左右。
👆🏻这些始终最高不过几十 MHz,SoC 内部基本都是几百 MHz 往上的高速时钟信号是怎么来的呢》
一般来讲需要跑 >16MHz 时钟的芯片里,要有一个用来倍频的部分。
所有为什么要用 PLL 呢?因为外部晶振常见的就 16MHz 以下。虽然也有 200MHz 的晶振,但一方面价格非常贵,不适合产品控制成本,另一方面,这么快的时钟从片外输入不是很稳定。
PLL (phase-locked-loop) 锁相环
高速的倍频时钟。 PLL 是做在芯片内部的一个模块,你不需要清楚内部原理,但是你需要知道它可以产生稳定的倍频时钟。
例如一头接在 16MHz 的 HSE 上,PLLCLK 就能获得 32MHz, 64MHz 等等高速时钟。
时钟域
简单来说,时钟域就是一个或多个模块共用一个时钟。 SoC 里有高速设备如 CPU,Memory,Bus 等,也有低速设备,如各种外设设备,I2C,USB,UART... 所以需要多个时钟域。
时钟和时钟频率会极大影响功耗。特别是边缘端低功耗的芯片,需要的不同时钟域至少有:
主时钟域: 计算核心组和数据外设组位于主时钟域。该时钟域在运行时速度较快,一般来讲运行于 8M-100M 之间。
常开时钟域: 主要用于系统外设组。频率值是 32.768KHz。
一共需要外接两个晶振,一个是 24MHz 的 HSE, 另一个是 32.768KHz 的 LSE。所有时钟均有 CLKGEN 模块来管理。
Clock Generate Unit
![[clock-generate-unit-simple.jpg]]
时钟管理模块其实分为两部分的,用来产生高速时钟的 HCLKGEN 和用来产生低速时钟的 LCLKGEN。
CGU 主要就是多路选择器,用于选择对应的时钟。对于 LCLK 需要选择片内还是片外。对于 HCLK 需要选择 HSE, PLL 还是 HSI。同时要为了更灵活的时钟配置,需要配置两个分频器,得到对应的时钟频率。
时钟树 Clock Tree
一般 SoC 里的时钟,指的是全局时钟,全局时钟在芯片中的体现形式是时钟树。
理想情况下,同时钟域中的所有寄存器的时钟边沿同时同时到达。但是在实际的电路中,这是不可能实现的。连接到各个模块的时钟信号线有长有短,如何保证时钟信号的同步?
![[clock-tree-without-clock-buffer.jpg]]
因此就需要对时钟域中的时钟信号进行管理,时钟树可以保证时钟域中的寄存器的时钟边沿偏最小,从而保证良好的时序特性。
时钟树并不是用来缩短时钟信号到达各个寄存器的时间,而是保证这些寄存器之间的时间差最小,即确保时钟信号尽量同时到达。
注意时钟的驱动能力是有限的,如果一个时钟域里面有多个需要时钟信号驱动的模块,时钟信号的负载会超过驱动能力,这会造成信号质量的下降。这会造成功能的错误。
![[clock-tree-with-buffer.jpg]]
简单来说,时钟树作用来确保时钟信号的质量和时序(同步状态)。
其他
- 上电时一般来讲会先使用片内的 HSI,因为起振更快。最后再切换到 HSE,因为更稳定。
- 如果比较极致的做法是把 HCLKGEN 单独作为一个外设挂到主时钟域而不是像此处合成一个模块放在常开时钟域。
- IP 级的 power gating 一般会做在 IP 内部,例如 RISC-V 和 AI CORE 内部,而不是做在这个系统级的 CLKGEN 里面