【实验室学习】时钟分频器,2、3、4、8分频 verilog实现

0引言

记录时钟分频器的Verilog代码编写,主要掌握分频器设计思路

1设计----2、3、4、8分频

2、4、8分频设计较为容易:

2分频—设计一个1位的寄存器,当原时钟上升沿时取反即可
代码展示:

`timescale 1ns / 1ps
module Clk_divider
(
input clk_i,
input rst_i,
output div_2_out,
output div_4_out,
output div_3_out,
output div_8_out;

);
//2分频代码
reg div_2_o;
always@(posedge clk_i)
begin
     if(!rst_i)
	     div_2_o<=1'b0;
     else
	     div_2_o<=~div_2_o;
end
assign div_2_out=div_2_o;
endmodule

4分频与8分频—设计一个两位的计数器,4分频只需在计数器计数到00B或者10B时跳变电平即可,8分频只需在计数器计数到00B时跳变电平即可。

原因:计数器跳变一次需要一个时钟周期,00->01->10->11->00 一次循环需要四个clk周期,4分频在两次周期时跳变即可,8分频在四次周期时跳变即可。
代码展示:

//4、8分频代码定义一个两位的寄存器实现
`timescale 1ns / 1ps
module Clk_divider
(
input clk_i,
input rst_i,
output div_2_out,
output div_4_out,
output div_3_out,
output div_8_out;

);
reg [1:0]div_reg_4_8;
reg div_4_o;
reg div_8_o;

always@(posedge clk_i)
begin
     if(!rst_i)
	     div_reg_4_8<=2'b00;
     else
	     div_reg_4_8<=div_reg_4_8+1'b01;
end


always@(posedge clk_i)
begin
     if(!rst_i)
	     div_4_o<=1'b0;
	 else if(div_reg_4_8==2'b00||div_reg_4_8==2'b10)
	     div_4_o<=~div_4_o;
     else
	     div_4_o<=div_4_o;
end
		 
always@(posedge clk_i)
begin
     if(!rst_i)
         div_8_o<=1'b0;
     else if(div_reg_4_8==2'b00)
         div_8_o<=~div_8_o;	 
	 else
	     div_8_o<=div_8_o;
end
assign div_4_out=div_4_o;
assign div_8_out=div_8_o;
endmodule

3分频较为复杂,需要设计两个计数器,一个计数器在clk下降沿工作,一个计数器在clk上升沿工作。且两个计数器计数三次一循环,而后设计两个寄存器r0与r1,两寄存器分别交错半个周期,高电平与低电平分别占据1.5个clk周期,即可完成3分频。

module Clk_divider
(
input clk_i,
input rst_i,
output div_2_out,
output div_4_out,
output div_3_out,
output div_8_out;

);
/*3分频代码定义两个寄存器,分别在clk上升沿和下降沿工作*/

reg [1:0]pos_cnt;
reg [1:0]neg_cnt;
reg  div_3_r0;
reg  div_3_r1;

always@(posedge clk_i)
begin
     if(!rst_i)
	     pos_cnt<=2'b00;
     else if(pos_cnt==2'd2)
	     pos_cnt<=2'b00;
     else
	     pos_cnt<=pos_cnt+1'b1;
end

always@(negedge clk_i)
begin
     if(!rst_i)
	     neg_cnt<=2'b00;
     else if(neg_cnt==2'd2)
	     neg_cnt<=2'b00;
     else
	     neg_cntt<=neg_cnt+1'b1;
end

always@(posedge clk_i)
begin
     if(!rst_i)
	     div_3_r0<=1'b0;
     else if(pos_cnt<2'b1)
	     div_3_r0<=1'b1;
	 else 
	     div_3_r0<=1'b0;
end

always@(negedge clk_i)
begin
     if(!rst_i)
	     div_3_r1<=1'b0;
     else if(neg_cnt<2'b1)
	     div_3_r1<=1'b1;
	 else 
	     div_3_r1<=1'b0;
end

assign div_3_out = div_3_r0||div_3_r1;
endmodule

2仿真实现

仿真代码如下:

`timescale 1ns / 1ps
module Clk_divider_f
(
);
reg clk_i;
reg rst_i;
wire div_2_out;
wire div_4_out;
wire div_3_out;
wire div_8_out;


Clk_divider#
(
.DEBUG_ENABLE(1'b0),
.REF_CLK(100000000)
)
Clk_divider_1
(
.clk_i(clk_i),
.rst_i(rst_i),
.div_2_out(div_2_out),
.div_4_out(div_4_out),
.div_3_out(div_3_out),
.div_8_out(div_8_out)
);
initial begin
clk_i = 0; 
rst_i = 0; // Wait 100 ns for global reset to finish 
#100; 
rst_i=1; 
end

always #5 clk_i=~clk_i;


endmodule

仿真结果如下:
100ns时复位为0,开始工作
在这里插入图片描述
仿真结果符合预期,实现了2、3、4、8分频
在这里插入图片描述

3结语

本文主要开始学习Verilog代码,通过编写代码实现FPGA时钟分频。

  • 5
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值