AFON // радиотехник affonya@mail.ru
← Проекты на VHDL

Проект 38. Простой командный интерпретатор по UART

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

Задача

Управлять светодиодами текстовыми командами, приходящими по UART.

Тип схемы: Комбинационно-синхронная надстройка над приёмником и передатчиком.
Модуль: uart_cmd. Среда: Quartus, Vivado, ISE или свободный GHDL для моделирования. Теорию по языку смотрите в статье VHDL — язык описания аппаратуры, по самим микросхемам — на странице ПЛИС.

Алгоритм

  1. Дождаться признака valid от приёмника UART.
  2. Сравнить принятый байт с кодами известных команд.
  3. Установить регистр светодиодов в соответствии с командой.
  4. Отправить принятый байт обратно как подтверждение.

Код на VHDL

Код проверен компилятором GHDL: проходит анализ и элаборацию без ошибок и предупреждений. Скачать: v38.vhd

--=====================================================
-- Проект 38. Простой командный интерпретатор по UART
-- Принятый байт сравнивается с набором команд
-- и управляет светодиодами; на каждую команду — эхо.
--=====================================================
library ieee;
use ieee.std_logic_1164.all;

entity uart_cmd is
    port (
        clk       : in  std_logic;
        rst       : in  std_logic;
        rx_data   : in  std_logic_vector(7 downto 0);
        rx_valid  : in  std_logic;                       -- байт принят приёмником UART
        tx_data   : out std_logic_vector(7 downto 0);
        tx_start  : out std_logic;                       -- запрос передачи ответа
        leds      : out std_logic_vector(7 downto 0)
    );
end entity uart_cmd;

architecture rtl of uart_cmd is
    signal led_reg : std_logic_vector(7 downto 0) := (others => '0');
begin
    process (clk, rst)
    begin
        if rst = '1' then
            led_reg  <= (others => '0');
            tx_start <= '0';
            tx_data  <= (others => '0');
        elsif rising_edge(clk) then
            tx_start <= '0';                             -- живёт один такт

            if rx_valid = '1' then
                case rx_data is
                    when x"31" => led_reg <= x"01";       -- символ '1'
                    when x"32" => led_reg <= x"03";       -- символ '2'
                    when x"33" => led_reg <= x"07";       -- символ '3'
                    when x"30" => led_reg <= x"00";       -- символ '0' — сброс
                    when others => null;                  -- неизвестная команда
                end case;
                tx_data  <= rx_data;                      -- эхо принятого байта
                tx_start <= '1';
            end if;
        end if;
    end process;

    leds <= led_reg;
end architecture rtl;

Пояснения

  • Модуль намеренно не содержит собственной логики UART — он подключается к готовым передатчику и приёмнику из проектов 16 и 17, демонстрируя повторное использование блоков.
  • Ветвь others в разборе команд отбрасывает нераспознанные байты, не нарушая работу схемы.
  • Такая прослойка между физическим интерфейсом и логикой устройства — стандартный архитектурный приём: заменить UART на другой канал связи можно, не трогая обработчик команд.

Что дальше

Следующие проекты — в разделе проекты на VHDL. Сравнить подход с языком Verilog можно в статье Verilog, а разобраться в устройстве самих кристаллов — в статье ПЛИС: FPGA и CPLD.