ПЛИС

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 19:22, 4 мая 2016.
Программируемая логическая интегральная схема

Программируемая логическая интегральная схема (англ. Programmable Logic Device, PLD) — электронный компонент, используемый для создания цифровых интегральных схем.

Принцип работы

В отличие от обычных цифровых микросхем, логика работы ПЛИС не определяется при изготовлении, а задаётся посредством программирования. Для программирования используются программатор и IDE (отладочная среда), позволяющие задать желаемую структуру цифрового устройства в виде принципиальной электрической схемы или программы на специальных языках описания аппаратуры.

История развития

По мере развития цифровых микросхем возникло противоречие между возможной степенью интеграции и номенклатурой выпускаемых микросхем. Экономически оправдано было выпускать микросхемы средней интеграции, таких как регистры, счетчики, сумматоры. Более сложные схемы приходилось создавать из этих узлов. Разместить более сложную схему на полупроводниковом кристалле не было большой проблемой, но это было оправдано либо очень большой серийностью аппаратуры, либо ценой. Заказные микросхемы не могли удовлетворить возникшую потребность в миниатюризации аппаратуры. Решение могло быть только одним — предоставить разработчикам аппаратуры возможность изменять внутреннюю структуру микросхемы (программировать).

История развития программируемых логических интегральных схем начинается с появления программируемых постоянных запоминающих устройств. Первое время программируемые ПЗУ использовались исключительно для хранения данных, однако вскоре их стали применять для реализации цифровых комбинационных устройств с произвольной таблицей истинности. Однако данное решение имело существенный недостаток - экспоненциальный рост сложности устройства в зависимости от количества входов. Добавление одного дополнительного входа цифрового устройства приводит к удвоению требуемого количества ячеек памяти ПЗУ. Это не позволяет реализовать многовходовые комбинационные цифровые схемы.

Для реализации цифровых комбинационных устройств с большим числом входов были разработаны программируемые логические матрицы (ПЛМ). В иностранной литературе они получили название — PLA(англ. Programmable Logic Arrays). Именно программируемые логические матрицы можно считать первыми программируемыми логическими интегральными схемами (Programmable Logic Devices — PLDs).

Классификация ПЛИС

  • PLA (англ. Programmable Logic Arrays) — программируемая логическая матрица. Основная идея работы ПЛМ заключается в реализации логической функции, представленной в СДНФ — дизъюнктивной нормальной форме. В программируемой логической матрице обе матрицы логических элементов "И" и "ИЛИ" программируемы.
Структура ПЛМ.gif
Рисунок 1. Обобщенная структура программируемых логических матриц (ПЛМ)
  • PAL (англ. Programmable Array Logic) — программируемая матрица логики. В отличии от ПЛМ в ПМЛ матрица логических элементов "И" является программируемой, а матрица логических элементов "ИЛИ" фиксированной. Поскольку изготовить такие устройства проще, чем ПЛМ, они имеют меньшую стоимость и обладают улучшенными характеристиками, что привело к их высокой популярности.
Структура ПМЛ.gif
Рисунок 2. Обобщенная структура программируемых матриц логики (ПМЛ)
  • GAL (англ. Gate Array Logic) ПЛИС, имеющие программируемую матрицу «И» и фиксированную матрицу «ИЛИ».
  • CPLD (англ Complex Programmable Logic Device). Программируемая логическая интегральная схема CPLD состоит из нескольких макроячеек, расположенных на одном кристалле. Каждая макроячейка соединена с блоками ввода-вывода, осуществляющими формирование необходимого вида входов или выходов для работы с внешними схемами. Кроме того, все макроячейки и блоки ввода-вывода связаны между собой внутренними параллельными шинами. Приведенная на рисунке 3 микросхема CPLD состоит из четырех макроячеек, которые связаны между собой внутренними шинами и соединяются с блоками ввода-вывода. Макроячейка построена подобно ПЛМ микросхеме, к которой на выходе подключен D-триггер. К недостаткам можно отнести то, что трудно обеспечить эффективное применение всех макроячеек. Всегда часть макроячеек остается неиспользуемыми. Часто из макроячейки используется только триггер или логический элемент "2И" ("2ИЛИ"). Остальная часть схемы зря занимает площадь кристалла и потребляет ток от источника питания.
Схема CPDL.gif
Рисунок 3. Пример внутренней схемы CPLD
  • FPGA (англ. Field-Programmable Gate Array). Принцип работы FPGA существенно отличаются от принципа работы CPLD. FPGA является наследником комбинационных схем, реализованных на постоянных запоминающих устройствах (ПЗУ). Обобщенная структура микросхем FPGA приведена на рисунке 4.
Обобщенная структура микросхем FPGA
Рисунок 4. Обобщенная структура микросхем FPGA

Пример проекта на плис: Таймер

Внутри ПЛИС находятся некие базовые элементы, которые соединяются на основе конфигурационной записи. Возможные базовые элементы, вид и место хранения конфигурационной записи зависят от вида ПЛИС и от конкретной модели. В современных ПЛИС выделяют два вида: CPLD и FPGA, еще раз о них:

  • CPLD (complex programmable logic device — сложные программируемые логические устройства) — ПЛИС, базовыми элементами которой являются макроячейки и простые логические вентили (И(-НЕ)/ИЛИ(-НЕ)). Обычно содержит меньше базовых элементов, чем FPGA, но является более быстродействующей. Также обычно содержит энергонезависимую конфигурационную память прямо на кристалле, но имеет ограниченное число циклов конфигурирования.
  • FPGA (field-programmable gate array — Программируемая пользователем вентильная матрица) – ПЛИС, которые обычно имеют целый букет видов базовых блоков, это и настраиваемые логические элементы (таблицами истинности) и блоки сложения-умножения (Digital signal processing — DSP) и PLL (Phase-Locked Loop) для деления и умножения частоты и некоторые другие в зависимости от модели. Обычно имеют энергозависимую внутреннюю память и функционал для загрузки конфигурации с внешней энергонезависимой памяти.

В примере будет использован стартовый набор разработчика Altera Cyclone II FPGA Starter Board, Altera Cyclone II FPGA Starter Board, это готовая плата, на которой установлена FPGA серии Cyclone II – EP2C20F484C7N, а также различная периферия и интерфейсы. Также светодиоды и семисегментные индикаторы.

PLIS ALTERA

Из ПО будем использовать Quartus II, free версию.

QuartusII

Запускаем наш САПР Quartus II и создаем проект. Первыми шагами визарда указываем имя проекта и его место дислокации, затем пропустим шаг добавления файлов. Закончим создание проекта на этапе выбора устройства, если делаем на железяке – точно знаем имя ПЛИС, его и выбираем. Если просто делаем проект для ПЛИС выберем что-нибудь помощней, например третий циклон. В примере выбиран FPGA.

PlisCreatProject

Жмем Finish – проект создан. Структура проекта в Quartus – иерархическая, нам необходимо выбрать верхушку иерархии (Top-Level Entity). Мы можем использовать для проектирования схемные файлы и файлы с описанием логики на одном из HDL (Hardware description language – язык описания аппаратуры). В качестве HDL языка проекта выбран VHDL ((Very high speed integrated circuits) Hardware Description Language), можно использовать любой другой, например Verilog или AHDL

Создаем наш первый файл проекта (File – New..) выбираем Block Diagram/Schematic File. Теперь давайте нарисуем простейшую схему, добавим один Input, один Output и соединим их (в реальной ПЛИС эта схема будет передавать сигнал с одной ножки на другую). Для этого Double Click на пустом месте схемы и в открывшемся диалоге Symbol выбираем необходимый элемент.

PlisNewFile

Наше устройство будет при включении питания начинать отсчет минут и часов. Значит нам понадобится четыре семисегментных индикатора «ЧЧ: ММ». Для отсчета времени нам нужен более-менее точный сигнал 1Hz. Его мы получим путем деления частоты 27Mhz, затем мы будем отсчитывать его на 60 (секунды), потом еще раз на 60 (минуты), а потом на 24 (часы). С последних двух блоков двоичное число минут и часов будет поступать на декодер Bin -> BCD (binary-coded decimal) -> 7seg. Схема будет асинхронная (Минуты заводятся от секунд, а часы от минут), для простоты и наглядности.

Plisscheme

Первый блок — блок деления частоты. Создадим новый файл, как мы уже умеем, только тип файла будет VHDL File. Вставим в него код:

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

entity Div_27Mhz_to_1Hz is
port( clk:in std_logic; clk_out:out std_logic);
end Div_27Mhz_to_1Hz;

architecture div_behavior of Div_27Mhz_to_1Hz is
begin
process(clk)
variable cnt : integer range 0 to 27000000;
begin
if(clk'event and clk = '1') 
then

if(cnt >= 13500000)
then
clk_out <= '1';
else 
clk_out <= '0';
end if;

if(cnt = 27000000)
then
cnt := 0;
else
cnt := cnt + 1;
end if; 

end if;
end process;
end div_behavior;

Вначале мы объявляем сущность, т.е. сам блок. Указываем его входы и выходы, их типы и имена. Тип std_logic в простонародье значит бит. Далее мы описываем внутреннюю архитектуру этого блока. Архитектура состоит из параллельных процессов. Каждый процесс имеет свой список чувствительности, например единственный процесс в примере выше чувствителен к изменениям на входе clk. Для процесса можно объявить переменные, в нашем примере это переменная типа integer range 0 to 27000000. Далее в теле процесса задается элементарная логика: пока не прошла половина периода — пихаем в выход логический ноль, как половина прошла – пихаем единицу, при этом не забываем считать и обнулять счетчик по достижению 27000000.

Сохраняем файл с кодом и создаем символ (File – Create/Update – Create Symbol Files For Current Files), это необходимо для того чтобы вставить данный блок в нашу главную схему. Найти свои символы можно в папке Project в диалоге вставки символа.

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

-- For CONV_STD_LOGIC_VECTOR:
use ieee.std_logic_arith.all;

entity cnt_0_to_59 is
port( clk:in std_logic; c59:out std_logic; vector:out std_logic_vector(5 downto 0));
end cnt_0_to_59;

architecture cnt_behavior of cnt_0_to_59 is
begin
process(clk)
variable cnt : integer range 0 to 59;
begin
if(clk'event and clk = '1') 
then
if(cnt = 59)
then
cnt := 0;
c59 <= '1';
vector <= CONV_STD_LOGIC_VECTOR(cnt, 6);
else
cnt := cnt + 1;
c59 <= '0';
vector <= CONV_STD_LOGIC_VECTOR(cnt, 6);
end if;
end if;
end process; 
end cnt_behavior;


Это блок счета от нуля до 59, который мы используем для счета минут и секунд.Из новинок тут тип выхода std_logic_vector(5 downto 0), который определяет группу битов (битовый вектор), а также функция CONV_STD_LOGIC_VECTOR(cnt, 6), которая преобразует переменную в битовый вектор указанной длины.

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

-- For CONV_STD_LOGIC_VECTOR:
use ieee.std_logic_arith.all;

entity cnt_0_to_23 is
port( clk:in std_logic; vector:out std_logic_vector(4 downto 0));
end cnt_0_to_23;

architecture cnt_behavior of cnt_0_to_23 is
begin
process(clk)
variable cnt : integer range 0 to 23;
begin
if(clk'event and clk = '1') 
then
if(cnt = 23)
then
cnt := 0;
vector <= CONV_STD_LOGIC_VECTOR(cnt, 5);
else
cnt := cnt + 1;
vector <= CONV_STD_LOGIC_VECTOR(cnt, 5);
end if;
end if;
end process;
end cnt_behavior;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

-- For CONV_STD_LOGIC_VECTOR:
use ieee.std_logic_arith.all;

entity bin2bcd_5bit is
port( bin:in std_logic_vector(4 downto 0); 
bcd1:out std_logic_vector(3 downto 0);
bcd10:out std_logic_vector(3 downto 0) 
);

end bin2bcd_5bit;

architecture converter_behavior of bin2bcd_5bit is 
begin
process(bin)
variable i : integer range 0 to 23;
variable i1 : integer range 0 to 9;
begin
i := conv_integer(bin);
i1 := i / 10;
bcd10 <= CONV_STD_LOGIC_VECTOR(i1, 4); 
i1 := i rem 10;
bcd1 <= CONV_STD_LOGIC_VECTOR(i1, 4); 
end process;
end converter_behavior;

Преобразователь Binary в BCD, по сути, просто разбивает одно бинарное число на два, каждое из которых представляет разряд десятичного числа. Из новинок – оператор rem, остаток от деления. Аналогично написан и преобразователь для шести бит, его приводить не буду.

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

entity BCD_to_7seg is
port( 
BCD:in std_logic_vector(3 downto 0); 
seg:out std_logic_vector(6 downto 0)
);

end BCD_to_7seg;

architecture conv_behavior of BCD_to_7seg is
begin
process(BCD)
begin
if BCD = "0000" then seg <= "0000001";--0
elsif BCD = "0001" then seg <= "1001111";--1
elsif BCD = "0010" then seg <= "0010010";--2 
elsif BCD = "0011" then seg <= "0000110";--3
elsif BCD = "0100" then seg <= "1001100";--4
elsif BCD = "0101" then seg <= "0100100";--5
elsif BCD = "0110" then seg <= "0100000";--6
elsif BCD = "0111" then seg <= "0001111";--7
elsif BCD = "1000" then seg <= "0000000";--8 
elsif BCD = "1001" then seg <= "0000100";--9
else seg <= "1001001";--err
end if;
end process;
end conv_behavior;

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

Plis7

Главная схема:

PlisMainScheme

bin2seg:

bin2seg

Проект готов, можно компилировать и тестировать.

Источники

  1. Пугачёв Б.А. Курс лекций по предмету "Электроника и схемотехника"
  2. Микушин А. В., Курс лекций по предмету "Цифровые устройства".
  3. Использование программируемых логических интегральных схем (ПЛИС). Электронный учебник по курсу компьютерная электроника.
  4. http://digteh.ru/digital/
  5. https://www.altera.com/
  6. http://vhdl.bas-net.by/
  7. http://altera-plis.ru/