实现目标
最近想设计一个实现时钟信号90°相移的代码,网上的都是通过FPGA调用PLL或者MCMM来实现的,奈何我是数字IC设计,没有这样的IP,只能自己苦想了一个办法用Verilog实现。
首先要有想相移时钟的至少两倍频时钟,然后对这个倍频时钟取反,用得到的反倍频时钟去采样想要相移的时钟即可得到90°相移的时钟信号,可以参考以下的时序图
代码和说明
因为倍频同样需要PLL或MCMM等IP,我同样无法用,故这次写的代码是用时钟分频得到想要相移的时钟的,顶层具体代码如下:
//-----------------------------------------------------------------------------------------------
// Copyright :
// Author : Luk.wj
// File Name : clk_90
// Module Name : clk_90
// Create : 2021.12.09
// Revise :
// Fuction :
//-----------------------------------------------------------------------------------------------
module CLK_90 (
input clk_256,
input rst_n,
output reg clk_out
);
wire clk_128;
assign clk_256_inv = ~clk_256;
Div#(
.cnt_width ( 2 ),
.fre_div ( 2 )
)u_Div(
.rst_n ( rst_n ),
.clk_in ( clk_256 ),
.clk_out ( clk_128 )
);
always @(posedge clk_256_inv or negedge rst_n) begin
if(!rst_n) clk_out <= 1'b0;
else clk_out <= clk_128;
end
endmodule
上面的代码调用了一个分频子模块,是我自己写的代码,具体可以参考我另一篇博文:
Verilog—1/x整数分频器通用代码.
测试结果和建议
前仿真的结果如下:
前仿真结果完美。
后仿真因为布局布线的问题,得到相移信号会有所延迟,我在FPGA上面验证了一下,比理想情况延迟了0.2ns,这对我的设计是无法接受的。另外,这次设计是把时钟信号当普通信号去采,理论上是可以的,实际上要斟酌考虑一下,延迟也是另一个问题,而且做数字IC中,这样的时序约束也是比较困难的,故不太建议采用这样的办法。个人建议还是用IP实现,或者用延迟门在底层布局布线来实现精准的时钟相移,这就需要模拟IC的知识了。