首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将100 into时钟分成16 into时钟[Verilog]

将100 into时钟分成16 into时钟[Verilog]
EN

Stack Overflow用户
提问于 2017-04-15 04:49:18
回答 2查看 2.4K关注 0票数 1

正如锡上写的,我有一个100 the的时钟(取自Nexys 3 Spartan 6板),我想把它分成16 the的时钟。我做了1兆赫和60赫兹的时钟没有问题,但我有一些问题获得干净的16兆赫信号。

以下是我目前正在测试的内容:

代码语言:javascript
复制
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整除的值。

EN

回答 2

Stack Overflow用户

发布于 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时钟。

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 2017-04-15 22:42:18

听起来你想用数字电路实现一个小数时钟分频器。由于时钟的分频是一个分数,因此输出时钟将在两个时钟周期之间抖动(在您的例子中,介于100 MHz时钟的6到7个周期之间),但平均值将是100/16=6.25个周期。如果分数小于或等于原始频率的一半,则如下所示:

代码语言:javascript
复制
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的比率下工作。

代码语言:javascript
复制
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;

在这种情况下,正边缘通过使两个信号不同而使时钟变高,而负边缘总是使时钟变低。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43419048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档