Я пока слабо представляю, что это за 580ВМ80 такой 64-хбитный :)
В реале они как-то попроще будут...
И как ты его собираешься реализовывать?
Вид для печати
Я пока слабо представляю, что это за 580ВМ80 такой 64-хбитный :)
В реале они как-то попроще будут...
И как ты его собираешься реализовывать?
Частотомер на ПЛИС?
Для такой задачи более подходят микроконтроллеры...
Не знаю, надо что-то другое...
---------- Post added at 22:07 ---------- Previous post was at 21:58 ----------
Вот тебе задачка, "близкая к реальности".
Имеем входящий клок 20МГц.
Нужно синтезировать два синхросигнала, горизонтальной и вертикальной развертки VGA.
Вот тебе картинка с времянками сигнала:
http://savepic.org/6206519.png
Калькулятор виндовый тебе в помощь! Все решается прекрасно с его помощью :)
Как всегда, я выложу свой вариант сюда под спойлер.
Скрытый текст
Код:library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_unsigned.ALL;
entity divider is
port(
CLK : in std_logic;
H_SYNC : out std_logic;
V_SYNC : out std_logic
);
end divider;
architecture syn of divider is
signal vcnt : std_logic_vector(9 downto 0);
signal hcnt : std_logic_vector(9 downto 0);
begin
process(CLK)
begin
if rising_edge(CLK) then
if (hcnt(9 downto 7)="101") then -- 640 точек дают 32мкс на частоте 20МГц
hcnt <= "0000000000";
if (vcnt="1000001100") then -- 524 строчки. 524*32мкс=16768мкс, что примерно 16,77мс.
vcnt <= "0000000000";
else
vcnt <= vcnt+1;
end if;
else
hcnt <= hcnt+1;
end if;
if (hcnt=520) then
H_SYNC <= '0';
elsif (hcnt=600) then
H_SYNC <= '1';
end if;
if (vcnt=490) then
V_SYNC <= '0';
elsif (vcnt=493) then
V_SYNC <= '1';
end if;
end if;
end process;
end syn;
[свернуть]
http://savepic.org/6193220.png
---------- Post added at 22:55 ---------- Previous post was at 22:07 ----------
Я свой код выложил под спойлер. Диаграмма прилагается, времянки там соответствуют требуемым (плюс/минус чуть-чуть, допускается).
---------- Post added at 23:21 ---------- Previous post was at 22:55 ----------
Добавил немножко кода, чтобы проверить проект "вживую".
http://savepic.org/6222941.jpg
---------- Post added at 23:34 ---------- Previous post was at 23:21 ----------
http://savepic.org/6162527.jpg
Для начала тебе нужны два счетчика, горизонтальный и вертикальный.
Горизонтальный должен считать такты на всю строку, включая синхро и гашение.
Полный такт - 31,77мкс (32 округленно).
20МГц = 0,00000005 сек/точку. = 0,05мкс/точку.
Нам нужно 32мкс на строку.
Значит, точек в строке нужно 32/0,05=640.
Делаем счетчик до 640, чтобы потом сбрасывался в ноль.
Вертикальный счетчик. 16784мкс на один фрейм. Строчка занимает 32 мкс.
Итого - 16784/32=524 строчки. Лепим счетчик на 524.
Счетчики тикают, по клоку увеличивается горизонтальный, по сбросу горизонтального в ноль - увеличивается вертикальный.
А тем временем проверяется содержимое счетчиков и в нужные моменты дергаем сигналы синхронизации вниз-вверх. Вот и вся кухня.
Не, никуда не годится...
Наверное надо было начать со счетчиков вообще, а не со сразу непонятной задачи.
Давай разобьем на этапы.
Как сделать счетчик, например, до 260?
Сколько разрядов счетчика нам потребуется, чтобы досчитать до этого числа?
Помним, что байт (8 бит) вмещает в себя максимум 256 комбинаций.
Следовательно, чтобы считать в диапазоне выше 256 импульсов, нужно добавить еще один разряд. Теперь мы сможем считать до 511, а количество состояний счетчика - 512.
Объявляем сигнал - signal counter: std_logic_vector(8 downto 0);
После объявления типа std_logic_vector мы пишем количество двоичных разрядов сигнала (счетчика, шины, регистра...) и их логическое размещение.
Здесь могут быть два варианта - 8 downto 0 и 0 upto 8.
Первый вариант означает, что левым (старшим) разрядом при операциях с сигналом будет старший бит. Так оно обычно всегда и делается, это просто логично. Ведь нулевой разряд у нас всегда находится справа (младший). Но для особых случаев можно воспользоваться и вторым вариантом, развернув байт.
Далее...
Как нам сделать, чтобы счетчик, дотикав до нужного числа, сбросился и начал отсчет снова?
На рассыпной логике для этой цели к счетчикам типа ИЕ5/ИЕ7 добавляют мелкологику. Здесь происходит аналогично.
Логика постоянно мониторит состояние битов счетчика и по совпадению с заданным числом дает сигнал сброса на счетчик.
Для нашего случая можно сделать например так, чтобы сброс был на 260:
А если нам нужно, как в случае с синхросигналами, запустить последовательно два счетчика?Код:process(CLK)
if (rising_edge(CLK)) then --всё должно быть синхронно!
if (counter=259) then --нужная цифра минус один, ведь 0 - тоже входит в счет
counter <= "000000000"; --в данном случае кактус не любит десятичные числа
else
counter <= counter + 1;
end if;
end if;
end process;
Чуть-чуть напрягаем мозг, и соображаем, что конструкцию второго счетчика проще всего воткнуть прямо в тот же процесс, где сидит и первый. Ведь там уже есть готовый момент, когда первый счетчик уходит в ноль? Да, это строчка counter <= "000000000";
Поэтому прямо под ней мы может вкошачить второй счетчик. Во второй - третий, и так до бесконечности :)
Давай, второй счетчик у нас будет до... 33, например.
Считаем необходимую разрядность - 6. Значит, нужны разряды от 0 до 5.
Описываем сигнал и - поехали...
Код:process(CLK)
if (rising_edge(CLK)) then
if (counter=259) then
counter <= "000000000";
if (counter1=33) then
counter1 <= "000000";
else
counter1 <= counter1 + 1;
end if;
else
counter <= counter + 1;
end if;
end if;
end process;
---------- Post added at 09:28 ---------- Previous post was at 09:04 ----------
А как нам определить, когда счетчик достиг нужного значения, чтобы соответствующим образом отреагировать? Просто смотрим, сколько он там насчитал, состояние счетчика всегда доступно.
Но и тут есть нюанс. ПЛИС - быстра, но и в ней после каждого импульса разряды устаканиваются не моментально. Если просто сделать типа
А <= '1' when (counter=100) else '0';
то возможно появление "иголок" в сигнале А.
Тут можно использовать принцип, что к следующему сигналу клока все разряды счетчика уже успокоились и показывают правильное значение.
Поэтому можно или создать регистр, разрядностью равный счетчику, и по фронту клока записывать в него текущее состояние счетчика. Тогда можно обычной логикой следить за состоянием счета.
Или можно смотреть счет в процессе, который тактируется тем же клоком, что и счетчик.
Вот один из вариантов. Можно делать это немножко по разному.Код:process(CLK)
if (rising_edge(CLK)) then
if (counter=259) then
counter <= "000000000";
else
counter <= counter + 1;
end if;
if (counter=100) then
A <= '1';
else
A <= '0';
end if;
end if;
end process;
---------- Post added at 09:35 ---------- Previous post was at 09:28 ----------
потому что время между кадровыми синхроимпульсами равно 16,784мс по документации. А обеспечить это время мы можем только количеством строк. Каждая строка выводится на экран монитора за 32 микросекунды.
И если мы выведем 524 строки по 32мкс каждая, то мы и получим эти несчастные 16,7миллисекунд на один фрейм (экран).
Допустимо оба варианта.
---------- Post added at 13:20 ---------- Previous post was at 13:17 ----------
Да, но не сейчас, пускай в голове пока оседает необходимый минимум.
И у меня, например, привычка обходиться без others, поскольку иногда требуется какой-либо битик поднять.
Но это дело сугубо личное :)
---------- Post added at 13:23 ---------- Previous post was at 13:20 ----------
Просто может быть непривычно, что сравнивать значения в многоразрядных сигналах можно с десятичными цифрами, а вот присваивать - ни в коем разе.
---------- Post added at 13:28 ---------- Previous post was at 13:23 ----------
Это выражение означает, что всем разрядам присваивается '0'.
По сути это тоже самое, и даже выглядит солидней. Но это - дело вкуса.
Да, классическая 24.5 или 25 вроде, на материнках можно увидеть старых.
Ничего страшного нет. Тем более, у нас учебный пример, который тем не менее работает :)
Да, конечно только один такт.
А кто тебе мешает вместо else написать elsif и написать второе условие для отключения?
1. Именно FPGA? Самый маленький - EP1C3T100C8. Не, 155ТМ8 туда не влезет... Но туда влезает Орион-128 с парой десятков корпусов, с процессором Z80, горой еще всякого разного и чуть-чуть не умещается AY-2910 поверх всей этой кучи....... :)
2. Дребезг устраняется программно, самим кодом в ПЛИС. Ну или лепи переключающие кнопки с триггерами, дабы делать это внешне. Проще, наверное, микроконтроллер снаружи прикрутить, чтобы он дребезг устранял. Хотя... Это снова код писать, теперь уже для МК :)
---------- Post added at 23:24 ---------- Previous post was at 23:20 ----------
Кстати, напиши тренировки ради код антидребезга для ПЛИС.
Алгоритм, например, такой - процесс, тактируемый клоком. В нем слушаем входной пин. Как только уровень изменился, по клоку начинает расти счетчик. Если сигнал на входе пропал - счетчик обнуляется. Если же он набрал десятка три импульсов - считать, что кнопа нажата выдачей соответствующего сигнала.
Вот и вся премудрость :)
MVV, я уже неделю из-под девборды не вылезаю :)
Viktor2312, для нее потребуется генератор, конфпзу не меньше EPCS1, стабилизаторы линейные на 3,3 и 1,5 вольт. Ну и разъем для бластера. Это минимум для работы.
У меня такая платка с этим циклоном размером со спичечный коробок. Макетку купи, TQFP-0,5 х 100.
---------- Post added at 23:58 ---------- Previous post was at 23:56 ----------
MVV, не делай вид, что ты не читал названия темы :)
ну хочет человек на плисе собрать то, что делается на МК за полбакса... Не мешай ему :)