Цитата(Саша Z @ Dec 2 2007, 12:15)

Есть входной клок с duty cycle 50%. Нужно его грамотно поделить на 3 при сохранении 50% +/- 10% duty cycle. Как сделать ?
Набросав диаграммы на бумажке я прикинул генерация выходного клока может быть:
Подсчитывать кол-во фронтов и спадов входного клока, по каждому второму фронту генерировать фронт выходного клока, по каждому второму спаду - генерировать спад выходного клока.
Но тогда получается что вмешивается комбинаторная логика в схему генерации выходного клока, и это насколько я понял не есть "здоровая" практика.
Подскажите как сделать грамотно ? Вообще, какие есть грамотные пути деления клока в ПЛИСах (кроме наверно встроенных PLLей...)
Спасибо.
Если Вы работает на одном системном клоке, без разницы скважность этого клока. Потому что если это не DDR? работают по переднему фронту. Т.Е образно берется временной интервал в отсчетах этого клока и внужный временной момент делается выборка данных по этому клоку длительностью в один период этого системного клока. такой подход легко ложиться на поведенческое описание. А на выход выдаются только данные, сопровождающиеся clk_en длительностью в один период системного клока.
Подразумевается что следующий модуль тоже работает на системном клоке.
Все чисто и прозрачно. И никакго skew/ потому что этот системный клок идет по специализированному пути. Т.Е его задержка поступления на С входы регистров в любой точке кристалла меньше, чем задержка поступления данных по цепям входов выходов регистров.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity RGB is
port (
DATA_IN : in std_logic_vector(7 downto 0);
XTAL_CLK : in std_logic;
nRST : in std_logic;
DATA_OUT : out std_logic_vector(23 downto 0);
INT_CPU : out std_logic
);
end RGB;
architecture RGB_arch of RGB is
signal cnt : std_logic_vector(1 downto 0);
signal clk_en_a, clk_en_b, clk_en_c : std_logic;
signal rg_a, rg_b : std_logic_vector(7 downto 0);
begin
process(XTAL_CLK)
begin
if XTAL_CLK'event and XTAL_CLK = '1' then
if nRST = '0' then
cnt <= (others => '0');
elsif cnt = "10" then
cnt <= (others => '0');
else
cnt <= cnt + 1;
end if;
if clk_en_a = '1' then
rg_a <= DATA_IN;
end if;
if clk_en_b = '1' then
rg_b <= DATA_IN;
end if;
if clk_en_c = '1' then
DATA_OUT <= DATA_IN & rg_b & rg_a;
end if;
INT_CPU <= clk_en_c;
end if;
end process;
clk_en_a <= '1' when (cnt = "00") else '0';
clk_en_b <= '1' when (cnt = "01") else '0';
clk_en_c <= '1' when (cnt = "10") else '0';
end RGB_arch;