Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> VHDL

Учебное пособие:Ваша первая программа для ПЛИС:мигалка для светодиодов

Часть 1. Проектирование VHDL или Verilog

В этом руководстве показано построение кода VHDL и Verilog, который мигает светодиодом с заданной частотой. Показаны как VHDL, так и Verilog, и вы можете выбрать, что вы хотите изучить в первую очередь. Всякий раз, когда код проекта пишется, разработчик FPGA должен убедиться, что он работает так, как задумано. Несмотря на все ваши усилия, в вашем первоначальном проекте всегда будут ошибки. Лучший способ найти эти ошибки — в среде моделирования. Это руководство разбито на 2 этапа:

  1. Дизайн HDL
  2. Моделирование ЛПВП

Оба эти шага имеют решающее значение для успешной разработки ПЛИС. Иногда проектировщики FPGA, у которых мало времени, пытаются пропустить второй шаг — моделирование своего кода. Однако это чрезвычайно важный шаг! Без надлежащего моделирования вам придется отлаживать свой код на оборудовании, что может оказаться очень трудным и трудоемким занятием.

Требования к проекту:

Разработайте HDL-код, который будет мигать светодиодом с заданной частотой 100 Гц, 50 Гц, 10 Гц или 1 Гц. Для каждой из частот мигания светодиод будет установлен на 50% рабочего цикла (он будет гореть половину времени). Частота светодиода будет выбираться с помощью двух переключателей, которые являются входами для FPGA. Существует дополнительный переключатель под названием LED_EN, который должен быть «1», чтобы включить светодиод. FPGA будет управляться генератором с частотой 25 МГц.

Давайте сначала нарисуем таблицу истинности для частотного селектора:

Включить Переключить 1 Переключатель 2 Частота привода светодиодов 0 - - (отключено) 1 0 0 100 Гц 1 0 1 50 Гц 1 1 0 10 Гц 1 1 1 1 Гц

Для правильной работы будет 4 входа и 1 выход. Сигналы будут:

Имя сигнала Направление Описание Вход i_clock Тактовая частота 25 МГц Вход i_enable Переключатель разрешения (логический 0 =нет управления светодиодом) i_switch_1 Входной переключатель 1 в приведенной выше таблице истинности i_switch_2 Входной переключатель 2 в приведенной выше таблице истинности o_led_drive Выход Сигнал, управляющий светодиодом

Для проекта предусмотрено четыре встречных процесса, которые выполняются одновременно. Это означает, что все они работают одновременно. Их работа состоит в том, чтобы отслеживать количество тактовых импульсов для каждой из различных частот. Даже если переключатели не выбирают эту конкретную частоту, счетчики продолжают работать! В этом прелесть аппаратного проектирования и параллелизма. Все работает постоянно! Поначалу это может быть сложно понять, но это основная концепция, которую вам необходимо освоить.

Переключатели служат только для выбора того, какой выход использовать. Они создают так называемый мультиплексор. Мультиплексор или мультиплексор для краткости — это селектор, который выбирает один из нескольких входов для распространения или передачи на выход. Это комбинаторная часть логики, а это означает, что для работы не требуются часы. Ниже представлена ​​блок-схема конструкции. Потратьте некоторое время на размышления о том, как вы могли бы реализовать этот дизайн. Попробуйте написать код самостоятельно. Способ, который я выбрал, можно найти ниже.

Блок-схема — программа мигания светодиодов

Код VHDL для дизайна, tutorial_led_blink.vhd:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tutorial_led_blink is
  port (
    i_clock      : in  std_logic;
    i_enable     : in  std_logic;
    i_switch_1   : in  std_logic;
    i_switch_2   : in  std_logic;
    o_led_drive  : out std_logic
    );
end tutorial_led_blink;

architecture rtl of tutorial_led_blink is

  -- Constants to create the frequencies needed:
  -- Formula is: (25 MHz / 100 Hz * 50% duty cycle)
  -- So for 100 Hz: 25,000,000 / 100 * 0.5 = 125,000
  constant c_CNT_100HZ : natural := 125000;
  constant c_CNT_50HZ  : natural := 250000;
  constant c_CNT_10HZ  : natural := 1250000;
  constant c_CNT_1HZ   : natural := 12500000;


  -- These signals will be the counters:
  signal r_CNT_100HZ : natural range 0 to c_CNT_100HZ;
  signal r_CNT_50HZ  : natural range 0 to c_CNT_50HZ;
  signal r_CNT_10HZ  : natural range 0 to c_CNT_10HZ;
  signal r_CNT_1HZ   : natural range 0 to c_CNT_1HZ;
  
  -- These signals will toggle at the frequencies needed:
  signal r_TOGGLE_100HZ : std_logic := '0';
  signal r_TOGGLE_50HZ  : std_logic := '0';
  signal r_TOGGLE_10HZ  : std_logic := '0';
  signal r_TOGGLE_1HZ   : std_logic := '0';

  -- One bit select wire.
  signal w_LED_SELECT : std_logic;
  
begin

  -- All processes toggle a specific signal at a different frequency.
  -- They all run continuously even if the switches are
  -- not selecting their particular output.
  
  p_100_HZ : process (i_clock) is
  begin
    if rising_edge(i_clock) then
      if r_CNT_100HZ = c_CNT_100HZ-1 then  -- -1, since counter starts at 0
        r_TOGGLE_100HZ <= not r_TOGGLE_100HZ;
        r_CNT_100HZ    <= 0;
      else
        r_CNT_100HZ <= r_CNT_100HZ + 1;
      end if;
    end if;
  end process p_100_HZ;


  p_50_HZ : process (i_clock) is
  begin
    if rising_edge(i_clock) then
      if r_CNT_50HZ = c_CNT_50HZ-1 then  -- -1, since counter starts at 0
        r_TOGGLE_50HZ <= not r_TOGGLE_50HZ;
        r_CNT_50HZ    <= 0;
      else
        r_CNT_50HZ <= r_CNT_50HZ + 1;
      end if;
    end if;
  end process p_50_HZ;

  
  p_10_HZ : process (i_clock) is
  begin
    if rising_edge(i_clock) then
      if r_CNT_10HZ = c_CNT_10HZ-1 then  -- -1, since counter starts at 0
        r_TOGGLE_10HZ <= not r_TOGGLE_10HZ;
        r_CNT_10HZ    <= 0;
      else
        r_CNT_10HZ <= r_CNT_10HZ + 1;
      end if;
    end if;
  end process p_10_HZ;

  
  p_1_HZ : process (i_clock) is
  begin
    if rising_edge(i_clock) then
      if r_CNT_1HZ = c_CNT_1HZ-1 then  -- -1, since counter starts at 0
        r_TOGGLE_1HZ <= not r_TOGGLE_1HZ;
        r_CNT_1HZ    <= 0;
      else
        r_CNT_1HZ <= r_CNT_1HZ + 1;
      end if;
    end if;
  end process p_1_HZ;

  
  -- Create a multiplexor based on switch inputs
  w_LED_SELECT <= r_TOGGLE_100HZ when (i_switch_1 = '0' and i_switch_2 = '0') else
                  r_TOGGLE_50HZ  when (i_switch_1 = '0' and i_switch_2 = '1') else
                  r_TOGGLE_10HZ  when (i_switch_1 = '1' and i_switch_2 = '0') else
                  r_TOGGLE_1HZ;

  
  -- Only allow o_led_drive to drive when i_enable is high (and gate).
  o_led_drive <= w_LED_SELECT and i_enable;

end rtl;

Код Verilog для дизайна, tutorial_led_blink.v:

module tutorial_led_blink 
  (
   i_clock,
   i_enable,
   i_switch_1,
   i_switch_2,
   o_led_drive
   );

  input i_clock;
  input i_enable;
  input i_switch_1;
  input i_switch_2;
  output o_led_drive;
   
  // Constants (parameters) to create the frequencies needed:
  // Input clock is 25 kHz, chosen arbitrarily.
  // Formula is: (25 kHz / 100 Hz * 50% duty cycle)
  // So for 100 Hz: 25,000 / 100 * 0.5 = 125
  parameter c_CNT_100HZ = 125;
  parameter c_CNT_50HZ  = 250;
  parameter c_CNT_10HZ  = 1250;
  parameter c_CNT_1HZ   = 12500;

  // These signals will be the counters:
  reg [31:0] r_CNT_100HZ = 0;
  reg [31:0] r_CNT_50HZ = 0;
  reg [31:0] r_CNT_10HZ = 0;
  reg [31:0] r_CNT_1HZ = 0;
  
  // These signals will toggle at the frequencies needed:
  reg 	     r_TOGGLE_100HZ = 1'b0;
  reg 	     r_TOGGLE_50HZ  = 1'b0;
  reg 	     r_TOGGLE_10HZ  = 1'b0;
  reg 	     r_TOGGLE_1HZ   = 1'b0;
  
  // One bit select
  reg 	     r_LED_SELECT;
  wire 	     w_LED_SELECT;
  
    
begin

  // All always blocks toggle a specific signal at a different frequency.
  // They all run continuously even if the switches are
  // not selecting their particular output.

  always @ (posedge i_clock)
    begin
      if (r_CNT_100HZ == c_CNT_100HZ-1) // -1, since counter starts at 0
        begin	      
          r_TOGGLE_100HZ <= !r_TOGGLE_100HZ;
          r_CNT_100HZ    <= 0;
        end
      else
        r_CNT_100HZ <= r_CNT_100HZ + 1;
    end

  
  always @ (posedge i_clock)
    begin
      if (r_CNT_50HZ == c_CNT_50HZ-1) // -1, since counter starts at 0
        begin	      
          r_TOGGLE_50HZ <= !r_TOGGLE_50HZ;
          r_CNT_50HZ    <= 0;
        end
      else
        r_CNT_50HZ <= r_CNT_50HZ + 1;
    end


  always @ (posedge i_clock)
    begin
      if (r_CNT_10HZ == c_CNT_10HZ-1) // -1, since counter starts at 0
        begin	      
          r_TOGGLE_10HZ <= !r_TOGGLE_10HZ;
          r_CNT_10HZ    <= 0;
        end
      else
        r_CNT_10HZ <= r_CNT_10HZ + 1;
    end

  
  always @ (posedge i_clock)
    begin
      if (r_CNT_1HZ == c_CNT_1HZ-1) // -1, since counter starts at 0
        begin	      
          r_TOGGLE_1HZ <= !r_TOGGLE_1HZ;
          r_CNT_1HZ    <= 0;
        end
      else
        r_CNT_1HZ <= r_CNT_1HZ + 1;
    end

  // Create a multiplexer based on switch inputs
  always @ (*)
  begin
    case ({i_switch_1, i_switch_2}) // Concatenation Operator { }
      2'b11 : r_LED_SELECT <= r_TOGGLE_1HZ;
      2'b10 : r_LED_SELECT <= r_TOGGLE_10HZ;
      2'b01 : r_LED_SELECT <= r_TOGGLE_50HZ;
      2'b00 : r_LED_SELECT <= r_TOGGLE_100HZ;
    endcase      
  end

  assign o_led_drive = r_LED_SELECT & i_enable;

  // Alternative way to design multiplexer (same as above):
  // More compact, but harder to read, especially to those new to Verilog
  // assign w_LED_SELECT = i_switch_1 ? (i_switch_2 ? r_TOGGLE_1HZ : r_TOGGLE_10HZ) : 
                                        (i_switch_2 ? r_TOGGLE_50HZ : r_TOGGLE_100HZ);
  // assign o_led_drive = w_LED_SELECT & i_enable;
    
  
end 
  
endmodule


VHDL

  1. C# Hello World — ваша первая программа на C#
  2. Встроенный дизайн с FPGA:создание проекта
  3. Упрощение проектирования с помощью встроенной технологии FPGA
  4. Как создать свою первую программу VHDL:Hello World!
  5. Максимизируйте свою программу анализа смазочных материалов
  6. Учебник Verilog
  7. Как разработать программу профилактического обслуживания вашего оборудования
  8. 10 советов, которые сделают вашу программу управления проектами лучше
  9. Учебное пособие по проектированию печатных плат Ultraboard
  10. Учебное пособие по проектированию печатных плат KiCAD