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

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

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

У тебя не хватало библиотек.

Мне кажется, что можно описать это в одном процессе:

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

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

architecture adder_arch of adder is
signal qq : std_logic_vector(31 downto 0);
begin
    process (CLK, A, B, RESET)
    begin
        if(RESET = '0') then
            qq <= (others => '0');
        elsif rising_edge(CLK) then
            qq <= A + B;
        end if;
Q <= qq;
    end process;

end architecture;

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


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

А зачем так подробно всё расписывать?Вот весь делитель.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

entity divider is
    port ( CLK : in std_logic;
        RESET : in std_logic;
        Q : out std_logic
    );
end divider;

architecture div of divider is
constant N : integer := 16;
constant K : std_logic_vector(N-1 downto 0) := KKK;
signal Reg : std_logic_vector(N-1 downto 0);
begin
    process (CLK, RESET)
    begin
        Q <= Reg(N-1);
        if(RESET = '0') then
            Reg <= (others => '0');
        elsif rising_edge(CLK) then
             Reg <= Reg + K;
        end if;
    end process;

end architecture;

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


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

Кстати вот еще нашел интересную статейку :)

UnusualClockDeviders.pdf

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


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

Переделал вышестоящий код, что бы можно было менять частоту, которую необходимо генерировать

 

 library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

entity divider is
    generic (
        N : integer := 16;
        CONSTANT16 : std_logic_vector(7 downto 0) := "00000010"    -- 2 в степени 16 поделить на номинальную частоту
    );
    port ( CLK : in std_logic;
        K : in std_logic_vector(N-1 downto 0);
        RESET : in std_logic;
        Q : out std_logic         
    );
end divider;

architecture div of divider is       

signal Reg : std_logic_vector(N-1 downto 0):=(others => '0'); 
signal KOEF : std_logic_vector(N-1 downto 0); 
signal mulres : std_logic_vector((N+7) downto 0);
begin          
    
       mulres <= K * CONSTANT16;
    KOEF <= mulres(N-1 downto 0);
    
    process (CLK, RESET, KOEF)
    begin          
        if(RESET = '0') then
            Reg <= (others => '0');
        elsif rising_edge(CLK) then
             Reg <= Reg + KOEF;
        end if;
    end process; 
    Q <= Reg(N-1);
    
end architecture;

 

На симуляторе работает все отлично. При синтезисе выдает ошибку: WARNING:Xst:2677 - Node <Reg_0> of sequential type is unconnected in block <divider>. Как я понял это из-за того, что при умножении числа на 2, последний розряд всегда является нулем. Повлияет ли этот варнинг на работу когда дело дойдет до железки?

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


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

 

Нет,если сигнал не изменяется он просто не разводится.

 

К вечеру голова уже не соображает,а зачем нужен CONSTANT16,почему нельзя просто прибавлять К?Просто задавать его таким,какой нужен.

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


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

Просто K в данном случае, это частота в в килогерцах, которую нужно получить. Очень удобно, для моего проекта. Я получаю от модуля управления какую частоту необходимо получить, я её сразу же не преобразовывая передаю в модуль. Надеюсь обьяснил свою мысль, а то сегодня голова тоже не варит особо :)

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


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

Просто K в данном случае, это частота в в килогерцах, которую нужно получить. Очень удобно, для моего проекта. Я получаю от модуля управления какую частоту необходимо получить, я её сразу же не преобразовывая передаю в модуль. Надеюсь обьяснил свою мысль, а то сегодня голова тоже не варит особо :)

 

KOEF <= mulres(N-1 downto 0);

 

На выходе умножителя Вы отбрасываете старшие разряды. (В результате от старшего разряда K ничего не зависит. Разве это правильно?) А надо бы младшие. Иначе зачем умножать.

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


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

K всегда меньше 30000, так как исходная частота 32000. Поэтому старшие разряды K * CONSTANT16 (максимум 60000) всегда будут нули. А отбрасывать пришлось потому что компилятор без этого компилить не хотел.

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


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

K всегда меньше 30000, так как исходная частота 32000. Поэтому старшие разряды K * CONSTANT16 (максимум 60000) всегда будут нули. А отбрасывать пришлось потому что компилятор без этого компилить не хотел.

Если K всегда меньше 30000, то наверно

K : in std_logic_vector(N-2 downto 0);

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

(Наверно параметров должно быть больше, чем один. Но это так к слову)

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


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

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

Вроде.

 

Идея понятна. А не подскажите, как сделать делитель с изменяемой "на лету" выходной частотой? Если делать так же "в лоб", то "константа" перестает быть константой и для ее расчета появляется делитель. А делитель, имхо, это плохо. Джиттер и даже точность не важны в разумных пределах.

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


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

Идея понятна. А не подскажите, как сделать делитель с изменяемой "на лету" выходной частотой? Если делать так же "в лоб", то "константа" перестает быть константой и для ее расчета появляется делитель. А делитель, имхо, это плохо. Джиттер и даже точность не важны в разумных пределах.

 

Если на плате есть процессор,то он должен вычислить нужное значение "константы" и по интерфейсу отправить её в плис.

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


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

Если на плате есть процессор,то он должен вычислить нужное значение "константы" и по интерфейсу отправить её в плис.

 

А если нет, только деление реализовывать? Вообще-то я уже сделал делитель частоты с изменяемыми на лету параметрами. За основу взят целочисленный алгоритм Брезенхема рисования отрезка. Там получается 3 сумматора, причем их разрядность не обязательно 32. Если нам надо из N клоков сделать M, то сумматоры будут разрядности числа N. Это значительно лучше, чем деление 32-разрядных чисел, но хуже чем описанный в этой ветке алгоритм на одном сумматоре. Вот и подумал, что может быть есть способ еще проще, чем Брезенхем?

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


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

Спасибо за информацию о DDS _Anatoliy и Maverick.

Вот аналогичный вашему код DDS на Verilog/

 

 

module dds (clk, reset,clk2); 

parameter    Size = 32;            
parameter   k = 87960934;              

input        clk, reset;;     
output  clk2;


reg [Size-1:0]    accum;        

always @(posedge clk or negedge reset)
begin 
   clk2=accum[Size-1];
   if (!reset) accum <= 0; 
   else  
      accum <= accum + k; 
end 

endmodule

 

Как в коде написать формулу, чтобы вводить в качестве параметра не k, а входную и выходную

частоты?

Изменено пользователем MAXXXX

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


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

Спасибо за информацию о DDS _Anatoliy и Maverick.

Как в коде написать формулу, чтобы вводить в качестве параметра не k, а входную и выходную

частоты?

 

Посмотрите здесь:

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

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


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

 

Да я это видел - те формулу знаю, а как в коде её задать незнаю.

Задавал через параметры - выдает ошибку.

Кстати откуда в формуле k=floor((2^n)*Fout/Fs)+1 появляется +1 ?

Во всех источниках вроде просто k=floor((2^n)*Fout/Fs).

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


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

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

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

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

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

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

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

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

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

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