参考:(详解)BUFG,IBUFG,BUFGP,IBUFGDS等含义以及使用 - 知乎
FPGA资源介绍——时钟资源(二)_fpga时钟资源-CSDN博客
1,BUFGCE
是带有时钟使能端的全局缓冲。它有一个输入I、一个使能端CE和一个输出端O。只有当BUFGCE的使能端CE有效(高电平)时,BUFGCE才有输出。
作用:防止竞争冒险现象
使用方法
vlg_design
/
//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
testbench_top
`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
仿真结果输出
对比发现:使用自己产生的是能造成了竞争冒险
2,BUFGMUX
BUFGMUX
是全局时钟选择缓冲,它有I0和I1两个输入,一个控制端S,一个输出端O。当S为低电平时输出时钟为I0,反之为I1。需要指出的是BUFGMUX的应用十分灵活,I0和I1两个输入时钟甚至可以为异步关系。
作用:
BUFGMUX的主要作用包括:
- 数据缓冲:BUFGMUX可以管理输入和输出缓冲区,用于存储待传输的数据。它提供了读写操作,以便在缓冲区中存储和检索数据。
- 间隙管理:在高速数据传输中,数据传输速率可能不匹配,导致接收方无法立即处理所有接收到的数据。BUFGMUX可以管理这些间隙,通过插入空闲周期或等待周期来匹配发送和接收之间的速率。
- 流量控制:BUFGMUX可以与上层协议(如PCIe、Ethernet等)进行通信,以实现流量控制。它可以根据接收方的处理能力来调整发送速率,以避免接收方过载。
此外,BUFGMUX还可以用于构建文件存储和分发服务,实现文件共享功能,并作为应用开发的基础组件,帮助开发者快速构建文件存储功能等。
使用方法
vlg_design
/
/*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
testbench_top
`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 时钟
文章来源:https://www.toymoban.com/news/detail-833705.html
en =0时,out也没有立刻等于in2,而是多等了半个in1时钟文章来源地址https://www.toymoban.com/news/detail-833705.html
到了这里,关于【FPGA/verilog -入门学习1】verlog中的BUFGCE,BUFGMUX原语的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!