正如锡上写的,我有一个100 the的时钟(取自Nexys 3 Spartan 6板),我想把它分成16 the的时钟。我做了1兆赫和60赫兹的时钟没有问题,但我有一些问题获得干净的16兆赫信号。
以下是我目前正在测试的内容:
module clk_gen(
input clk_100MHz,
output reg clk_16MHz,
output reg clk_1MHz,
output reg clk_1s );
integer count_16MHz;
integer count_1MHz;
integer count_1s;
integer skip_cnt;
initial begin
count_16MHz = 1;
count_1MHz = 1;
count_1s = 1;
skip_cnt = 1;
clk_1s = 1'b0;
clk_1MHz = 1'b0;
clk_16MHz = 1'b0;
end
//16MHz
always@(posedge clk_100MHz) begin
//8*(100Mhz/6.25) == 7*(100MHz/6)+((100MHz/8))
if((skip_cnt == 8) & (count_16MHz == 4)) begin
clk_16MHz = ~clk_16MHz;
skip_cnt = 1;
count_16MHz = 1;
end
else if((skip_cnt < 8) & (count_16MHz == 3)) begin
clk_16MHz = ~clk_16MHz;
skip_cnt = skip_cnt + 1;
count_16MHz = 1;
end
count_16MHz = count_16MHz + 1;
end
//1MHz
always@(posedge clk_100MHz) begin
if(count_1MHz == 50) begin
clk_1MHz = ~clk_1MHz;
count_1MHz = 1;
end
count_1MHz = count_1MHz + 1;
end我有我的1 1Mhz和60 is (1秒)的分频,但16 1Mhz是一个痛苦。有没有更好的方法(同时保留在Verilog中)?
不幸的是,我确实想要一个非常严格的16 1MHz,因为在1 1MHz时钟周期之间发生了16次移位操作。我唯一的另一种攻击方法可能是将1 1MHz降低到更慢、更容易被16整除的值。
发布于 2017-04-15 11:23:25
使用FPGA上可用的时钟资源。
由于您使用的是Spartan-6,因此可以访问DCM_CLKGEN和DCM_SP原语。设置这些的最简单方法是使用Xilinx时钟向导,但是如果您真的想使用Verilog来设置,您可以直接实例化一个DCM_CLKGEN。
从100 MHz到16 MHz的最简单方法是乘以4,然后再除以25。通过将输出除以16,数模转换器还可以同时产生1 MHz时钟。
DCM_CLKGEN #(
.CLKIN_PERIOD("100 MHZ"),
.CLKFX_MULTIPLY(4),
.CLKFX_DIVIDE(25),
.CLKFXDV_DIVIDE(16)
) clkgen_100to16and1 (
.RST (1'b0),
.CLKIN (clk_100MHz),
.CLKFX (clk_16MHz),
.CLKFXDV (clk_1MHz)
);请注意,16 MHz和1 MHz输出之间没有保证的相位关系。
有关Spartan-6中提供的DCM和其他时钟资源的详细信息,请参阅Xilinx文档UG382: Spartan-6 FPGA Clocking Resources。
发布于 2017-04-15 22:42:18
听起来你想用数字电路实现一个小数时钟分频器。由于时钟的分频是一个分数,因此输出时钟将在两个时钟周期之间抖动(在您的例子中,介于100 MHz时钟的6到7个周期之间),但平均值将是100/16=6.25个周期。如果分数小于或等于原始频率的一半,则如下所示:
always@(posedge clk_100MHz) begin
if(count_16MHz >= 100) begin
clk_16MHz <= 1;
count_16MHz <= count_16MHz - 100 + 16;
end
else begin
count_16MHz <= count_16Mhz + 16;
if(count_16MHz >= 50) begin
clk_16MHz <= 0
end
end
end分频器的关键是它不会被重置为0,它只是在一个时钟周期发生时递减100。
如果分数大于一半,这个电路就不工作了。由于此电路仅在原始时钟的后沿计时,因此在这种情况下,没有足够的后沿时钟来生成所生成时钟的上升沿和下降沿。
这里是一种实现方式,它将时钟保持为高电平,持续较快时钟的半个时钟周期,因此可以在大于1/2的比率下工作。
always@(posedge clk_100MHz) begin
if(count_75MHz >= 100) begin
pos <= ~neg;
count_75MHz <= count_75MHz - 100 + 75;
end
else begin
count_75MHz <= count_75Mhz + 75;
end
end
always@(negedge clk_100MHz) begin
neg <= pos;
end
assign clk_75MHz <= pos ^ neg;在这种情况下,正边缘通过使两个信号不同而使时钟变高,而负边缘总是使时钟变低。
https://stackoverflow.com/questions/43419048
复制相似问题