设计背景:
分频在fpga的设计中一直都担任着很重要的角色,而说到分频,我相信很多人都已经想到了利用计算器来计算达到想要的时钟频率,但问题是仅仅利用计数器来分频,只可以实现偶数分频,而如果我需要三分频,五分频,七分频等等奇数类分频,那究竟怎么办呢?在这里,让我介绍一个可以实现任意整数分频的方法,这个办法也是同样利用了计数器来计算,当是跟偶数分频不一样的地方是任意整数分频利用了两个计数器来实现。
设计原理:
本次设计主要是设计一个可调的分频器,我可以设置其参数,可以调节其输出的占空比,占空比的意思就是高电平所占周期的多少。我们通知计算高电平的时间和低电平的时间来实现,其实就是我们用两个计数器来控制的。
设计架构图:
状态转移图
通过对两个计数器的计数,一个计算到了跳转下一个状态,等下一计数器计数到了又调回第一个状态,从而完成任意分频器的设计。
设计代码:
设计模块
0 module fenpinqi(clk,rst_n,clk0);
1 input clk;
2 input rst_n;
3
4 output reg clk0;
5
6 parameter HW = 7 ; //分一个高位7
7 parameter LW = 3 ; //低电平为3 也就是5M的时钟
8
9 localparam s0 = 1'b0; //定义两个状态
10 localparam s1 = 1'b1;
11
12 reg state;
13 reg [2:0] count;
14
15 always @(posedge clk or negedge rst_n)
16 if(!rst_n)
17 begin
18 state <= 1'b0;
19 count <= 3'b0;
20 clk0 <= 1'b0;
21 end
22 else
23 begin
24 case (state)
25 s0:begin
26
27 if(HW + 1 > 1) //判断是否HW为0
28 if(count < HW -1 ) //计数器计数高电平
29 begin
30 clk0 <= 1'b1; //产生高电平
31 count <= count + 1'b1;
32 end
33 else
34 begin
35 count <= 1'b0;
36 state <= 1;
37 end
38 end
39 s1:begin
40 if(LW + 1 > 1) //判断是否LWW为0
41 if(count < LW -1) //计数器计数低电平
42 begin
43 clk0 <= 1'b0; //产生低电平
44 count <= count + 1'b1;
45 end
46 else
47 begin
48 count <= 1'b0;
49 state <= 0;
50 end
51 end
52 default:state <= 0;
53 endcase
54 end
55 endmodule
测试模块
0 `timescale 1ns/1ps
1 module fenpinqi_tb();
2
3 reg clk;
4 reg rst_n;
5
6 wire clk0; //定义输出为wire型
7
8 parameter HW = 5;
9 parameter LW = 1;
10
11 initial begin
12 clk = 1'b1;
13 rst_n = 1'b0;
14
15 #200.1 rst_n = 1'b1;
16 #2000 $stop;
17 end
18 always #10 clk = ~clk; //产生50M时钟
19
20 fenpinqi #(.HW(HW),.LW(LW)) //例化,我们可以在这里改变占空比, 和频率
21 fenpinqi_dut(
22 .clk(clk),
23 .rst_n(rst_n),
24 .clk0(clk0)
25 );
26 endmodule
仿真图:
图中我们通过数上升沿的个数可以看到输出clk0的输出为高7,低3,符合我们的设计。
来源:oschina
链接:https://my.oschina.net/u/2963604/blog/4327597