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

VHDL счетчик с ответвлениями

Пытаюсь всунуть цепочку VHDL счетчиков в один процесс. Вроде должно работать. Но... работает только последнее ответвление.

Общий счетчик считает на 420 - 28*3*5 Нужны ответвления на 28, 84 в виде импульсов длительностью в период тактовой частоты.

process (s_rclk, clk)

begin
    if s_rclk = '0' then
        s_cntdiv <= (others => '0');
        s_rs_cntdiv28 <= '1';
        s_rs_cntdiv3 <= '1';
        s_rs_cntdiv5 <= '1';
    elsif clk'event and clk = '0' then
        if s_rs_cntdiv5 = '0' then
            s_cntdiv <= (others => '0');
        else    
            s_cntdiv <= s_cntdiv + 1;
        end if;
        if s_cntdiv =  conv_std_logic_vector(27,16) then
            s_rs_cntdiv28 <= '0';
        elsif s_cntdiv =  conv_std_logic_vector(28,16) then
            s_rs_cntdiv28 <= '1';
        elsif s_cntdiv =  conv_std_logic_vector(83,16) then
            s_rs_cntdiv3 <= '0';
        elsif s_cntdiv =  conv_std_logic_vector(84,16) then
            s_rs_cntdiv3 <= '1';
        elsif s_cntdiv =  conv_std_logic_vector(420,16) then
            s_rs_cntdiv5 <= '0';
        else
            s_rs_cntdiv5 <= '1';
        end if;
    end if;

end process;

 

Подскажите пожалуйста где неверно.

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


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

Пытаюсь всунуть цепочку VHDL счетчиков в один процесс. Вроде должно работать. Но... работает только последнее ответвление.

Общий счетчик считает на 420 - 28*3*5 Нужны ответвления на 28, 84 в виде импульсов длительностью в период тактовой частоты.

process (s_rclk, clk)

begin
    if s_rclk = '0' then
        s_cntdiv <= (others => '0');
        s_rs_cntdiv28 <= '1';
        s_rs_cntdiv3 <= '1';
        s_rs_cntdiv5 <= '1';
    elsif clk'event and clk = '0' then
        if s_rs_cntdiv5 = '0' then
            s_cntdiv <= (others => '0');
        else    
            s_cntdiv <= s_cntdiv + 1;
        end if;
        if s_cntdiv =  conv_std_logic_vector(27,16) then
            s_rs_cntdiv28 <= '0';
        elsif s_cntdiv =  conv_std_logic_vector(28,16) then
            s_rs_cntdiv28 <= '1';
        elsif s_cntdiv =  conv_std_logic_vector(83,16) then
            s_rs_cntdiv3 <= '0';
        elsif s_cntdiv =  conv_std_logic_vector(84,16) then
            s_rs_cntdiv3 <= '1';
        elsif s_cntdiv =  conv_std_logic_vector(420,16) then
            s_rs_cntdiv5 <= '0';
        else
            s_rs_cntdiv5 <= '1';
        end if;
    end if;

end process;

 

Подскажите пожалуйста где неверно.

я бы вот так написал

 

process (s_rclk, clk)

 

begin

if s_rclk = '0' then

s_cntdiv <= conv_std_logic_vector(92,16); -- 92=512-420

s_rs_cntdiv28 <= '1';

s_rs_cntdiv3 <= '1';

elsif clk'event and clk = '0' then

if s_cntdiv (9)= '1' then --счетчик досчитал до 512

s_cntdiv <= conv_std_logic_vector(92,16);

else

s_cntdiv <= s_cntdiv + 1;

end if;

if s_cntdiv = conv_std_logic_vector(120,16) then --28+92

s_rs_cntdiv28 <= '1';

elsif s_cntdiv = conv_std_logic_vector(176,16) then –84+92

s_rs_cntdiv3 <= '1';

else

s_rs_cntdiv3 <= '0';

s_rs_cntdiv28 <= '0';

end if;

end if;

 

end process;

после ресета в счетчик пишется не 0 а 512-420. так проще определять момент, когда счетчик досчитал до 420. проверять нужнл только 1 бит. Да, я не моделировал. Возможно, где-то надо немного подвигать плюс минус 1

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

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


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

Спасибо. Ваша мысль понятна. Но... выдает только последние переносы, как и мой.

Тестирую на встроенном симуляторе Quartus 9. Вроде не подводит ( Пока во всяком случае).

Если не сложно пропустите пожалуйста через свой симулятор.

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


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

Спасибо. Ваша мысль понятна. Но... выдает только последние переносы, как и мой.

Тестирую на встроенном симуляторе Quartus 9. Вроде не подводит ( Пока во всяком случае).

Если не сложно пропустите пожалуйста через свой симулятор.

Попробуйте вместо if s_cntdiv = conv_std_logic_vector(120,16) then написать if s_cntdiv = x"0078" then. Это если s_cntdiv: (15 downto 0)

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


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

Попробуйте вместо if s_cntdiv = conv_std_logic_vector(120,16) then написать if s_cntdiv = x"0078" then. Это если s_cntdiv: (15 downto 0)

 

Пробовал. Формально это то же самое.

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


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

Сколько не пытался в квартусе оперировать конструкциями conv_std_logic_vector(), так и не получилось. Пришел к "внутреннему" соглашению делать через unsigned

process(clk)
variable cnt_v:unsigned(8 downto 0):="000000000";
constant step:unsigned(8 downto 0):="000000001";
variable s1,s2:std_logic:='0';
constant a:unsigned(8 downto 0):="000011000";--24
constant b:unsigned(8 downto 0):="001010100";--84
constant max:unsigned(8 downto 0):="110100100";--420
constant zero:unsigned(8 downto 0):="000000000";
begin
if(rising_edge(clk))then
cnt_v:=cnt_v+step;
if(cnt_v=a)then
s1:='1';
elsif(cnt_v=b)then
s2:='1';
elsif(cnt_v=max)then
cnt_v:=zero;
else
s1:='0';
s2:='0';
end if;
--тут можно вывести переменные s1, s2 во внешний мир
end if;
end process;

Сброс не стал писать. Попробуйте - может квартус так лучше поймет.

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


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

Пытаюсь всунуть цепочку VHDL счетчиков в один процесс.

Подскажите пожалуйста где неверно.

Я вообще делаю такие вещи не так.

Когда производится сравнивание с несколькими константами, то это жрет приличный ресурс и понижает быстродействие. А потому я делаю загружаемый таймер, который считает от загруженного кода до нуля. И к нему еще делаю автомат, который получает сигнал готовности от таймера и загружает таймер новым кодом ддля счета. И поскольку таймер делает для каждого интервала отдельно, то он получается меньшей разрядности, чем "один большой счетчик"...

Таймер делаете параметризируемым и пользуетесь им всю жизнь, как библиотечным компонентом...

Примеры на верилоге у меня на сайте, в статьях - "Краткий Курс"...

 

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


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

Я вообще делаю такие вещи не так.

Когда производится сравнивание с несколькими константами, то это жрет приличный ресурс и понижает быстродействие. А потому я делаю загружаемый таймер, который считает от загруженного кода до нуля. И к нему еще делаю автомат, который получает сигнал готовности от таймера и загружает таймер новым кодом ддля счета. И поскольку таймер делает для каждого интервала отдельно, то он получается меньшей разрядности, чем "один большой счетчик"...

Таймер делаете параметризируемым и пользуетесь им всю жизнь, как библиотечным компонентом...

Примеры на верилоге у меня на сайте, в статьях - "Краткий Курс"...

Не совсем понятно. То есть в данной задаче Вы сначала будете считать от 0 до 28 (минимум 5-и битный счетчик, но сравнивать с 5-и битной константой, либо 6-и битный и провярять старший бит), затем от 28 до 84 это еще 6-и битный счетчик, затем от 84 до 420 это еще 9 бит. И того минимум 20 разрядов на счетчики. В чем выигрыш?

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


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

Можно обойись одним 5 разрядным, а им уже отсчитывать 84 это счет до трех, затем уже до 420 - до 15. Выигрыш только в том что сравнивать в "старшем" счетчике.

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


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

Можно обойись одним 5 разрядным, а им уже отсчитывать 84 это счет до трех, затем уже до 420 - до 15. Но по моему выигрыша не будет - 9 бит хоть убейся..

Уверен, что не будет. Если нужно в сумме досчитать до 420, то 9 бит как не крути. Но я в таких случаях, делаю как в примере. Добавляю 1 бит к счетчику. По ресету пишу туда не 0, а в данном случае 512-420 = 92, и в этом случае мне не нужно сравнивать 9-и битный счетчик с 9-и битной константой. Нужно тестировать только старший бит.

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


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

По ресету пишу туда не 0, а в данном случае 512-420 = 92, и в этом случае мне не нужно сравнивать 9-и битный счетчик с 9-и битной константой. Нужно тестировать только старший бит.

Хорошо когда одна константа, а когда их несколько и они кратны "некоему значению", метод предложенный iosifk, может дать лучший выход, но при кратности

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


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

Хорошо когда одна константа, а когда их несколько и они кратны "некоему значению", метод предложенный iosifk, может дать лучший выход, но при кратности

В этом случае можно также добавлять по 1 биту к каждому счетчику. Суть тажа.

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

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


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

Я вообще делаю такие вещи не так.

Когда производится сравнивание с несколькими константами, то это жрет приличный ресурс и понижает быстродействие. А потому я делаю загружаемый таймер, который считает от загруженного кода до нуля. И к нему еще делаю автомат, который получает сигнал готовности от таймера и загружает таймер новым кодом ддля счета. И поскольку таймер делает для каждого интервала отдельно, то он получается меньшей разрядности, чем "один большой счетчик"...

Таймер делаете параметризируемым и пользуетесь им всю жизнь, как библиотечным компонентом...

Примеры на верилоге у меня на сайте, в статьях - "Краткий Курс"...

Да, так мы делали давно на дискретных элементах.

В данном случае позвольте не согласиться.

Конечно же выгоднее длинный счетчик с отводами, что-то вроде централи времени.

Нет там констант. Просто комбинационные схемы на каждый отвод.

Пскольку компилятор немного смыслит в картах карно то часто получается неплохо.

В моем частном случае кажется глючит симулятор. Раньше не замечал. Проекты были не на циклонах. Очевидно это для симулятора тоже имеет значение.

Кроме того думаю что счет нужно вести по одному фронту клока, а компараторы должны работать по другому фронту и в другом процессе. Надо проверить...

Хотя про таймер спасибо. Надо попробовать.

 

Алдек говорит что все хорошо.

Спасибо.

Это изначальный код?

 

Уверен, что не будет. Если нужно в сумме досчитать до 420, то 9 бит как не крути. Но я в таких случаях, делаю как в примере. Добавляю 1 бит к счетчику. По ресету пишу туда не 0, а в данном случае 512-420 = 92, и в этом случае мне не нужно сравнивать 9-и битный счетчик с 9-и битной константой. Нужно тестировать только старший бит.

Нет там констант.

Так тоже неплохо (один бит контролировать). Но симулятор не хочет ничего показывать...

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

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


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

Кроме того думаю что счет нужно вести по одному фронту клока, а компараторы должны работать по другому фронту и в другом процессе. Надо проверить...

Зачем разные фронты? Ваша задача тривиальная. Зачем ее усложнять? Добавление другого фронта не упростит задачу, а усложнит.

 

Нет там констант.

Если Вы пишите if aa = x"bb" then ... то это сравнение сигнала aa с константой x"bb"

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


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

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

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

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

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

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

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

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

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

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