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

Деление частоты в 50 миллионов раз.

Написал вот такой вот код.

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.

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


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

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

 

integer = signed31 - 32бита, -2147483648.....2147483647

поэтому 50 милионов никак по любому, почему у вас 1048ХХХ вылетает смотреть нужно,

ИМХО причина в этом

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


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

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

 

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

 

Если временные ограничения не выполняются, то делить поэтапно надо. Например сначала на 50, потом на 1e6.

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


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

Помоему код вообще написан неправильно.

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

 

Помоему дело здесь в самом коде.

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


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

переменная count уничтожается по завершении выполнения процесса и создается вновь при каждом входе в процесс по событию на clock.

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

 

Другое дело, что да, переменные лучше не использовать. Можно огрести некоторые глюки. Да и посмотреть их историю можно не всегда. И читаемость кода ниже.

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


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

переменная count уничтожается по завершении выполнения процесса и создается вновь при каждом входе в процесс по событию на clock.

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

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

Другое дело, что да, переменные лучше не использовать. Можно огрести некоторые глюки. Да и посмотреть их историю можно не всегда. И читаемость кода ниже.

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

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


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

Самый простой способ решить вашу задачу - это реализация счетчика с заданным коэффициентом пересчета (можно и управляемым). Однако, как Вы заметили на очень высокой частоте длинный счетчик уже работает медленнее. А здесь есть два выхода:

1. Построить счетчик по так называемой схеме "Hight speed", теорию по которому можно найти в разделе Applications на сайте "xilinx.com";

2. Разбить один счетчик на неколько последовательно включенных, где обнуление (установка) предыдущего является разрешением изменения состояния следующего звена, а быстродействие будет опредляться счетчиком наибольшей разрядности. Естественно, все звенья должны работать на одной тактовой частоте.

 

При реализации первого варианта Вам прийдется потратить дополнительно значительное количество логики, а второй вариант даст лишь конвейерную задержку в N тактов, равную количеству звеньев.

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


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

Des, вы написали range с краями в два миллиарда с копейками. Почему туда 50 миллионов не влазят я не пойму.

Kas, входная частота - 50MHz. На глобальную тактовую цепь - а как это узнать? Временные ограничение - а как это сделать? :) В файле UCF создать такое ограничение? поэтапно - спасибо, так работает. Просто интересовало, почему не работает в один этап.

andrew_b, а как делать арифметические операции с std_logic_vector? (я не издеваюсь - я действительно не знаю. могу догадаться только путем перевода в другой тип туда и обратно постоянно, но где тогда найти эти функции перевода?)

oval, спасибо. буду искать книгу.

genn, спасибо, по второму варианту уже сделал.

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


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

Kas, входная частота - 50MHz. На глобальную тактовую цепь - а как это узнать? Временные ограничение - а как это сделать? :) В файле 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 файле.

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


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

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

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

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


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

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

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

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

 

PS: забыл, бывает, давно это было, всех деталей не упомнишь. Спасибо за поправку.

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


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

To kas:

Маленькая поправочка. Надо проинициализировать driveout1 0-ем или 1-ей.

signal driveout1:std_logic:='0';

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

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


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

To kas:

Маленькая поправочка. Надо проинициализировать driveout1 0-ем или 1-ей.

signal driveout1:std_logic:='0';

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

да. это для меня новость. я не знал, что сигнал может быть интеджером... и это все дело синтезируемое?

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


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

To kas:

Маленькая поправочка. Надо проинициализировать driveout1 0-ем или 1-ей.

signal driveout1:std_logic:='0';

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

Согласен, но для временного моделирования это не критично. А вот поведенческое работать не будет.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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