Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Деление частоты в 50 миллионов раз.
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
asya
Написал вот такой вот код.
Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity tst_clk is
   Port ( clock : in std_logic;
          drive : out std_logic);
end tst_clk;

architecture Behavioral of tst_clk is
signal driveout1:std_logic;
begin
drive<=driveout1;
process(clock)
variable count:integer range 0 to 1_000_000:=0;
begin
    if    (clock='1') and (clock'event) then
 count:=count+1;
    end if;
    if count=1_000_000 then
 count:=0;
 driveout1<=not driveout1;
    end if;
end process;  
end Behavioral;

Делаю это для того, чтобы поделить частоту на 50 миллионов. (там написал 1 миллион, потому что проблема - читайте ниже). И вот если я там меняю 1 миллион на большее число (больше 1 048 ХХХ), то не работает. а вот так - работает. (правда слишком высокая частота - мне надо больше поделить. Если пытаюсь увеличить range - то даже так уже не работает. Пытаюсь убрать вообще range (знаю, что нехорошо, но ради теста) - тоже не работает. Пользуюсь Xilinx ISE 6.3 + spartan3.
des00
Цитата(asya @ May 17 2005, 18:14)
Делаю это для того, чтобы поделить частоту на 50 миллионов. (там написал 1 миллион, потому что проблема - читайте ниже). И вот если я там меняю 1 миллион на большее число (больше 1 048 ХХХ), то не работает. а вот так - работает. (правда слишком высокая частота - мне надо больше поделить. Если пытаюсь увеличить range - то даже так уже не работает. Пытаюсь убрать вообще range (знаю, что нехорошо, но ради теста) - тоже не работает. Пользуюсь Xilinx ISE 6.3 + spartan3.
*


integer = signed31 - 32бита, -2147483648.....2147483647
поэтому 50 милионов никак по любому, почему у вас 1048ХХХ вылетает смотреть нужно,
ИМХО причина в этом
kas
Цитата(asya @ May 18 2005, 07:14)
Делаю это для того, чтобы поделить частоту на 50 миллионов. (там написал 1 миллион, потому что проблема - читайте ниже). И вот если я там меняю 1 миллион на большее число (больше 1 048 ХХХ), то не работает. а вот так - работает. (правда слишком высокая частота - мне надо больше поделить. Если пытаюсь увеличить range - то даже так уже не работает. Пытаюсь убрать вообще range (знаю, что нехорошо, но ради теста) - тоже не работает. Пользуюсь Xilinx ISE 6.3 + spartan3.
*


Входная частота какая? Она заведена на глобальную тактовую цепь? Наложите временные ограничения на исходную частоту (PERIOD) - выполняются?

Если временные ограничения не выполняются, то делить поэтапно надо. Например сначала на 50, потом на 1e6.
andrew_b
Нужно отказаться от integer и использовать std_logic_vector.
oval
Помоему код вообще написан неправильно.
Выполнение кода процесса вызывается каждый раз по событию на сигнале clock (следует из списка чувствительности процесса). Каждый раз, как только на clock возникает событие выполняется инициализация переменной count и ей присваивается значение 0. Если событие на clock является передним фронтом, то count увеличивается на 1, то есть приобретает значение 1. Следующее условие count = 1000000 не выполняется никогда, т. к. переменная count уничтожается по завершении выполнения процесса и создается вновь при каждом входе в процесс по событию на clock. Переменной здесь пользоваться бессмысленно, тем более если схему нужно получить в железе. Можно пользоваться shared variable, она действительно подобно сигналу может хранить значение при выходе из процесса, но это несинтезируемая конструкция. Нужно использовать сигнал count. Для меня удивительно, что приведенный код вообще как-то работал.

Помоему дело здесь в самом коде.
andrew_b
Цитата(oval @ May 18 2005, 15:13)
переменная count уничтожается по завершении выполнения процесса и создается вновь при каждом входе в процесс по событию на clock.

Ничего подобного. Переменная существует всегда.

Другое дело, что да, переменные лучше не использовать. Можно огрести некоторые глюки. Да и посмотреть их историю можно не всегда. И читаемость кода ниже.
oval
Цитата(andrew_b @ May 18 2005, 16:06)
Цитата(oval @ May 18 2005, 15:13)
переменная count уничтожается по завершении выполнения процесса и создается вновь при каждом входе в процесс по событию на clock.

Ничего подобного. Переменная существует всегда.

Да, возможно, с точки зрения выделения памяти и других внутренних особенностей системы моделирования она и существует всегда, но с точки зрения VHDL и цикла моделирования она уничтожается и создается вновь. Это очень важный момент, его необходимо четко себе представлять. Советую Peter J. Ashenden "The Designer's Guide to VHDL". Лучше книги не найти. Все профессионалы обращаются к ней.
Цитата
Другое дело, что да, переменные лучше не использовать. Можно огрести некоторые глюки. Да и посмотреть их историю можно не всегда. И читаемость кода ниже.

Переменные можно и нужно использовать, только там, где нужно, и использовать правильно. Никаких некоторых глюков не будет, если четко представляешь себе, что делаешь и понимаешь разницу между сигналом и переменной.
Genn
Самый простой способ решить вашу задачу - это реализация счетчика с заданным коэффициентом пересчета (можно и управляемым). Однако, как Вы заметили на очень высокой частоте длинный счетчик уже работает медленнее. А здесь есть два выхода:
1. Построить счетчик по так называемой схеме "Hight speed", теорию по которому можно найти в разделе Applications на сайте "xilinx.com";
2. Разбить один счетчик на неколько последовательно включенных, где обнуление (установка) предыдущего является разрешением изменения состояния следующего звена, а быстродействие будет опредляться счетчиком наибольшей разрядности. Естественно, все звенья должны работать на одной тактовой частоте.

При реализации первого варианта Вам прийдется потратить дополнительно значительное количество логики, а второй вариант даст лишь конвейерную задержку в N тактов, равную количеству звеньев.
asya
Des, вы написали range с краями в два миллиарда с копейками. Почему туда 50 миллионов не влазят я не пойму.
Kas, входная частота - 50MHz. На глобальную тактовую цепь - а как это узнать? Временные ограничение - а как это сделать? smile.gif В файле UCF создать такое ограничение? поэтапно - спасибо, так работает. Просто интересовало, почему не работает в один этап.
andrew_b, а как делать арифметические операции с std_logic_vector? (я не издеваюсь - я действительно не знаю. могу догадаться только путем перевода в другой тип туда и обратно постоянно, но где тогда найти эти функции перевода?)
oval, спасибо. буду искать книгу.
genn, спасибо, по второму варианту уже сделал.
kas
Цитата(asya @ May 19 2005, 05:24)
Kas, входная частота - 50MHz. На глобальную тактовую цепь - а как это узнать? Временные ограничение - а как это сделать? smile.gif В файле UCF создать такое ограничение? поэтапно - спасибо, так работает. Просто интересовало, почему не работает в один этап.
*


Впринципе частота для этого кристала низкая. Должно все работать.
попробуй так:

Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity tst_clk is
  Port ( clock : in std_logic;
         drive : out std_logic);
end tst_clk;

architecture Behavioral of tst_clk is
signal driveout1:std_logic;
signal count:integer range 0 to 25_000_000-1:=0;
begin
drive<=driveout1;
process(clock)
begin
if (clock='1') and (clock'event) then
 if count=25_000_000-1 then
  count<=0;
  driveout1<=not driveout1;
 else
   count<=count+1;  
 end if;
end if;
end process;  
end Behavioral;


После Place&Route смотри отчет. Там написано какие тактовые сигналы на какие цепи заведены. Если тактовая не заведена на глобальную цепь, то сделай вручную.
Временное ограничение накладывается в UCF файле.
andrew_b
Цитата(oval @ May 18 2005, 18:13)
Да, возможно, с точки зрения выделения памяти и других внутренних особенностей системы моделирования она и существует всегда, но с точки зрения VHDL и цикла моделирования она уничтожается и создается вновь. Это очень важный момент, его необходимо четко себе представлять. Советую Peter J. Ashenden "The Designer's Guide to VHDL". Лучше книги не найти. Все профессионалы обращаются к ней.

А как тогда работают все Xilinx'овы модели компонентов BlockRAM и основанных на них (FIFO, etc)? Содержимое памяти --- это динамический список, переменные, его описывающие (не shared), декларированы в процессе.
oval
Цитата(andrew_b @ May 19 2005, 09:44)
Цитата(oval @ May 18 2005, 18:13)
Да, возможно, с точки зрения выделения памяти и других внутренних особенностей системы моделирования она и существует всегда, но с точки зрения VHDL и цикла моделирования она уничтожается и создается вновь. Это очень важный момент, его необходимо четко себе представлять. Советую Peter J. Ashenden "The Designer's Guide to VHDL". Лучше книги не найти. Все профессионалы обращаются к ней.

А как тогда работают все Xilinx'овы модели компонентов BlockRAM и основанных на них (FIFO, etc)? Содержимое памяти --- это динамический список, переменные, его описывающие (не shared), декларированы в процессе.
*


Вы правы. Я специально проверил (написал тест). Действительно, присвоение начального значения переменной происходит только в цикле инициализации моделирования. Историю присвоения значений переменной нельзя посмотреть, т. к. эти присвоения происходят последовательно в одно и то же модельное время. Но для описания синтезируемых моделей я бы не рекомендовал стиль описания с использованием переменных таким образом. Типовые шаблоны описания схем обычно всегда приводятся в документации к средствам синтеза. Я бы придерживался их.

PS: забыл, бывает, давно это было, всех деталей не упомнишь. Спасибо за поправку.
Alexandr
To kas:
Маленькая поправочка. Надо проинициализировать driveout1 0-ем или 1-ей.
Код
signal driveout1:std_logic:='0';

А в остальном код работоспособен, глюков быть не должно.
asya
Цитата(Alexandr @ May 19 2005, 16:22)
To kas:
Маленькая поправочка. Надо проинициализировать driveout1 0-ем или 1-ей.
Код
signal driveout1:std_logic:='0';

А в остальном код работоспособен, глюков быть не должно.
*

да. это для меня новость. я не знал, что сигнал может быть интеджером... и это все дело синтезируемое?
kas
Цитата(Alexandr @ May 19 2005, 20:22)
To kas:
Маленькая поправочка. Надо проинициализировать driveout1 0-ем или 1-ей.
Код
signal driveout1:std_logic:='0';

А в остальном код работоспособен, глюков быть не должно.
*

Согласен, но для временного моделирования это не критично. А вот поведенческое работать не будет.
kas
Цитата(asya @ May 20 2005, 06:02)
да. это для меня новость. я не знал, что сигнал может быть интеджером... и это все дело синтезируемое?
*

А то... Даже в реальных проектах пашет на ура.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.