Verilog:【1】时钟分频电路(clk_divider.sv)

碎碎念:

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

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

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

目录

1 模块功能

2 模块代码

3 模块思路

4 TestBench与仿真结果


1 模块功能

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

2 模块代码

//------------------------------------------------------------------------------
// clk_divider.sv
// published as part of https://github.com/pConst/basic_verilog
// Konstantin Pavlov, [email protected]
//------------------------------------------------------------------------------

// INFO ------------------------------------------------------------------------
//  Divides main clock to get derivative slower synchronous clocks
//

/* --- INSTANTIATION TEMPLATE BEGIN ---

clk_divider #(
  .WIDTH( 32 )
) CD1 (
  .clk( clk ),
  .nrst( 1'b1 ),
  .ena( 1'b1 ),
  .out(  )
);

--- INSTANTIATION TEMPLATE END ---*/


module clk_divider #( parameter
  WIDTH = 32
)(
  input clk,
  input nrst,
  input ena,
  output logic [(WIDTH-1):0] out = '0
);


always_ff @(posedge clk) begin
  if ( ~nrst ) begin
    out[(WIDTH-1):0] <= '0;
  end else if (ena) begin
    out[(WIDTH-1):0] <= out[(WIDTH-1):0] + 1'b1;
  end
end

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与仿真结果

`timescale 1ns / 1ps
module clk_divider_tb();

reg  clk;
wire [31:0] out;
parameter half_cycle = 10;

initial                                                
begin                                                  
// code that executes only once                        
// insert code here --> begin                          
    clk = 0;
    forever begin
        #half_cycle clk = 1;
        #half_cycle clk = 0;
    end                                                          
// --> end                                             
$display("Running testbench");                       
end     

clk_divider #(
  .WIDTH( 32 )
) CD1 (
  .clk( clk ),
  .nrst( 1'b1 ),
  .ena( 1'b1 ),
  .out( out )
);

endmodule

Verilog:【1】时钟分频电路(clk_divider.sv)_第1张图片

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


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

你可能感兴趣的:(Basic,Verilog,修炼足迹,fpga开发,Verilog,System,Verilog)