Опасность использования защёлок – пример из Quartus Prime

quartus latch защелка

Рассмотрим код, написанный для реализации задачи «бегающих» светодиодов с помощью ПЛИС Altera Cyclone IV в САПР Quartus Prime.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity running_LEDs is
	port (
		clk : in std_logic;
		led : out std_logic_vector(7 downto 0)
	);
end running_LEDs;

architecture rtl of running_LEDs is

	signal count : std_logic_vector(25 downto 0) := (others => '0');
	signal temp : std_logic_vector(7 downto 0) := (0 => '1', others => '0');
	signal rst : std_logic := '0';
	

begin
	process (clk)
	begin
		if (rst = '1') then
			count <= (others => '0');
		elsif (rising_edge(clk)) then
			count <= count + 1;
		end if;
	end process;

	process (count)
	begin
		if count = 50000000 then
			rst <= '1';
			temp(7 downto 0) <= temp (6 downto 0) & temp(7);
		else
			rst <= '0';
		end if;
	end process;
	led <= temp;
end rtl;

Идея программы заключалась в создании 8-битного регистра – «temp», а также счетчика – «count», который считает до 50 миллионов тактов и сбрасывается с помощью сигнала «rst». При каждом обнулении счетчика «зажженный» светодиод сдвигается влево. Правильность функционала подтверждает проведенное моделирование в ModelSim (рисунок 1).

Рисунок 1 Моделирование программы

С помощью инструмента RTL Viewer представим данный проект в графическом виде. На рисунке 2 можно заметить, что в программе образуются защелки – «temp». Как известно, не все программы-синтезаторы хорошо справляются с ними. В данном случае Quartus неверно инициализирует защелку, определяя начальное значение переменной «temp» как “11111111” вместо “00000001”. Используя логический анализатор SignalTap, подтверждаем это (рисунок 3). В результате, значение «temp» не будет меняться при каждом обнулении счетчика, как было задумано изначально.

Рисунок 2 – Графическая реализация проекта

Рисунок 3 – Анализ сигналов, полученный при помощи SignalTap

В конечном итоге, восемь светодиодов светятся одновременно (рисунок 4).

Рисунок 4 – Реализация программы на ПЛИС Altera Cyclone IV

Таким образом, из-за использования защелки в коде Quartus неверно выполняет программу. Исправить это можно, заменив защелку на D-триггер. Пример кода приведен ниже.

library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity running_LEDs is
	port (
		clk : in std_logic;
		led : out std_logic_vector(7 downto 0)
	);
end running_LEDs;

architecture rtl of running_LEDs is

	signal count : std_logic_vector(25 downto 0) := (others => '0');
	signal temp  : std_logic_vector(7 downto 0)  := (0 => '1', others => '0');
	signal rst   : std_logic := '0';

begin
	process (clk)
	begin
		if (rst = '1') then
			count <= (others => '0');
		elsif (rising_edge(clk)) then
			count <= count + 1;
		end if;
	end process;

	process (clk)
	begin
		if (rising_edge(clk)) then
			if count = 50000000 then
				rst <= '1';
				temp(7 downto 0) <= temp (6 downto 0) & temp(7);
			else
				rst <= '0';
			end if;
		end if;
	end process;
	led <= temp;
end rtl;

Материал подготовлен Валерией Дьяковой

Создан 2021-10-12 16:17:16

Обновлен 2023-05-15 15:46:43