реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Closed TopicStart new topic
> Устройство мигания светодиодов (VHDL)
lyzifer
сообщение Jul 13 2017, 11:52
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 13-07-17
Пользователь №: 98 133



Устройство моргания 4-мя светодиодами.По сути,программа очень простая.Но у меня в итоге светодиоды "бегают" (т.е. загорелся первый,потом сразу же следующий с частотой 1 Гц).А мне нужно чтобы диод загорелся,потух,а только потом,через 1 с, следующий. Заранее благодарен.
вот реализация и временная диаграмма:

Код
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity LED is
port( CLK : in std_logic;
L_D : out std_logic_vector(3 downto 0)); -- поправил у меня 4 светодиода подключены
end LED;

architecture A_LED of LED is
signal counter : std_logic_vector(20 downto 0):= (others => '0');
signal LED_temp : std_logic_vector(3 downto 0) := (0 => '1',others =>'0'); -- поправил на 4 светодиода
signal res : std_logic := '0';
begin
count : process(CLK,res)
begin
if(res = '1') then
counter <= (others => '0');
elsif(rising_edge(CLK)) then
counter <= counter +1;
end if;
end process;

L : process(counter)
begin
if(counter = 2000000) then
res <= '1';
LED_temp <= LED_temp(2 downto 0) & LED_temp(3);
-- вращаю выходной вектор по кругу налево, постоянно смещая на 1 разряд
else
res <= '0';
end if;
end process;

L_D <= led_temp; -- выдаю информацию из регистров в порт

end A_LED;


На выходе получаю



а надо:




Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jul 13 2017, 11:58
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 3 604
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(lyzifer @ Jul 13 2017, 14:52) *
Устройство моргания 4-мя светодиодами.По сути,программа очень простая.Но у меня в итоге светодиоды "бегают" (т.е. загорелся первый,потом сразу же следующий с частотой 1 Гц).А мне нужно чтобы диод загорелся,потух,а только потом,через 1 с, следующий. Заранее благодарен.

Это значит, что нужна пауза, когда все светодиоды будут выключены... Ну так и сделайте ее... Например к Вашему коду можно добавить сигнал блокировки, который будет срабатывть по переднему фронту импульсов на светодиоды и будет их выключать на требуемое время...
Ну а можно сделать еще проще. Автомат и таймер. Могу рассказать по скайпу...
Удачи!


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
lyzifer
сообщение Jul 13 2017, 12:02
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 13-07-17
Пользователь №: 98 133



Цитата(iosifk @ Jul 13 2017, 14:58) *
Это значит, что нужна пауза, когда все светодиоды будут выключены... Ну так и сделайте ее... Например к Вашему коду можно добавить сигнал блокировки, который будет срабатывть по переднему фронту импульсов на светодиоды и будет их выключать на требуемое время...

хм..это не плохой вариант.но я новичок в VHDL (т.е. тупой). не могли бы написать,как должен выглядеть этот кусок кода??буду очень благодарен
Go to the top of the page
 
+Quote Post
Tausinov
сообщение Jul 13 2017, 13:51
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 112
Регистрация: 19-10-13
Пользователь №: 78 795



Ввести дополнительный сигнал
signal phase : std_logic;

По каждому превышению счетчиком порога делать
phase <= not(phase);
И соответственно сдвигать регистр LED_temp только при нуле или при единице.

А дальше останется 1 if добавить.

if (phase = '0') then
LD <= (others => '0');
else
LD <= LED_temp;
end if;
Go to the top of the page
 
+Quote Post
lyzifer
сообщение Jul 13 2017, 14:32
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 13-07-17
Пользователь №: 98 133



Цитата(Tausinov @ Jul 13 2017, 16:51) *
Ввести дополнительный сигнал
signal phase : std_logic;

По каждому превышению счетчиком порога делать
phase <= not(phase);
И соответственно сдвигать регистр LED_temp только при нуле или при единице.

А дальше останется 1 if добавить.

if (phase = '0') then
LD <= (others => '0');
else
LD <= LED_temp;
end if;


Блин,видимо я не оч догоняю,как правильно добавить в код...((ошибку выдаёт на выходе при моделировании...
Покажи,плиииииз, как правильно.заранее благодарен!!
Код
signal counter : std_logic_vector(22 downto 0):= (others => '0');
signal LED_temp : std_logic_vector(3 downto 0) := (0 => '1',others =>'0');
signal res : std_logic := '0';
signal phase : std_logic;
begin
  count : process(CLK,res)
  begin
    if(res = '1') then
      counter <= (others => '0');
    elsif(rising_edge(CLK)) then
      counter <= (counter + 1);
    end if;
  end process;
L : process(counter)
  begin
    if(counter = 5000000) then
      res <= '1';
    LED_temp <= LED_temp(2 downto 0) & LED_temp(3);
    phase <= not(phase);
   else
      res <= '0';
    end if;
  end process;
  
G: process (phase)
begin
if (phase = '0') then
L_D <= (others => '0');
else
L_D <= LED_temp;
end if;
end process;

L_D <= led_temp; --  сигнал из регистров в порт
end A_LED;
Go to the top of the page
 
+Quote Post
Tausinov
сообщение Jul 13 2017, 15:18
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 112
Регистрация: 19-10-13
Пользователь №: 78 795



Цитата(lyzifer @ Jul 13 2017, 17:32) *
Блин,видимо я не оч догоняю,как правильно добавить в код...((ошибку выдаёт на выходе при моделировании...
Покажи,плиииииз, как правильно.заранее благодарен!!


Код
signal res      : std_logic                     := '0';
signal phase    : std_logic                     := '0';
signal LED_temp : std_logic_vector( 3 downto 0) := (0 => '1', others =>'0');
signal counter  : std_logic_vector(22 downto 0) := (others => '0');

begin
  count : process(CLK, res)
  begin
    if(res = '1') then
      counter <= (others => '0');
    elsif(rising_edge(CLK)) then
      counter <= (counter + 1);
    end if;
  end process;

  L : process(counter)
  begin
    if(counter = 5000000) then
      phase <= not(phase);

      if (phase = '1') then
        res <= '1';
        LED_temp <= LED_temp(2 downto 0) & LED_temp(3);
      else
        res <= '0';
      end if;
    else
      res <= '0';
    end if;
  end process;
  
  G: process(phase)
  begin
    if (phase = '0') then
      L_D <= (others => '0');
    else
      L_D <= LED_temp;
    end if;
  end process;
  
end A_LED;


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

Сообщение отредактировал Tausinov - Jul 13 2017, 15:28
Go to the top of the page
 
+Quote Post
lyzifer
сообщение Jul 13 2017, 15:32
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 13-07-17
Пользователь №: 98 133



Цитата(Tausinov @ Jul 13 2017, 18:18) *

Всеравно ошибка на выходе.но спосибо за попытку помочь))

Go to the top of the page
 
+Quote Post
Tausinov
сообщение Jul 13 2017, 15:58
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 112
Регистрация: 19-10-13
Пользователь №: 78 795



Дизайн:
Код
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.numeric_std.all;

entity test_led is
  generic (
    p_TD      : time    := 1 ns;
    p_CNT_LIM : integer := 32768 - 1
  );
  port (
    clk : in  std_logic;
    led : out std_logic_vector(3 downto 0)
  );
end test_led;

architecture rtl of test_led is
  signal div_cnt_u : unsigned(31 downto 0)        := (others => '0');

  signal phase     : std_logic                    := '1';
  signal led_reg   : std_logic_vector(3 downto 0) := (0 => '1', others => '0');
begin

  counter_control_p : process(clk)
  begin
    if (rising_edge(clk)) then
      if (div_cnt_u < p_CNT_LIM) then
        div_cnt_u <= div_cnt_u + 1 after p_TD;
      else
        div_cnt_u <= (others => '0');
      end if;
    else
      NULL;
    end if;
  end process;

  phase_control_p : process(clk)
  begin
    if (rising_edge(clk)) then
      if (div_cnt_u = p_CNT_LIM) then
        phase <= not(phase) after p_TD;
      else
        NULL;
      end if;
    else
      NULL;
    end if;
  end process; --phase_control_p

  led_reg_control_p : process(clk)
  begin
    if (rising_edge(clk)) then
      if (div_cnt_u = p_CNT_LIM) then
        if (phase = '1') then
          led_reg <= led_reg(2 downto 0) & led_reg(3) after p_TD;
        else
          NULL;
        end if;
      else
        NULL;
      end if;
    else
      NULL;
    end if;
  end process; --led_reg_control_p

  out_form_logic_p : process(phase)
  begin
    if (phase = '0') then
      led <= (others => '0');
    else
      led <= led_reg;
    end if;
  end process; --out_form_logic_p

end rtl;


Тестбенч:
Код
library ieee;
   use ieee.std_logic_1164.all;

entity test_led_tb is
   generic (
      p_TD    : time := 1 ns;
      p_CLK_T : time := 4 ns
   );
end test_led_tb;

architecture behav of test_led_tb is
   signal clk : std_logic                    := '0';
   signal led : std_logic_vector(3 downto 0);

   component test_led is
     generic (
       p_TD      : time    := 1 ns;
       p_CNT_LIM : integer := 32768 - 1
     );
     port (
       clk : in  std_logic;
       led : out std_logic_vector(3 downto 0)
     );
   end component;
begin
   clk_gen_p : process
   begin
      clk <= not(clk);
      wait for p_CLK_T / 2;
   end process;

   UUT : test_led
      generic map (
         p_TD => p_TD
      )
      port map (
         clk => clk,
         led => led
      );
end behav;


Go to the top of the page
 
+Quote Post
Stewart Little
сообщение Jul 13 2017, 16:17
Сообщение #9


Лентяй
******

Группа: Свой
Сообщений: 2 117
Регистрация: 11-10-04
Из: Санкт-Петербург
Пользователь №: 843



Цитата(lyzifer @ Jul 13 2017, 14:52) *
А мне нужно чтобы диод загорелся,потух,а только потом,через 1 с, следующий.

Коллеги каких-то сложностей насоветовали...
А нельзя ли просто увеличить разрядность сдвигового регистра в два раза, а светодиоды поджигать только четными (или только нечетными) разрядами?


--------------------
Чтобы слова не расходились с делом, нужно молчать и ничего не делать...
Go to the top of the page
 
+Quote Post
Tausinov
сообщение Jul 13 2017, 16:26
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 112
Регистрация: 19-10-13
Пользователь №: 78 795



Цитата(Stewart Little @ Jul 13 2017, 19:17) *
Коллеги каких-то сложностей насоветовали...
А нельзя ли просто увеличить разрядность сдвигового регистра в два раза, а светодиоды поджигать только четными (или только нечетными) разрядами?


Можно, красивый вариант. Просто, если потом захочется чего-то более необычного, то, имхо, проще будет поправить текущий вариант, чем переделывать узко заточенный.
Go to the top of the page
 
+Quote Post
lyzifer
сообщение Jul 13 2017, 18:23
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 13-07-17
Пользователь №: 98 133



Цитата(Tausinov @ Jul 13 2017, 18:58) *


оу))не ожидал,что вы мне ещё напишите))большое спасибо за интерес к моей проблеме))жаль,что только завтра утром смогу проверить работоспособность проги. rolleyes.gif

Сообщение отредактировал lyzifer - Jul 13 2017, 18:23
Go to the top of the page
 
+Quote Post
Maverick
сообщение Jul 13 2017, 18:37
Сообщение #12


я только учусь...
******

Группа: Модераторы
Сообщений: 3 366
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



lyzifer, это не программа, а описание цифровой схемы - посмотреть можно в RTL viewer


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
AVR
сообщение Jul 14 2017, 06:24
Сообщение #13


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 055
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Вопрос автору темы: обязательно ли VHDL? Видя это требование, воздерживался от ответов. Я мог бы на Verilog сделать. Вижу что начинающий, еще не поздно, ссылки у меня в подписи.


--------------------
Go to the top of the page
 
+Quote Post
lyzifer
сообщение Jul 14 2017, 07:41
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 13-07-17
Пользователь №: 98 133



Цитата(Tausinov @ Jul 13 2017, 19:26) *

ЕЕЕЕ)))Заработала))ещё раз нереальное спасибо))
Go to the top of the page
 
+Quote Post
AVR
сообщение Jul 14 2017, 08:08
Сообщение #15


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 055
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(lyzifer @ Jul 14 2017, 10:41) *
ЕЕЕЕ)))Заработала))ещё раз нереальное спасибо))

Будет ли Вам интересно увидеть, как я решу эту задачу в разы меньшим по объему текстом на другом HDL-языке? sm.gif
Не буду назойливым, просто меня шокировал объем кода для такой-то простой задачи...


--------------------
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd September 2017 - 03:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01514 секунд с 7
ELECTRONIX ©2004-2016