当前位置:   article > 正文

【FPGA/verilog -入门学习1】verlog中的BUFGCE,BUFGMUX原语

bufgce

参考:(详解)BUFG,IBUFG,BUFGP,IBUFGDS等含义以及使用 - 知乎

FPGA资源介绍——时钟资源(二)_fpga时钟资源-CSDN博客

1,BUFGCE

带有时钟使能端的全局缓冲。它有一个输入I、一个使能端CE和一个输出端O。只有当BUFGCE的使能端CE有效(高电平)时,BUFGCE才有输出。

作用:防止竞争冒险现象

使用方法

vlg_design

  1. /
  2. //FPGA系统时钟100MHz
  3. //系统每秒进行一次数据的采集与处理,每次维持10ms,其余时间空闲
  4. //希望系统空闲时,关闭100MHz的工作时钟
  5. //使用BUFGCE原语实现此功能
  6. /
  7. `timescale 1ns/1ps
  8. module vlg_design(
  9. input clk,//100M
  10. input rest_n,
  11. output reg clk_10ms_en,
  12. output reg o_clk_out_1, //自己产生是能
  13. output o_clk_out_2 // 使用原语
  14. );
  15. `define Debug
  16. `ifdef Debug
  17. localparam CNT_1S_MAX = 1_000_000 -1 ; //10ms
  18. localparam CNT_10MS_MAX = 1_000 -1; //10us
  19. `else
  20. localparam CNT_1S_MAX = 100_000_000 -1 ;//1s
  21. localparam CNT_10MS_MAX = 1_000_000 -1 ; //10ms
  22. `endif
  23. reg [27:0]r_cnt_10ms;
  24. wire r_clk_out_1;
  25. wire r_clk_out_2;
  26. //产生1s的计数
  27. always @(posedge clk) begin
  28. if(!rest_n) r_cnt_10ms <='b0;
  29. else if (r_cnt_10ms < CNT_1S_MAX)
  30. r_cnt_10ms <= r_cnt_10ms + 1'b1;
  31. else r_cnt_10ms <='b0;
  32. end
  33. //10ms以下是能
  34. always @(posedge clk) begin
  35. if(!rest_n) clk_10ms_en <='b0;
  36. else if(r_cnt_10ms <= CNT_10MS_MAX) clk_10ms_en <=1'b1;
  37. else clk_10ms_en <='b0;
  38. end
  39. //10ms以下clk_out_1 按clk 输出
  40. always @(*) begin
  41. if(!rest_n) o_clk_out_1 <='b0;
  42. else if(clk_10ms_en)
  43. o_clk_out_1 <= clk ;
  44. else o_clk_out_1 <= 'b0;
  45. end
  46. //使用原语例化代码
  47. BUFGCE BUFGCE_inst (
  48. .O(r_clk_out_2), // 1-bit output: Clock output
  49. .CE(clk_10ms_en), // 1-bit input: Clock enable input for I0
  50. .I(clk) // 1-bit input: Primary clock
  51. );
  52. assign o_clk_out_2 = r_clk_out_2;
  53. endmodule

testbench_top

  1. `timescale 1ns/1ps
  2. module testbench_top();
  3. //参数定义
  4. `define CLK_PERIORD 10 //时钟周期设置为10ns(100MHz)
  5. //接口申明
  6. reg clk;
  7. reg rest_n;
  8. wire clk_10ms_en;
  9. wire o_clk_out_1;
  10. wire o_clk_out_2;
  11. vlg_design uut_vlg_design(
  12. .clk(clk),
  13. .rest_n(rest_n),
  14. .clk_10ms_en(clk_10ms_en),
  15. .o_clk_out_1(o_clk_out_1),
  16. .o_clk_out_2(o_clk_out_2)
  17. );
  18. //时钟和复位初始化、复位产生
  19. initial begin
  20. clk <= 0;
  21. rest_n <= 0;
  22. #10;
  23. rest_n <= 1;
  24. end
  25. //时钟产生
  26. always #(`CLK_PERIORD/2) clk = ~clk;
  27. //测试激励产生
  28. initial begin
  29. @(posedge rest_n); //等待复位完成
  30. @(posedge clk);
  31. #1_000_000_000;
  32. #1_000_000_000;
  33. $stop;
  34. end
  35. endmodule

仿真结果输出

对比发现:使用自己产生的是能造成了竞争冒险

2,BUFGMUX

BUFGMUX

全局时钟选择缓冲,它有I0和I1两个输入,一个控制端S,一个输出端O。当S为低电平时输出时钟为I0,反之为I1。需要指出的是BUFGMUX的应用十分灵活,I0和I1两个输入时钟甚至可以为异步关系。

作用:

BUFGMUX的主要作用包括:

  1. 数据缓冲:BUFGMUX可以管理输入和输出缓冲区,用于存储待传输的数据。它提供了读写操作,以便在缓冲区中存储和检索数据。
  2. 间隙管理:在高速数据传输中,数据传输速率可能不匹配,导致接收方无法立即处理所有接收到的数据。BUFGMUX可以管理这些间隙,通过插入空闲周期或等待周期来匹配发送和接收之间的速率。
  3. 流量控制:BUFGMUX可以与上层协议(如PCIe、Ethernet等)进行通信,以实现流量控制。它可以根据接收方的处理能力来调整发送速率,以避免接收方过载。

此外,BUFGMUX还可以用于构建文件存储和分发服务,实现文件共享功能,并作为应用开发的基础组件,帮助开发者快速构建文件存储功能等。

使用方法

vlg_design

  1. /
  2. /*FPGA系统时钟100MHz
  3. FPGA系统快速时钟100MHz,慢速时钟1MHz
  4. 系统每秒进行一次数据的采集与处理,每次维持10ms,其余时间空闲
  5. 数据采集与处理时,FPGA工作在100MHz快时钟(10ms/s)
  6. 系统空闲时, FPGA工作在1MHz慢时钟(990ms/s)
  7. 使用Xilinx BUFGMUX原语实现此功能
  8. 编写Verilog代码
  9. 编写测试脚本,搭建仿真平台
  10. 运行仿真,查看波形
  11. */
  12. /
  13. `timescale 1ns/1ps
  14. module vlg_design(
  15. input clk_in1,//100M
  16. input clk_in2,//1M
  17. input rest_n,
  18. output reg clk_10ms_en,
  19. output reg o_clk_out_1, //自己产生是能
  20. output o_clk_out_2 // 使用原语
  21. );
  22. `define Debug
  23. `ifdef Debug
  24. localparam CNT_1S_MAX = 1_000_000 -1 ; //10ms
  25. localparam CNT_10MS_MAX = 1_000 -1; //10us
  26. `else
  27. localparam CNT_1S_MAX = 100_000_000 -1 ;//1s
  28. localparam CNT_10MS_MAX = 1_000_000 -1 ; //10ms
  29. `endif
  30. reg [27:0]r_cnt_10ms;
  31. wire r_clk_out_1;
  32. wire r_clk_out_2;
  33. //产生1s的计数
  34. always @(posedge clk_in1) begin
  35. if(!rest_n) r_cnt_10ms <='b0;
  36. else if (r_cnt_10ms < CNT_1S_MAX)
  37. r_cnt_10ms <= r_cnt_10ms + 1'b1;
  38. else r_cnt_10ms <='b0;
  39. end
  40. //10ms以下是能
  41. always @(posedge clk_in1) begin
  42. if(!rest_n) clk_10ms_en <='b0;
  43. else if(r_cnt_10ms <= CNT_10MS_MAX) clk_10ms_en <=1'b1;
  44. else clk_10ms_en <='b0;
  45. end
  46. //10ms以下clk_out_1 按clk 输出
  47. always @(*) begin
  48. if(!rest_n) o_clk_out_1 <='b0;
  49. else if(clk_10ms_en)
  50. o_clk_out_1 <= clk_in1 ;
  51. else o_clk_out_1 <= clk_in2;
  52. end
  53. //使用原语例化代码
  54. BUFGMUX BUFGMUX_inst (
  55. .O(o_clk_out_2), // 1-bit output: Clock output
  56. .I0(clk_in2), // 1-bit input: Clock input (S=0) 低脉冲
  57. .I1(clk_in1), // 1-bit input: Clock input (S=1) 高脉冲
  58. .S(clk_10ms_en) // 1-bit input: Clock select
  59. );
  60. endmodule

testbench_top

  1. `timescale 1ns/1ps
  2. module testbench_top();
  3. //参数定义
  4. `define CLK_PERIORD 10 //时钟周期设置为10ns(100MHz)
  5. //接口申明
  6. reg clk_in1;
  7. reg clk_in2;
  8. reg rest_n;
  9. wire clk_10ms_en;
  10. wire o_clk_out_1;
  11. wire o_clk_out_2;
  12. vlg_design uut_vlg_design(
  13. .clk_in1(clk_in1),
  14. .clk_in2(clk_in2),
  15. .rest_n(rest_n),
  16. .clk_10ms_en(clk_10ms_en),
  17. .o_clk_out_1(o_clk_out_1),
  18. .o_clk_out_2(o_clk_out_2)
  19. );
  20. //时钟和复位初始化、复位产生
  21. initial begin
  22. clk_in1 <= 0;
  23. clk_in2 <= 0;
  24. rest_n <= 0;
  25. #10;
  26. rest_n <= 1;
  27. clk_in1 <= 1;
  28. clk_in2 <= 1;
  29. end
  30. //时钟产生
  31. always #(`CLK_PERIORD/2) clk_in1 = ~clk_in1;
  32. always #(`CLK_PERIORD*100/2) clk_in2 = ~clk_in2;
  33. //测试激励产生
  34. initial begin
  35. @(posedge rest_n); //等待复位完成
  36. @(posedge clk_in1);
  37. #1_000_000_000;
  38. #1_000_000_000;
  39. $stop;
  40. end
  41. endmodule

仿真结果输出

问题

使用原语例化的时候,

en=1,out 没有立刻等于in1.而是多等了半个in2 时钟

en =0时,out也没有立刻等于in2,而是多等了半个in1时钟

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/519206
推荐阅读
相关标签
  

闽ICP备14008679号