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分频
文章来源:https://www.toymoban.com/news/detail-509115.html
3结语
本文主要开始学习Verilog代码,通过编写代码实现FPGA时钟分频。文章来源地址https://www.toymoban.com/news/detail-509115.html
到了这里,关于【实验室学习】时钟分频器,2、3、4、8分频 verilog实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!