理论学习
数字电路中时钟占有非常重要的地位。时间的计算都依靠时钟信号作为基本单元。一般而言,一块板子只有一个晶振,即只有一种频率的时钟,但是数字系统中,经常需要对基准时钟进行不同倍数的分频,进而得到各模块所需的频率。
若想得到比系统时钟更慢的时钟,可以将基准时钟进行分频。
若想得到比系统时钟更快的时钟,可以将基准时钟进行倍频。
不管是分频还是倍频,都通过PLL实现或者用verilog描述实现。
我们用verilog实现的一般是分频电路,即分频器。分频电路是数字系统设计中常用的基本电路之一。
分频器分为偶数分频和奇数分频。
偶数分频demo1
module divider_sex
(
input wire sys_clk ,
input wire sys_rst_n ,
output reg clk_out
);
reg [1:0] cnt ;
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
cnt <= 2'd0 ;
end
else if( cnt == 2'd2 )
begin
cnt <= 2'd0 ;
end
else
begin
cnt <= cnt + 1'b1 ;
end
end
always@(posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
clk_out <= 1'b0 ;
end
else if( cnt == 2'd2 )
begin
clk_out <= ~clk_out ;
end
end
endmodule
偶数分频demo2
module divider_six
(
input wire sys_clk ,
input wire sys_rst_n ,
outpur reg clk_out
);
reg [2:0] cnt ;
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
cnt <= 3'd0 ;
end
else if( cnt == 3'd5 )
begin
cnt <= 3'd0 ;
end
else
begin
cnt <= cnt + 1'b1 ;
end
end
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
clk_out <= 1'b0 ;
end
else if( cnt == 3'd4 )
begin
clk_out <= 1'b1 ;
end
else
begin
clk_out <= 1'b0 ;
end
end
endmodule
偶数分频对应的tb
`timescale 1ns/1ns
module tb_divider_six();
reg sys_clk ;
reg sys_rst_n ;
wire clk_out ;
initial
begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
#20 ;
sys_rst_n <= 1'b1 ;
end
always #10 sys_clk <= ~sys_clk ;
divider_six divider_six_inst
(
.sys_clk (sys_clk) ,
.sys_rst_n (sys_rst_n) ,
.clk_out (clk_out)
);
endmodule
奇数分频
module divider_five
(
input wire sys_clk ,
input wire sys_rst_n ,
output wire clk_out
);
reg [2:0] cnt ;
reg clk1 ;
reg clk2 ;
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
cnt <= 3'd0 ;
end
else if( cnt == 3'd4 )
begin
cnt <= 3'd0 ;
end
else
begin
cnt <= cnt + 1'b1 ;
end
end
//clk1
always@( posedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
clk1 <= 1'b1 ;
end
else if( cnt == 3'd2 )
begin
clk1 <= 1'b0 ;
end
else
begin
clk1 <= 1'b1 ;
end
end
//clk2
always@( negedge sys_clk or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
clk2 <= 1'b1 ;
end
else if( cnt == 3'd2 )
begin
clk2 <= 1'b0 ;
end
else
begin
clk2 <= 1'b1 ;
end
end
assign clk_out = clk1 & clk2 ;
endmodule
奇数分频的tb
`timescale 1ns/1ns
module tb_divider_five();
reg sys_clk ;
reg sys_rst_n ;
wire clk_out ;
initial
begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
#20 ;
sys_rst_n <= 1'b1 ;
end
always #10 sys_clk <= ~sys_clk ;
divider_five divider_five_inst
(
.sys_clk (sys_clk) ,
.sys_rst_n (sys_rst_n) ,
.clk_out (clk_out)
);
endmodule