赞
踩
参考:(详解)BUFG,IBUFG,BUFGP,IBUFGDS等含义以及使用 - 知乎
FPGA资源介绍——时钟资源(二)_fpga时钟资源-CSDN博客
是带有时钟使能端的全局缓冲。它有一个输入I、一个使能端CE和一个输出端O。只有当BUFGCE的使能端CE有效(高电平)时,BUFGCE才有输出。
- /
- //FPGA系统时钟100MHz
- //系统每秒进行一次数据的采集与处理,每次维持10ms,其余时间空闲
- //希望系统空闲时,关闭100MHz的工作时钟
- //使用BUFGCE原语实现此功能
-
- /
- `timescale 1ns/1ps
- module vlg_design(
- input clk,//100M
- input rest_n,
- output reg clk_10ms_en,
- output reg o_clk_out_1, //自己产生是能
- output o_clk_out_2 // 使用原语
- );
-
- `define Debug
- `ifdef Debug
- localparam CNT_1S_MAX = 1_000_000 -1 ; //10ms
- localparam CNT_10MS_MAX = 1_000 -1; //10us
- `else
- localparam CNT_1S_MAX = 100_000_000 -1 ;//1s
- localparam CNT_10MS_MAX = 1_000_000 -1 ; //10ms
- `endif
-
- reg [27:0]r_cnt_10ms;
- wire r_clk_out_1;
- wire r_clk_out_2;
-
- //产生1s的计数
- always @(posedge clk) begin
- if(!rest_n) r_cnt_10ms <='b0;
- else if (r_cnt_10ms < CNT_1S_MAX)
- r_cnt_10ms <= r_cnt_10ms + 1'b1;
- else r_cnt_10ms <='b0;
- end
-
- //10ms以下是能
- always @(posedge clk) begin
- if(!rest_n) clk_10ms_en <='b0;
- else if(r_cnt_10ms <= CNT_10MS_MAX) clk_10ms_en <=1'b1;
- else clk_10ms_en <='b0;
- end
-
- //10ms以下clk_out_1 按clk 输出
- always @(*) begin
- if(!rest_n) o_clk_out_1 <='b0;
- else if(clk_10ms_en)
- o_clk_out_1 <= clk ;
- else o_clk_out_1 <= 'b0;
- end
-
-
- //使用原语例化代码
- BUFGCE BUFGCE_inst (
- .O(r_clk_out_2), // 1-bit output: Clock output
- .CE(clk_10ms_en), // 1-bit input: Clock enable input for I0
- .I(clk) // 1-bit input: Primary clock
- );
-
- assign o_clk_out_2 = r_clk_out_2;
-
-
- endmodule
-
-
- `timescale 1ns/1ps
- module testbench_top();
-
-
- //参数定义
-
- `define CLK_PERIORD 10 //时钟周期设置为10ns(100MHz)
-
-
- //接口申明
-
-
- reg clk;
- reg rest_n;
- wire clk_10ms_en;
- wire o_clk_out_1;
- wire o_clk_out_2;
-
-
-
- vlg_design uut_vlg_design(
- .clk(clk),
- .rest_n(rest_n),
- .clk_10ms_en(clk_10ms_en),
- .o_clk_out_1(o_clk_out_1),
- .o_clk_out_2(o_clk_out_2)
- );
-
- //时钟和复位初始化、复位产生
- initial begin
- clk <= 0;
- rest_n <= 0;
- #10;
- rest_n <= 1;
- end
-
- //时钟产生
- always #(`CLK_PERIORD/2) clk = ~clk;
-
-
- //测试激励产生
- initial begin
-
- @(posedge rest_n); //等待复位完成
- @(posedge clk);
- #1_000_000_000;
- #1_000_000_000;
- $stop;
- end
-
- endmodule
-
-
-
-
-
-
-
对比发现:使用自己产生的是能造成了竞争冒险
BUFGMUX
是全局时钟选择缓冲,它有I0和I1两个输入,一个控制端S,一个输出端O。当S为低电平时输出时钟为I0,反之为I1。需要指出的是BUFGMUX的应用十分灵活,I0和I1两个输入时钟甚至可以为异步关系。
BUFGMUX的主要作用包括:
此外,BUFGMUX还可以用于构建文件存储和分发服务,实现文件共享功能,并作为应用开发的基础组件,帮助开发者快速构建文件存储功能等。
- /
- /*FPGA系统时钟100MHz
- FPGA系统快速时钟100MHz,慢速时钟1MHz
- 系统每秒进行一次数据的采集与处理,每次维持10ms,其余时间空闲
- 数据采集与处理时,FPGA工作在100MHz快时钟(10ms/s)
- 系统空闲时, FPGA工作在1MHz慢时钟(990ms/s)
- 使用Xilinx BUFGMUX原语实现此功能
- 编写Verilog代码
- 编写测试脚本,搭建仿真平台
- 运行仿真,查看波形
-
- */
- /
- `timescale 1ns/1ps
- module vlg_design(
- input clk_in1,//100M
- input clk_in2,//1M
- input rest_n,
- output reg clk_10ms_en,
- output reg o_clk_out_1, //自己产生是能
- output o_clk_out_2 // 使用原语
- );
-
- `define Debug
- `ifdef Debug
- localparam CNT_1S_MAX = 1_000_000 -1 ; //10ms
- localparam CNT_10MS_MAX = 1_000 -1; //10us
- `else
- localparam CNT_1S_MAX = 100_000_000 -1 ;//1s
- localparam CNT_10MS_MAX = 1_000_000 -1 ; //10ms
- `endif
-
- reg [27:0]r_cnt_10ms;
- wire r_clk_out_1;
- wire r_clk_out_2;
-
- //产生1s的计数
- always @(posedge clk_in1) begin
- if(!rest_n) r_cnt_10ms <='b0;
- else if (r_cnt_10ms < CNT_1S_MAX)
- r_cnt_10ms <= r_cnt_10ms + 1'b1;
- else r_cnt_10ms <='b0;
- end
-
- //10ms以下是能
- always @(posedge clk_in1) begin
- if(!rest_n) clk_10ms_en <='b0;
- else if(r_cnt_10ms <= CNT_10MS_MAX) clk_10ms_en <=1'b1;
- else clk_10ms_en <='b0;
- end
-
- //10ms以下clk_out_1 按clk 输出
- always @(*) begin
- if(!rest_n) o_clk_out_1 <='b0;
- else if(clk_10ms_en)
- o_clk_out_1 <= clk_in1 ;
- else o_clk_out_1 <= clk_in2;
- end
-
-
-
- //使用原语例化代码
- BUFGMUX BUFGMUX_inst (
- .O(o_clk_out_2), // 1-bit output: Clock output
- .I0(clk_in2), // 1-bit input: Clock input (S=0) 低脉冲
- .I1(clk_in1), // 1-bit input: Clock input (S=1) 高脉冲
- .S(clk_10ms_en) // 1-bit input: Clock select
- );
-
- endmodule
-
- `timescale 1ns/1ps
- module testbench_top();
-
-
- //参数定义
-
- `define CLK_PERIORD 10 //时钟周期设置为10ns(100MHz)
-
-
- //接口申明
-
- reg clk_in1;
- reg clk_in2;
- reg rest_n;
- wire clk_10ms_en;
- wire o_clk_out_1;
- wire o_clk_out_2;
-
-
-
- vlg_design uut_vlg_design(
- .clk_in1(clk_in1),
- .clk_in2(clk_in2),
- .rest_n(rest_n),
- .clk_10ms_en(clk_10ms_en),
- .o_clk_out_1(o_clk_out_1),
- .o_clk_out_2(o_clk_out_2)
- );
-
- //时钟和复位初始化、复位产生
- initial begin
- clk_in1 <= 0;
- clk_in2 <= 0;
- rest_n <= 0;
- #10;
- rest_n <= 1;
- clk_in1 <= 1;
- clk_in2 <= 1;
- end
-
- //时钟产生
- always #(`CLK_PERIORD/2) clk_in1 = ~clk_in1;
- always #(`CLK_PERIORD*100/2) clk_in2 = ~clk_in2;
-
-
- //测试激励产生
- initial begin
-
- @(posedge rest_n); //等待复位完成
- @(posedge clk_in1);
- #1_000_000_000;
- #1_000_000_000;
- $stop;
- end
-
- endmodule
使用原语例化的时候,
en=1,out 没有立刻等于in1.而是多等了半个in2 时钟
en =0时,out也没有立刻等于in2,而是多等了半个in1时钟
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。