FPGA学习altera 系列 第十六篇 分频器设计

2020-12-29 17:07:53 浏览数 (1)

大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。

今天给大侠带来“FPGA学习系列 altera"系列,持续更新。此学习心得是本人之前所写,所用设计软件为Quartus II 13.1,现Quartus II 新版本已更新到19 ,以下仅供初学者学习参考。后续会更新其他系列,敬请关注。话不多说,上货。

对于每一个的小实验,我们都可以把它看作是一个小项目,逐步的去分析,设计,调试,最后完成功能。下面我们就开始我们的“小项目”。

项目名称:分频器

具体要求:将本地晶振分频成一定的频率。

架构图如下:

系统设计:

1. 工程的名称:div_freq。

2. 状态转移图如下:

HW:高电平所占的周期数

LW:低电平所占的周期数

设计代码如下:

代码语言:javascript复制
/*
模块名称:div_freq
模块功能:将本地晶振分频成一定的频率且占空比可调
作者:郝旭帅
邮箱:746833924@qq.com
*/
module div_freq (clk, rst_n, clk_out);

  input clk;
  input rst_n;
  
  output reg clk_out;

  parameter HW = 50;//高电平的周期数
  parameter LW = 50;//低电平的周期数
  
  reg state;
  
  localparam s0 = 1'b0;
  localparam s1 = 1'b1;
  
  reg [25:0] cnt;//计数器
  
  always @ (posedge clk or negedge rst_n)  
    begin
      if (!rst_n)
        begin
          clk_out <= 1'b1;
          state <= s0;
          cnt <= 0;
        end
      else
        begin
          case (state)
            s0 : begin//高电平
                if (cnt < HW - 1)
                  begin
                    cnt <= cnt   1;
                    state <= s0;
                    clk_out <= 1'b1;
                  end
                else  
                  begin
                    cnt <= 0;
                    state <= s1;
                    clk_out <= 1'b1;
                  end
              end
              
            s1 : begin//低电平
                if (cnt < LW - 1)
                  begin
                    cnt <= cnt   1;
                    state <= s1;
                    clk_out <= 1'b0;
                  end
                else  
                  begin
                    cnt <= 0;
                    state <= s0;
                    clk_out <= 1'b0;
                  end
              end
          
            default : state <= s0;
          
          endcase
        end
    end
    
endmodule

解析:

笔者想把本地晶振(50MHz)分频到1Hz,故而将计数器(cnt)的位宽设置为26位。本设计中占空比可以通过改变高电平周期数和低电平的周期数来调节,但是并不是所有的占空比都可以实现。

激励代码如下:

代码语言:javascript复制
/*
模块名称:div_freq_tb
模块功能:为div_freq模块提供激励信号
作者:郝旭帅
邮箱:746833924@qq.com
*/
`timescale 1ns/1ps

module div_freq_tb;
  
  reg clk;
  reg rst_n;
  
  wire clk_out;

  parameter HW = 3;//仿真时,高电平的周期数
  parameter LW = 2;//仿真时,低电平的周期数

  initial begin
    clk = 1'b1;
    rst_n = 1'b0;
    # 200.1
    rst_n = 1'b1;
    # 2000
    $stop;
  end

  always # 10 clk = ~clk;//本地晶振50MHz

  div_freq #(.HW(HW),//传递参数
       .LW(LW)
      )
    div_freq_dut(
      .clk(clk),
      .rst_n(rst_n),
      .clk_out(clk_out)
    );

endmodule

仿真波形如下:

高电平为3个周期,低电平为2个周期。本地晶振是50MHz,我们分频出来的时钟为10MHz,并且占空比为60%。

如果本地晶振或者输出的时钟和笔者的设计不同,请自行更改设计,以保证设计的正确性。如果还是有不明白的读者可以发邮件到我邮箱或者加群询问。

END

0 人点赞