【FPGA学习】时钟分频

概况:

用一个频率块的时钟产生一个频率小的时钟

实验目的:

掌握任意就分频的写法

原理:

一般来说 开发板上面只有一个晶振,即只有一种时钟频率,但是我们有时候需要用到不同频率的时钟,若想要更慢的时钟,则可以将该固定的是何种进行分频,若想要更快的时钟,则可以在这个固定的时钟上进行倍频。无论是分频还是倍频,我们都有两种方法,一种你是使用pll核,另外一种是手动用verilog hdl描述。(适用于整数比的分频),只有调用pll核才能进行倍频,一般在进行非整数比的分频或者倍频的情况下都使用pll核pll为专用电路他生成的时钟到每一级寄存器时间延迟是固定的,称这个时钟网络的时钟偏斜比较小

     假如我们要做一个四分频(当前时钟周期的四倍)的时钟,首先我们需要确定是否有四个周期的,然后用一个计数器来记时钟的周期的个数,将连续的一般固定时钟周几设置为高(1),另外连续的一半设置为低(0)。、

四分频

【FPGA学习】时钟分频_第1张图片

module div_clk_4(
	input  wire clk,
	input  wire rst,//高电平有效,XILINX器件提倡高电平有效
	
	output 	reg clk_4

);
	reg [1:0] div_cnt;
	always @(posedge clk )begin 
		if(rst == 1'b1)begin
			div_cnt <= 'd0;
		end
		else if(div_cnt == 2'd3) begin						
			div_cnt <= 'd0;													
		end
		else begin
			div_cnt <= div_cnt + 1'b1;
		end 
	end
	
	always @(posedge clk )begin 
		if(rst == 1'b1)begin
			clk_4 <= 1'b0;
		end
		else if (div_cnt == 2'd1)begin
			clk_4 <= 1'b1;
		end
		else if (div_cnt == 2'd3)begin
			clk_4 <= 1'b0;
		end
	end
endmodule 

tesbench

`timescale 1ns/1ns
module tb_div_clk_4();
	reg clk;
	reg rst;
	
	wire clk_4;
	
	div_clk_4    u_div_clk_4(
	
	.clk (clk),
	.rst (rst),
	
	.clk_4 (clk_4)
	);
always #10 clk = ~clk;
	initial begin
		clk = 0;
		rst = 1;
		#100
		rst = 0;//退出复位
		
	end
endmodule 

 【FPGA学习】时钟分频_第2张图片

 十六分频

【FPGA学习】时钟分频_第3张图片

/*  */
module div_clk_16(
	input  wire clk,
	input  wire rst,
	output 	reg 	[1:0]	po_cnt = 'd0

);
	reg [1:0] div_cnt;
	reg  clk_4;
	always @(posedge clk )begin 
		if(rst == 1'b1)begin
			div_cnt <= 'd0;
		end
		else if(div_cnt == 2'd3) begin
			div_cnt <= 'd0;	
		end
		else begin
			div_cnt <= div_cnt + 1'b1;
		end 
	end
	
	always @(posedge clk )begin 
		if(rst == 1'b1)begin
			clk_4 <= 1'b0;
		end
		else if (div_cnt == 2'd1)begin
			clk_4 <= 1'b1;
		end
		else if (div_cnt == 2'd3)begin
			clk_4 <= 1'b0;
		end
	end
	
	always @(posedge clk_4 )begin
		if(rst == 1'b1)begin
			po_cnt <= 1'b0;
		end
		else if (po_cnt == 2'd3)begin
			po_cnt <= 'd0;
		end
		else begin
			po_cnt <= po_cnt + 1'b1;
		end
	end
endmodule 

 tesbench

`timescale 1ns/1ns
module tb_div_clk_16();
	reg clk;
	reg rst;
	
	wire [1:0] po_cnt;
	
	div_clk_16	u_div_clk_16(
	
	.clk (clk),
	.rst (rst), 
	
	.po_cnt (po_cnt)
	);
always #10 clk = ~clk;
	initial begin
		clk = 0;
		rst = 1;
		#100
		rst = 0;
		
	end
endmodule 

【FPGA学习】时钟分频_第4张图片 可见po_cnt信号出现异常,这是由于同步复位所导致的,如果将复位信号“后推”能否解决,答案是不能的因为一旦rst复位信号后延那么div_cnt也随之后延,最后仍然检测不到rst == 1的状态。

【FPGA学习】时钟分频_第5张图片

 故给po_cnt赋值一个初始值即可解决问题

【FPGA学习】时钟分频_第6张图片

xilinx建议的复位准则(原文连接xilinx建议的复位准则_leave_her_johnny的博客-CSDN博客_xilinx 复位)

1.尽量少用复位 

FPGA提供专用的全局复位置位信号GSR,在配置结束后,寄存器状态初始化到设定值或者默认逻辑零状态

控制路径可能需要复位,数据路径通常不需要复位

使用功能仿真可判断是否需要复位

少用复位整体上改善性能,减小面积和功耗

 2.必须复位时采用同步复位

同步复位可直接映射到FPGA架构中的更多功能器件

DSP48、块RAM只提供同步复位

3.确保使用高电平有效复位 

​

因为XILINX内SLICE和内部逻辑等为高电平复位有效,用低电平需要反相器
​

 4.避免异步复位

如果使用异步复位,则异步复位同步释放 

关于时钟域的一些笔记

【FPGA学习】时钟分频_第7张图片

        上图可见有两个时钟域,时钟域一是由晶振输入的它所走的是全局时钟网络(这个网络在设计芯片的时候已经布局好了,在未来使用过程中到达每一级寄存器的时间是几乎相等的

对于clk_4的时钟网络,是由我们自己分频出来的,在设计初期没办法设计走线,所以由自己设计出来的分频时钟走的是普通数据线,(到达每一级寄存器的时间延迟是不一样的),延时一旦不一样就会导致时钟的偏斜(Clock Skew))偏大。这种延误会导致时钟的错误。

所以这种自分频的时钟最好不要使用。

你可能感兴趣的:(Spartan-6,fpga开发,学习)