当前位置:   article > 正文

Verilog:【1】时钟分频电路(clk_divider.sv)_verilog计数器实现时钟分频的原理

verilog计数器实现时钟分频的原理

碎碎念:

作为Basic Verilog的第一个学习笔记,打算用这种命名方式来对博客进行命名,应该有助于检索。

简单阅览了部分工程的代码,发现里面有很多嵌套关系,因此决定先从基础模块开始,也是为了整个博客内容的流畅性。

读者朋友有问题的话,也可以随时和我进行讨论!咋们一起学习,一起进步!

目录

1 模块功能

2 模块代码

3 模块思路

4 TestBench与仿真结果


1 模块功能

通过计数器来将时钟进行分频处理的功能,通过修改parameter部分,可以用来修改输出数据的范围大小。

2 模块代码

  1. //------------------------------------------------------------------------------
  2. // clk_divider.sv
  3. // published as part of https://github.com/pConst/basic_verilog
  4. // Konstantin Pavlov, pavlovconst@gmail.com
  5. //------------------------------------------------------------------------------
  6. // INFO ------------------------------------------------------------------------
  7. // Divides main clock to get derivative slower synchronous clocks
  8. //
  9. /* --- INSTANTIATION TEMPLATE BEGIN ---
  10. clk_divider #(
  11. .WIDTH( 32 )
  12. ) CD1 (
  13. .clk( clk ),
  14. .nrst( 1'b1 ),
  15. .ena( 1'b1 ),
  16. .out( )
  17. );
  18. --- INSTANTIATION TEMPLATE END ---*/
  19. module clk_divider #( parameter
  20. WIDTH = 32
  21. )(
  22. input clk,
  23. input nrst,
  24. input ena,
  25. output logic [(WIDTH-1):0] out = '0
  26. );
  27. always_ff @(posedge clk) begin
  28. if ( ~nrst ) begin
  29. out[(WIDTH-1):0] <= '0;
  30. end else if (ena) begin
  31. out[(WIDTH-1):0] <= out[(WIDTH-1):0] + 1'b1;
  32. end
  33. end
  34. endmodule

3 模块思路

这个模块比较简单,当nrst=0的时候,复位;非复位的情况下,会利用计数器原理,对out进行加一处理,下面重点介绍一下其中两个值得注意的地方。

1.always_ff

相比Verillog中千篇一律的always模块,这是System中的升级写法(之后可以专门写一个专题机进行横向总结)。

always_ff中,ff是flip_flop的缩写,表示它是边沿触发的触发器,需要加关键字posedge或negedge,本例中表示他是clk信号上升沿来触发。

2.logic

参考博客:SystemVerilog logic、wire、reg数据类型详解 - 民工袁师傅的文章 - 知乎

logic类型是System Verilog中升级的部分,Verilog中数据类型整体分为net型和variable两个类型,net类型使用assign进行连续赋值,只能被综合成组合逻辑;variable类型使用过程赋值,可能被综合成时序逻辑,可能被综合成组合逻辑

logic类型,即可以被连续赋值也可以被过程赋值,由编译器来进行控制。但是logic只能允许一个输入,不能被多重驱动。wire定义时赋值是连续赋值,而logic定义时赋值只是赋初值,并且赋初值是不能被综合的。

4 TestBench与仿真结果

  1. `timescale 1ns / 1ps
  2. module clk_divider_tb();
  3. reg clk;
  4. wire [31:0] out;
  5. parameter half_cycle = 10;
  6. initial
  7. begin
  8. // code that executes only once
  9. // insert code here --> begin
  10. clk = 0;
  11. forever begin
  12. #half_cycle clk = 1;
  13. #half_cycle clk = 0;
  14. end
  15. // --> end
  16. $display("Running testbench");
  17. end
  18. clk_divider #(
  19. .WIDTH( 32 )
  20. ) CD1 (
  21. .clk( clk ),
  22. .nrst( 1'b1 ),
  23. .ena( 1'b1 ),
  24. .out( out )
  25. );
  26. endmodule

通过仿真波形可以看到,就是简单的计数器原理,之后可以在out输出连接组合逻辑(例如与门)来实现分频操作。


这就是本期的全部内容啦,如果你喜欢我的文章,不要忘了点赞+收藏+关注,分享给身边的朋友哇~

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

闽ICP备14008679号