首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从100 base基准时钟生成78 base时钟

从100 base基准时钟生成78 base时钟
EN

Stack Overflow用户
提问于 2012-11-11 01:40:57
回答 2查看 6K关注 0票数 5

我必须使用VHDL语言从一个100 the的基准时钟(占空比0.5)生成一个78 the的时钟(占空比为0.5或0.7) (因此比率是200/156)。我知道我可以使用DCM、PLL或类似的工具,但现在(不幸的是)我就是不能。

因此,我想使用(不包括任何DCM或PLL)一个简单的分频器,但在这种情况下,我也知道频率只能除以整数(最小2,因为我会使用计数器来做这件事-在我的例子中,我必须除以1,2820512820512820512820512820513…)。

所以我不知道如何在不使用任何DCM或其他东西的情况下实现这一点。我想把100 the的时钟分成更小的频率(比如50 the,25 the等等)。并添加它们(例如50+25+3),但这是正确的方法吗(从逻辑上讲,我不这么认为)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-13 03:47:06

这里是一个通用的小数M/D时钟分频器设计,应该可以解决您的问题。几年前,我写了这篇文章供我自己使用。根据您的目标设备,您可能希望使用std_logic而不是bit。

基本思想是使用累加器跟踪小数时钟相位。这非常类似于如何实现直接数字合成器(DDS),但只需担心时钟。

尽情享受!=)

如果不清楚如何使用它,您将用于乘数39和除数50的参数作为100 * 39/100 = 78,因此所需的操作数宽度是6(因为2**6 = 64)。请注意,由于这是输入时钟速率的一半以上,因此没有同步逻辑可以生成输出时钟信号,因此该模块在该速率下的唯一有效输出将是时钟使能。

还要注意,对于任何可能的除数值,对于任何一个周期,最坏的情况是33%/66%的占空比。你对乘数和除数的特殊选择可能会更好(我需要做一些数学运算来告诉你),但你不能比任何使用有理除法的算法在最坏的情况下得到更好的结果。您可以使用实际硬件PLL或DLL来清理此模块的输出,以过滤相位噪声并使占空比进入您的目标范围。

代码语言:javascript
复制
-- Copyright © 2010 Wesley J. Landaker <wjl@icecavern.net>
-- 
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- 
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
-- 
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

library ieee;
use ieee.numeric_bit.all;

-- Clock Divider
-- =============
--
-- Fractionally divides the input clock using simultaneous frequency
-- multiplication and division.
--
-- Outputs both a clock enable and a balanced duty-cycle clock. The clock's
-- duty-cycle is as always close to 50% as possible, worst case is 33%/66%.
--
-- Details
-- =======
--
-- Given:
--
--   Fi = input frequency Hz
--   M  = multiplier
--   D  = divisor
--   Fo = output frequency Hz
--
-- Where:
--
--   M ≤ D
--
-- Then:
--
--        ⎧    M
--        ⎪ Fi·—        if M <= D
--   Fo = ⎨    D
--        ⎪
--        ⎩ undefined   if M > D
--
--
-- If (M/D) is greater than 0.5, only the clock enable is valid.
-- If (M/D) is greater than 1.0, both outputs are invalid.

entity Clock_Divider is
  generic (
    operand_width : positive
    );
  port (
    clock : in bit;
    reset : in bit;

    multiplier : in unsigned(operand_width-1 downto 0);
    divisor    : in unsigned(operand_width-1 downto 0);

    out_enable : buffer bit;
    out_clock  : buffer bit
    );
end entity;

architecture any of Clock_Divider is
  signal enable_2x : bit;
begin

  -- Divide the clock by accumulating phase using the mulitplier and
  -- subtracting when we pass the divisor value.

  proc_enable : process is
    variable phase : unsigned(operand_width downto 0);
  begin
    wait until rising_edge(clock);
    phase := phase + multiplier;
    if phase >= divisor then
      phase := phase - divisor;
      out_enable <= '1';
    else
      out_enable <= '0';
    end if;
    if reset = '1' then
      phase := (others => '0');
      out_enable <= '0';
    end if;
  end process;

  proc_enable : process is
    variable phase : unsigned(operand_width downto 0);
  begin
    wait until rising_edge(clock);
    phase := phase + (multiplier & '0');
    if phase >= divisor then
      phase := phase - divisor;
      enable_2x <= '1';
    else
      enable_2x <= '0';
    end if;
    if reset = '1' then
      phase := (others => '0');
      enable_2x <= '0';
    end if;
  end process;


  proc_out_clock : process is
  begin
    wait until rising_edge(clock);
    if enable_2x = '1' then
      out_clock <= not out_clock;
    end if;
  end process;

end architecture;
票数 5
EN

Stack Overflow用户

发布于 2012-11-14 00:53:15

完全出人意料的想法,有点特定于技术,所以可能不适合你的目标,而且相当可怕……

很明显,如果没有(a) PLL,(b) DLL,(c)更高的频率时钟或(d) 5 5ns p-p抖动,你就不能做到这一点。

您需要更多可用的时钟边沿,但是(假设)您没有更多的时钟边沿,您将不得不生成自己的时钟边沿。一种特定于技术(Xilinx)的方法是通过多个引脚将时钟送出,然后再送回,每个引脚上都有不同的IBUFDELAY设置。实际设置可能会通过实验(甚至在通电时)进行校准,自然会受到温度漂移的影响。

另一种方式可以是LUT链连续延迟时钟,逻辑检测第n个延迟超过半个周期。(或整个周期),然后点击n/2大约晚90度,n/4晚45度,等等(您无法确保这些时间的一致性。不过,布局规划和锁定这个核心在一定程度上会有所帮助。)

无论哪种方式,一旦你有了100 the时钟的多个相位,你就可以将它们应用于上面描述的DDS (小数分频器)。性能不太可能是稳定的,但应该比目前最好的5 5ns更好。

(是的,我知道这等同于滚动您自己的(和次要的) DLL。这算作弊吗?)

对于复杂度较低的方法,您可以尝试Peter Alfke的延迟/XOR技巧,以便从100 out时钟中获得200 out。不能保证它的M/S比,但它确实给了你4个边来玩…

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

https://stackoverflow.com/questions/13324445

复制
相关文章

相似问题

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