赞
踩
用一个频率块的时钟产生一个频率小的时钟
掌握任意就分频的写法
一般来说 开发板上面只有一个晶振,即只有一种时钟频率,但是我们有时候需要用到不同频率的时钟,若想要更慢的时钟,则可以将该固定的是何种进行分频,若想要更快的时钟,则可以在这个固定的时钟上进行倍频。无论是分频还是倍频,我们都有两种方法,一种你是使用pll核,另外一种是手动用verilog hdl描述。(适用于整数比的分频),只有调用pll核才能进行倍频,一般在进行非整数比的分频或者倍频的情况下都使用pll核pll为专用电路他生成的时钟到每一级寄存器时间延迟是固定的,称这个时钟网络的时钟偏斜比较小
假如我们要做一个四分频(当前时钟周期的四倍)的时钟,首先我们需要确定是否有四个周期的,然后用一个计数器来记时钟的周期的个数,将连续的一般固定时钟周几设置为高(1),另外连续的一半设置为低(0)。、
- 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

- `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

- /* */
- 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

- `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

可见po_cnt信号出现异常,这是由于同步复位所导致的,如果将复位信号“后推”能否解决,答案是不能的因为一旦rst复位信号后延那么div_cnt也随之后延,最后仍然检测不到rst == 1的状态。
故给po_cnt赋值一个初始值即可解决问题
1.尽量少用复位
FPGA提供专用的全局复位置位信号GSR,在配置结束后,寄存器状态初始化到设定值或者默认逻辑零状态
控制路径可能需要复位,数据路径通常不需要复位
使用功能仿真可判断是否需要复位
少用复位整体上改善性能,减小面积和功耗
2.必须复位时采用同步复位
同步复位可直接映射到FPGA架构中的更多功能器件
DSP48、块RAM只提供同步复位
3.确保使用高电平有效复位
-
-
- 因为XILINX内SLICE和内部逻辑等为高电平复位有效,用低电平需要反相器
-
4.避免异步复位
如果使用异步复位,则异步复位同步释放
上图可见有两个时钟域,时钟域一是由晶振输入的它所走的是全局时钟网络(这个网络在设计芯片的时候已经布局好了,在未来使用过程中到达每一级寄存器的时间是几乎相等的)
对于clk_4的时钟网络,是由我们自己分频出来的,在设计初期没办法设计走线,所以由自己设计出来的分频时钟走的是普通数据线,(到达每一级寄存器的时间延迟是不一样的),延时一旦不一样就会导致时钟的偏斜(Clock Skew))偏大。这种延误会导致时钟的错误。
所以这种自分频的时钟最好不要使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。