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

Устройство мигания светодиодов (VHDL)

Устройство моргания 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;

 

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

 

111111.jpg

 

а надо:

 

 

image.jpg

post-98133-1499946586_thumb.jpg

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


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

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

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

Ну а можно сделать еще проще. Автомат и таймер. Могу рассказать по скайпу...

Удачи!

 

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


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

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

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

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


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

Ввести дополнительный сигнал

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 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;

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


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

Блин,видимо я не оч догоняю,как правильно добавить в код...((ошибку выдаёт на выходе при моделировании...

Покажи,плиииииз, как правильно.заранее благодарен!!

 

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

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


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

Дизайн:

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;

 

 

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


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

А мне нужно чтобы диод загорелся,потух,а только потом,через 1 с, следующий.

Коллеги каких-то сложностей насоветовали...

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

 

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


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

Коллеги каких-то сложностей насоветовали...

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

 

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

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


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

 

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

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

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


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

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

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


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

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

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


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

ЕЕЕЕ)))Заработала))ещё раз нереальное спасибо))

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

Не буду назойливым, просто меня шокировал объем кода для такой-то простой задачи...

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


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

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...