在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 40780|回复: 7

[原创] 关于altera fpga 时钟切换(clk mux) 的讨论

[复制链接]
发表于 2013-3-28 22:06:49 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 caicaixuehua 于 2013-3-30 13:21 编辑

首先我用fpga是 altera cyclone II:  里面有个时钟mux: 一个时钟来自 pll , 一个时钟来自tck (jtag)

// 需要不同时钟的debug_ram。
debug_ram
debug_ram_inst (.address (clk_sw ? jtag_addr : rom_addr),
                                .clken   (jtag_wr|~rom_rd_n            ),

                        .clock   (debug_ram_clk                ),

                        .data    (jtag_data                    ),

                        .wren    (jtag_wr                      ),

                        .q       (rom_data                     )

                                                               );


(1)如果直接用rtl作逻辑选择:assign debug_ram_clk = clk_sw ? tck : clk;  //使用此逻辑综合要报rom_addr hold violation 时序warning(估计是因为做时钟切换clk时钟延时太长,看时序报告rom_addr hold需要2点几纳钞)
  (2) 如果使用quartus ii 里的 ip, altclkctrl :clk_ctrl
u_clk_ctrl(.clkselect( clk_sw            ),

                                                                              .inclk0x  ( clk                  ),

                                                                              .inclk1x  ( tck                 ),

                                                                              .outclk   ( debug_ram_clk)

                                                                                                                  );
        会报如此错:Error: inclk[0] port of Clock Control Block "clk_ctrl:u_clk_ctrl|clk_ctrl_altclkctrl_8af:clk_ctrl_altclkctrl_8af_component|clkctrl1" is driven by PLLLL_inst|altpll:altpll_component|_clk0, but must be driven by a clock pin
                         Error: inclk[1] port of Clock Control Block "clk_ctrl:u_clk_ctrl|clk_ctrl_altclkctrl_8af:clk_ctrl_altclkctrl_8af_component|clkctrl1" is driven by altera_internal_jtag~TCKUTAP, but must be driven by a clock pin
         //不知道为什么会报错,还在查资料中,也请大神赐教。。。。

(3)使用时钟mux代码如下:
module clk_mux#(parameter num_clk = 2      )
               (input  [num_clk-1:0] clk    ,

//input  [num_clk-1:0] clk_rst,

input  [num_clk-1:0] clk_sel,

output clk_o

                                   );
genvar i;
reg  [num_clk-1:0] ena_r0;
reg  [num_clk-1:0] ena_r1;
reg  [num_clk-1:0] ena_r2;
wire [num_clk-1:0] qualified_sel;

// A look-up-table (LUT) can glitch when multiple inputs
// change simultaneously. Use the keep attribute to
// insert a hard logic cell buffer and prevent
// the unrelated clocks from appearing on the same LUT.
wire [num_clk-1:0] gated_clks /* synthesis keep */;
wire [num_clk-1:0] tmp_mask[0:num_clk-1];

generate
  for (i=0; i<num_clk; i=i+1)
  begin : lp0
    assign tmp_mask = {num_clk{1'b1}} ^ (1 << i);
    assign qualified_sel = clk_sel & (~|(ena_r2 & tmp_mask));
    always @(posedge clk) begin
    ena_r0 <= qualified_sel;
    ena_r1 <= ena_r0;
  end
  always @(negedge clk) begin
  ena_r2 <= ena_r1;
  end
  assign gated_clks = clk & ena_r2;
end
endgenerate
// These will not exhibit simultaneous toggle by construction
assign clk_o = |gated_clks;
endmodule
电路如下:
test2.jpg

再实例化:clk_mux u_clk_mux({tclk,clk},{clk_sw,~clk_sw},debug_ram_clk); // 则这样就不会报错

(4)还有一种方法是动态配置pll(有些altera fpga支持),可是有一个时钟不是来自pll,故不能使用此方法了

前三种方法,暂时只有(3)不报错





Clock Control Block (ALTCLKCTRL) Megafunction资料上有如此表格:

test.jpg


下有如此一段话:The global clock network allows a clock signal (or other global signals) to reach all parts of the chip with a similar amount of skew. The regional clock network allows a signal to reach one quadrant of the chip (though half of the chip can be reached by driving two quadrants). The external clock-out path represents the clock path from the outputs of the phase-locked loop (PLL) to the dedicated PLL_OUT pins. The ALTCLKCTRL megafunction also provides glitch-free implementation for multiple clock input signals.

好像:cyclone II 只支持(1)global clock network ,(2) Dedicated External Clock Out Path , 但是选择(2)又无法支持时钟的mux,如下图:
test2.jpg

完全无语呀,限制真心多


纠正:其实(3)也会报rom_addr相对clk的hold violation的WARNING(原因是之类代码有点问题)


欢迎大家多多讨论,不知道大家一般在fpga中怎么做clk的mux呢。。。
发表于 2013-3-28 22:31:31 | 显示全部楼层
第一种方法没有问题,也是Synopsys推荐的方法。关键是,你在时序约束里有没把这两个时钟设为不同的clock group?

如果需要动态切换则需要进一步约束,你这里应该用不着。
 楼主| 发表于 2013-3-28 22:42:34 | 显示全部楼层
回复 2# Timme 设了的,我是在altera quartus 中综合,没有使用dc综合,dc综合要求没那么多(asic想怎么走线,就怎么走啥,而fpga布线资源是固定的),不过dc也还是要注意切换时的glitch啥(对了,synosys 的dc会自动考虑切换时的glitch而加保护电路吗,如果使用三目运算符)。
 楼主| 发表于 2013-3-28 22:48:25 | 显示全部楼层
回复 2# Timme
你给我推荐的是时钟gating的文档吧,好像不是时钟切换吧
发表于 2013-3-28 22:52:07 | 显示全部楼层
本帖最后由 Timme 于 2013-3-28 22:54 编辑




你看看第五个例子。

作为一个最简单的尝试,你试试在Fitter设置里把自动全局时钟关了,看看还有没有hold time的大违规。
 楼主| 发表于 2013-3-29 20:38:23 | 显示全部楼层
回复 5# Timme
example 5: 是假设TSTCLK 在切换过程中,它是关了的,并且假设clk1和clk2是同一个时钟,故才可以 no glitch switch。(原文:Assume that the test clock is not a free-running clock, and that it is quiet when you switch to/from it.)



时钟无glitch的切换就只需要保证,一个时钟关了之后,另外一个时钟再打开(当然它们的开关一定不能出现glitch):                                        (1)当然它们可以直接或起来(clk_out = clk1|clk2)
                                         (2) 或者在第一个时钟关了之后,切换成第二个时钟(改变clk_sw的值),然后再打开第二个时钟(clk_out =                                    
                                                                                                                                                        clk_sw ? clk1 : clk2)


其实我认为只要不需要切换完成后保证马上可以用,也不用考虑那么多,直接切换完成时钟后,复位不就行了。


其中(3)的时钟mux 代码就是保证在一个时钟完全无glitch的关好后(输出clk_out的或门一个输入),另一个时钟才会打开(输出clk_out的或门另一个输入)


另外我想问的是为什么要把自动全局时钟关掉?
 楼主| 发表于 2013-3-30 13:26:50 | 显示全部楼层
经改了clk_mux代码后, 法(1)和法(3)相比,法(1)时序会更好一些,由于我不关心有没有latch(因为我时钟切换完成再复位),但是时序一直有hold violation
发表于 2018-12-24 16:50:35 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-5 12:51 , Processed in 0.026494 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表