在FPGA设计中,时钟可以算作系统的“血液”。在时序电路设计中,几乎所有的信号都需要依靠时钟向前传递,因此在进行VHDL开发前需要确定所需的时钟频率。
偶数分频电路
偶数倍分频是最简单的一种分频模式,可通过计数器来实现,有多种实现方法。下面介绍一种最常用的方法。如要进行N倍偶数分频,那么可由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行反转,并给计数器一个复位信号,使得下一个时钟从0开始计数,如此循环下去 。
下面是一个4分频电路:
module clk_div_4(
clk_in,
rst_n,
clk_out
);
input clk_in;
input rst_n;
output clk_out;
reg clk_out_reg;
reg [1:0]cnt;
always@(posedge clk_in) begin
if(!rst_n) begin
cnt <=0;
clk_out_reg<=0;
end
else begin
if(cnt==2'b01) begin
clk_out_reg<=~clk_out_reg;
cnt <= 0;
end
else begin
cnt<= cnt+1;
end
end
end
assign clk_out=clk_out_reg;
endmodule
仿真结果:
奇数分频电路
奇数倍分频有很多实现方法,下面介绍常用的错位异或法的原理。如进行三分频,通过待分频时钟上升沿触发计数器进行模3计数,当计数器计数到临近值时,进行两次反转。这样实现的三分频占空比为1/3或2/3。要实现占空比为50%的三分频时钟,可以通过待分频时钟上升沿和下降沿分别进行三分频,然后将二者得到的分频时钟相或,即可得到占空比为50%的三分频时钟。
下面是3分频电路:
module clk_div_3(
clk_in,
rst_n,
clk_out
);
input clk_in;
input rst_n;
output clk_out;
reg clk_out_reg1;
reg clk_out_reg2;
reg [1:0]cnt1;
reg [1:0]cnt2;
always@(posedge clk_in) begin
if(!rst_n) begin
cnt1<=0;
clk_out_reg1<=0;
end
else begin
if(cnt1==2) begin
cnt1<=0;
clk_out_reg1<=clk_out_reg1;
end
else begin
cnt1<=cnt1+1;
clk_out_reg1<=~clk_out_reg1;
end
end
end
always@(negedge clk_in) begin
if(!rst_n) begin
cnt2<=0;
clk_out_reg2<=0;
end
else begin
if(cnt2==2) begin
cnt2<=0;
clk_out_reg2<=clk_out_reg2;
end
else begin
clk_out_reg2<=~clk_out_reg2;
cnt2<=cnt2+1;
end
end
end
assign clk_out=clk_out_reg1|clk_out_reg2;
endmodule
仿真结果如下: