注:本文翻译自Constraining Logically Exclusive Clocks in Synthesis
逻辑互斥时钟的定义
逻辑互斥时钟是指设计中活跃(activate)但不彼此影响的时钟。常见的情况是,两个时钟作为一个多路选择器的输入,并根据sel信号决定哪一个时钟被激活。一个处理逻辑互斥时钟的重要指导思想就是逻辑互斥时钟不应该在mux以外的地方发生交互。
如上图所示,设计中共有两个时钟,分别是CLKA和CLKB,两个时钟是多路选择的,某一时刻,只有一个时钟对电路起作用。一种约束的方法是使用set_case_analysis
约束,即假定SEL恒为0或者1,然后进行时序分析。否则,若不进行任何约束,则flop-1和flop-2的发起时钟和捕获时钟分别有两种可能,因而综合工具总共会分析四条路径,如下表所示:
flop-1发起时钟 | flop-2捕获时钟 |
---|---|
CLKA | CLKA |
CLKB | CLKA |
CLKA | CLKB |
CLKB | CLKB |
然而,事实上,表中中间的两种情况永远不可能发生。因此,为了杜绝这一问题,我们可以采用下面所示的约束方式:
set_clock_groups -logically_exclusive -group CLKA -group CLKB
通过上述约束,综合工具只会分析CLKA–>CLKA和CLKB–>CLKB这两条路径。
事实上,我们也可以通过设置伪路径来实现:
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
set_false_path -from [get_clocks CLKB] -to [get_clocks CLKA]
现在考虑另一种情况,如上图所示,CLKA直接驱动了flop-3,因此,如果我们仍然采用set_clock_groups -logically_exclusive -group CLKA -group CLKB
约束,那么综合工具只会分析CLKA–>CLKA和CLKB–>CLKB之间的路径,而事实上,flop-3和flop-2之间可能存在CLKA–>CLKB这种情况。
因此,为了解决上述问题,我们需要为CLKA和CLKB创建生成时钟,如下所示:
create_generated_clock -name -CLKA_GEN -source CLKA [get_pins clk_mux/out]
create_generated_clock -name -CLKB_GEN -source CLKB [get_pins clk_mux/out]
然后,我们设置生成时钟之间是逻辑互斥的:
set_clock_groups -logically_exclusive -group CLKA_GEN -group CLKB_GEN
经此约束后,原先遗漏的路径CLKA(flop-3)–>CLKB(flop-2)也会被综合工具分析了。
考虑上图所示的情况,由图可知,CLKA和CLKB被信号SEL1 MUX,CLKC和CLKD被信号SEL2 MUX,flop-1和flop-2以及flop-6被CLKA和CLKB MUX后的时钟驱动,而flop-4、flop-5以及flop-3被CLKC和CLKD MUX后的时钟驱动。
为了对上述设计进行约束,我们有:
set_clock_groups -logically_exclusive -group CLKA -group CLKB
set_clock_groups -logically_exclusive -group CLKC -group CLKD
我们也可以通过设置伪路径实现上述效果:
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
set_false_path -from [get_clocks CLKB] -to [get_clocks CLKA]
set_false_path -from [get_clocks CLKC] -to [get_clocks CLKD]
set_false_path -from [get_clocks CLKD] -to [get_clocks CLKC]
我们在上述例子的情况再作了一些改变,即两个MUX的SEL信号是相同的,此时CLKA和CLKB以及CLKD不能交互,CLKC也不能和CLKD以及CLKB交互,因此,我们可以做如下约束:
set_clock_groups -logically_exclusive -group “CLKA CLKC” -group “CLKB CLKD”
上述约束中,同一组内的时钟可以交互,而不同组间的时钟不能交互,其效果正是我们想达到的。