Перейти к содержанию
    

Делитель входной частоты

Здравствуйте. Есть такая поставленная задача. Есть входная частота 60 Мгц. Нужно написать модуль, который будет делить динамически эту частоту на определенный коэффициент. Я написал модуль, который делит эту частоту на целые числа 2,3,4,5... поэтому на выходе можно получить частоты 30МГц, 20Мгц, 15МГц, 12МГц и т.д. Код ниже:

library ieee;
use ieee.std_logic_1164.ALL; 
use ieee.std_logic_unsigned.ALL; 
use IEEE.std_logic_arith.all; 

entity devide_clk is
    generic (
        DEVIDE_WIDTH: integer := 8
    );
    port (
        clk_in: IN std_logic;
        reset: IN std_logic;
        devide: in std_logic_vector(0 to DEVIDE_WIDTH-1);
        clk_out: OUT std_logic := '0'
    );                          
end entity devide_clk;     

architecture devide_clk_a of devide_clk is     
begin          
    process(clk_in, reset, devide) 
        variable stat : std_logic := '1';
        variable count: std_logic_vector(0 to DEVIDE_WIDTH-1); 
        begin
        if(clk_in = '1') then    
            if(count < ((devide-1)) ) then
                clk_out <=     stat;
                count := count + 1;
            else    
                clk_out <=not stat;
                stat := not stat;                
                count := (others => '0');
            end if;
        end if;    
        if(clk_in = '0') then    
            if(count < ((devide-1)) ) then
                clk_out <=     stat;
                count := count + 1;
            else      
                clk_out <=not stat;
                stat := not stat;                
                count := (others => '0');
            end if;
        end if;                
        if(reset = '1') then
            count := (others => '0');
            stat := '1';   
            clk_out <= '0';
        end if;
    end process; 
end architecture;

 

 

Но необходимо написать модуль который будет на выходе выдавать любые частоты в диапазоне от 1КГц до 50 МГц (длительной нуля и единицы при этом не обязательно должны быть одинаковыми, частота определяется количествами передних фронтов). У меня не получается написать такой модуль. Не подскажите как мне его написать? Или может у кого-то уже есть готовый модуль? Если можно то поделитесь... Заранее спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насчет динамического не знаю. А параметрический можно.

Ввести два параметра. Частоту системного клока и рабочую частоту на выходе.

Вот и получится счетчик с нужным коэффициентом пересчета.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужен именно динамический делитель. Есть ли у кого готовый пример? Или мысли о том как его сделать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос джиттера.

Если частота измеря от фронта до фронтается за бесконечно(приблизительно) долгий период времени и никого не волнует джиттер (грубо - постоянство периода времени от фронта до фронта) - проблем нет.

Делается сумматор на 32 бита скажем. и через регистр задается константа для суммирования. Причем константа=2**32*(X/60) где X - нужная частота. По признаку переполнения сумматора "пропускаем" клок наружу. Примерно так.

Вроде.

 

Если джиттер важен - когда решите задачку средствами ПЛИСа - скажите мне :) Очень хочется знать. ИМХО - динамически не получится. Статически - с помощью DCM с соответствующими ограничениями.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я новичек в этом деле. Если чесно я не понял основной идеи предлагаемого вами метода :( Попроще никак нельзя? И все-таки если можно хоть какой-нибудь примерчик...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда обьясните поподробнее алгоритм. Что является первым аргументом операции суммирования, а что вторым? Если у вас ссылки на этот алгоритм в Интернете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Код ниже
В целевой FPGA наверняка не будет триггеров, работающих по обоим фронтам клока.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что является первым аргументом операции суммирования, а что вторым?

Один аргумент - константа (см. формулу выше).

Второй - результат предыдущей операции.

Код я принципиально писать не буду. Хоть что-то надо сделать самому.... Впрочем в pdf'ке выше и так есть готовая схема.

 

[offtop]По-моему студенты совсем оборзели....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не студент. Код писать никого не просил. Я попросил лишь поподробнее обьянить. А код я просил предложить только в том случае, если он уже написан был до этого. Так что я не считаю что я оборзел.

 

После того как ты сказал, что "Второй - результат предыдущей операции." мне сразу стало понятно, я почему-то сам до этого не ддумался :( всем спасибо...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос джиттера.

Если частота измеря от фронта до фронтается за бесконечно(приблизительно) долгий период времени и никого не волнует джиттер (грубо - постоянство периода времени от фронта до фронта) - проблем нет.

Делается сумматор на 32 бита скажем. и через регистр задается константа для суммирования. Причем константа=2**32*(X/60) где X - нужная частота. По признаку переполнения сумматора "пропускаем" клок наружу. Примерно так.

Вроде.

 

Наверное, я жутко туплю, т.к. деление частоты аккумулятором не использовал, но не получается поделить частоту, например в 3 раза. Пусть разрядность N = 4, коэф. деления D = 3, тогда константа

K = 2**N*Fout/Fin = 2**N/D = 5.(3). Округляя и к 5, и к 6 деление в 3 раза не получаю...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Наверное, я жутко туплю, т.к. деление частоты аккумулятором не использовал, но не получается поделить частоту, например в 3 раза. Пусть разрядность N = 4, коэф. деления D = 3, тогда константа

K = 2**N*Fout/Fin = 2**N/D = 5.(3). Округляя и к 5, и к 6 деление в 3 раза не получаю...

 

http://electronix.ru/forum/index.php?showtopic=55615

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задачу реализовал. Отпишите на сколько грамотен мой код?

 

adder.vhd

library IEEE;
use IEEE.std_logic_1164.all;

entity adder is
    port (
        A, B : in std_logic_vector(31 downto 0); 
        RESET : in std_logic;
        Q : out std_logic_vector(31 downto 0)
    );
end entity;

library IEEE;
use IEEE.std_logic_unsigned.all;

architecture adder_arch of adder is
begin
    process (A, B, RESET)
    begin
        if(RESET = '0') then
            Q <= (others => '0');
        else
            Q <= A + B;
        end if;
    end process;

end architecture;

register32.vhd

library IEEE;
use IEEE.std_logic_1164.all;

entity register32 is
    port (
        CLK : in std_logic;
        DATA : in std_logic_vector(31 downto 0);
        Q : out std_logic_vector(31 downto 0)
    );
end entity;

architecture register32_arch of register32 is
begin
    process (CLK)
    begin

        if rising_edge(CLK) then
            Q <= DATA;
        end if;

    end process;

end register32_arch;

add_devider.vhd

library IEEE;
use IEEE.std_logic_1164.all;

entity add_devider is       
    port (
        CONST : in STD_LOGIC_VECTOR(31 downto 0);  
        RESET : in std_logic;
        CLK_IN : in STD_LOGIC;
        CLK_OUT : out STD_LOGIC;
        REG_OUT : out STD_LOGIC_VECTOR(31 downto 0)
  );
end add_devider;

architecture add_devider of add_devider is

component adder
  port (
       A : in STD_LOGIC_VECTOR(31 downto 0);
       B : in STD_LOGIC_VECTOR(31 downto 0);   
       RESET : in std_logic;
       Q : out STD_LOGIC_VECTOR(31 downto 0)
  );
end component;
component register32
  port (
       CLK : in STD_LOGIC;
       DATA : in STD_LOGIC_VECTOR(31 downto 0);
       Q : out STD_LOGIC_VECTOR(31 downto 0)
  );
end component;

signal regout : STD_LOGIC_VECTOR (31 downto 0);        
signal add2reg : STD_LOGIC_VECTOR (31 downto 0);

begin                            

U1 : adder
  port map(
       A => CONST,
       B => regout,      
       RESET => RESET,
       Q => add2reg
  );

U2 : register32
  port map(
       CLK => CLK_IN,
       DATA => add2reg,
       Q => regout
  );

  CLK_OUT <= regout(31);
  REG_OUT <= regout;
end add_devider;

add_devider_TB.vhd

library ieee;
use ieee.std_logic_1164.all;


entity add_devider_tb is
end add_devider_tb;

architecture TB_ARCHITECTURE of add_devider_tb is
    component add_devider
    port(
        CONST : in std_logic_vector(31 downto 0); 
        RESET : in std_logic;
        CLK_IN : in std_logic;
        CLK_OUT : out std_logic;
        REG_OUT : out STD_LOGIC_VECTOR(31 downto 0));
    end component;


    signal CONST : std_logic_vector(31 downto 0);
    signal CLK_IN : std_logic;
    signal CLK_OUT : std_logic;
    signal RESET : std_logic;
    signal REG_OUT : std_logic_vector(31 downto 0);
begin
    UUT : add_devider
        port map (
            CONST => CONST,    
            RESET => RESET,
            CLK_IN => CLK_IN,
            CLK_OUT => CLK_OUT,
            REG_OUT => REG_OUT
        );

    CONST <= "00100000000000000000000000000000";         
    
    process    --62,5 Mhz
    begin
        clk_in <= '1';
        wait for 8 ns;
        clk_in <= '0';
        wait for 8 ns;
    end process;     
    
    process    --62,5 Mhz
    begin
        RESET <= '1';
        wait for 10 ns;
        RESET <= '0';
        wait for 100 ns;
        RESET <= '1';
        wait for 1 us;

    end process;

end TB_ARCHITECTURE;

configuration TESTBENCH_FOR_add_devider of add_devider_tb is
    for TB_ARCHITECTURE
        for UUT : add_devider
            use entity work.add_devider(add_devider);
        end for;
    end for;
end TESTBENCH_FOR_add_devider;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...