1 BUFGCE 简介
1.1 Xilinx 文档原文
与 BUFG 不同,BUFGCE 由一个时钟输入、一个时钟输出、一个时钟使能信号构成。这个原语基于 BUFGCTRL 并以一些引脚连接逻辑高电位和低电位。图 2-7 表明了 BUFGCE 和 BUFGCTRL 的关联。LOC 约束可用于手动布置 BUFGCE 和 BUFGCE_1 的位置。
使能信号线路使用了 BUFGCTRL 的 CE 引脚,使能信号必须满足预设时间的要求。违反此预设时间会产生毛刺。
1.2 BUFGCE 的作用
BUFGCE 是带有时钟使能信号的全局缓冲。它有一个输入时钟 I 、一个时钟使能信号端 CE 和一个输出时钟 O 。只有当 BUFGCE 的 CE 端有效 ( 高电平 ) 时,BUFGCE 才有输出。
1.3 BUFGCE 的延迟
从图 2-8 可以看出,在 CE 为高时,O 端的输出信号会跟随 I 端的输入信号变化。
当 CE 为高。I 端信号上升沿结束到达高电平的时刻,O 端信号的上升沿开始,经过相同的上升沿时间后到达高电平。同样,在 I 端信号下降沿结束到低电平的时刻,O 端信号的下降沿开始,经过相同的下降沿时间后到达低电平。也就是说,O 端信号跟随 I 端信号变化总会落后一个时钟沿的时间。
2 BUFG 设计实例
2.1 实例功能需求
(1)系统时钟 100MHz ;
(2)系统每秒进行一次数据的采集和处理,每次维持 10 ms ,其余时间空闲;
(3)希望系统空闲时,关闭 100MHz 的工作时钟。
2.2 Verilog 代码
`timescale 1ns / 1ps
// 输入时钟频率 100MHz ,时钟周期 10ns 。
// 1s 内有 100_000_000 个输入时钟,计数器设置为 20 位不够,因此设置为 30 位(一般都是整数位)。
// 10ms 内有 1_000_000 个输入时钟,计数器设置为 20 位。
module top(
input clk ,
input rst_n ,
output reg en_10ms ,
output clk_out // 输出波形
);
// 设置 1s 和 10ms 的计数器
reg [19:0] cnt_10ms ; // 1s 计数器
reg [29:0] cnt_1s ; // 10ms 计数器
localparam CNT_PERIOD_10ms = 1_000_000 ; // cnt_10ms 的最大值
localparam CNT_PERIOD_1s = 100_000_000 ; // cnt_1s 的最大值
// cnt_10ms 的初始化和赋值
// cnt_10ms 从 0 到 999_999 。到达 999_999 后,在下个时钟复位
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt_10ms = 20'd0;
else begin
if(cnt_10ms < CNT_PERIOD_10ms -1)
cnt_10ms = cnt_10ms + 1'b1;
else
cnt_10ms = 20'd0;
end
end
// cnt_1s 的初始化和赋值
// cnt_1s 从 0 到 99_999_999 。到达 99_999_999 后,在下个时钟复位
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt_1s = 30'd0;
else begin
if(cnt_1s < CNT_PERIOD_1s -1)
cnt_1s = cnt_1s + 1'b1;
else
cnt_1s = 30'd0;
end
end
// 设置使能信号
// 因为只在 10ms 内产生输出波形。所以在 1s 内,使能信号在 10ms 内为高电平有效,剩下的时间均为低电平。
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
en_10ms = 1'b0;
else begin
if(cnt_1s < CNT_PERIOD_10ms)
en_10ms = 1'b1;
else
en_10ms = 1'b0;
end
end
BUFGCE BUFGCE_inst (
. O( clk_out), // 1-bit output: Clock output 输出信号
.CE( en_10ms), // 1-bit input: Clock enable input for I0 输入使能信号
. I( clk) // 1-bit input: Primary clock 输入信号时钟
);
endmodule
2.3 TestBench 代码
`timescale 1ns / 1ps
module tb_top;
reg clk ;
reg rst_n ;
wire en_10ms ;
wire clk_out ;
localparam CLK_PERIOD = 10;
top top_1( .clk(clk), .rst_n(rst_n), .en_10ms(en_10ms), .clk_out(clk_out) );
initial begin
clk = 0;
rst_n = 1;
#1;
rst_n = 0;
#(CLK_PERIOD*3);
rst_n = 1;
end
always #(CLK_PERIOD/2) clk = ~clk;
initial begin
@(posedge clk);
@(posedge rst_n);
repeat(100_000_000*3) begin
@(posedge clk);
end
end
endmodule
3 出现的问题
仿真时出现错误,在修改了顶层模块的例化名后仍无法解决。
目前无法仿真。