仅对英特尔可见 — GUID: mwh1409959605598
Ixiasoft
1.6.2. 时钟多路复用(Clock Multiplexing)
请使用专用硬件来执行时钟多路复用(如果可用),而不要使用多路复用逻辑。例如,您可以使用某些英特尔FPGA器件中的Clock Switchover功能或者Clock Control Block。这些专用的硬件模块可避免故障,确保使用全局低偏斜布线,并避免由于时钟线上的逻辑延迟而导致器件上的保持时间问题。英特尔FPGA器件也支持动态PLL重配置,这是在器件操作期间更改时钟速率的最安全,最可靠的方法。
如果您的设计中有太多时钟使用时钟控制模块,或者动态重配置对于设计而言过于复杂,那么可以在逻辑单元中实现时钟多路复用器。但是,如果您使用此实现,那么请考虑同时切换输入并确保无干扰跳变。
每个器件数据手册均描述了LUT输出如何在同时切换输入信号的过程中产生毛刺,与LUT功能无关。即使在同时进行数据输入切换期间4:1 MUX功能不会产生可检测到的毛刺,但是多路复用逻辑的某些单元实现也表现出明显的毛刺,因此不建议使用这种时钟多路复用器结构。这种实现方式的另一个问题是,在clk_select信号发生变化时,输出的行为会异常。此行为可能会在系统时钟馈送的所有寄存器上造成时序冲突,并可能导致亚稳态。
更复杂的时钟选择结构可以消除同时发生的翻转和切换问题。
您可以对任意数量的时钟通道采用此结构。此设计确保在所有其他时钟都至少保持无效数个周期后才激活一个时钟,并且确保时钟为低电平时进行激活。此设计对右侧的AND gate应用synthesis_keep指令,以确保clk_out OR gate的输入上没有同时翻转。
用于避免毛刺的Verilog HDL时钟多路复用设计
此示例适用于Verilog-2001。
module clock_mux (clk,clk_select,clk_out); parameter num_clocks = 4; input [num_clocks-1:0] clk; input [num_clocks-1:0] clk_select; // one hot output clk_out; genvar i; reg [num_clocks-1:0] ena_r0; reg [num_clocks-1:0] ena_r1; reg [num_clocks-1:0] ena_r2; wire [num_clocks-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_clocks-1:0] gated_clks /* synthesis keep */; initial begin ena_r0 = 0; ena_r1 = 0; ena_r2 = 0; end generate for (i=0; i<num_clocks; i=i+1) begin : lp0 wire [num_clocks-1:0] tmp_mask; assign tmp_mask = {num_clocks{1'b1}} ^ (1 << i); assign qualified_sel[i] = clk_select[i] & (~|(ena_r2 & tmp_mask)); always @(posedge clk[i]) begin ena_r0[i] <= qualified_sel[i]; ena_r1[i] <= ena_r0[i]; end always @(negedge clk[i]) begin ena_r2[i] <= ena_r1[i]; end assign gated_clks[i] = clk[i] & ena_r2[i]; end endgenerate // These will not exhibit simultaneous toggle by construction assign clk_out = |gated_clks; endmodule