Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> VHDL

Tutorial:Program FPGA Pertama Anda:LED Blinker

Bagian 1:Desain VHDL atau Verilog

Tutorial ini menunjukkan konstruksi kode VHDL dan Verilog yang mengedipkan LED pada frekuensi tertentu. VHDL dan Verilog keduanya ditampilkan, dan Anda dapat memilih mana yang ingin Anda pelajari terlebih dahulu. Setiap kali kode desain ditulis, perancang FPGA perlu memastikan bahwa kode itu berfungsi seperti yang dimaksudkan. Terlepas dari upaya terbaik Anda, akan selalu ada kesalahan dalam desain awal Anda. Cara terbaik untuk menemukan kesalahan ini adalah dalam lingkungan simulasi. Tutorial ini dibagi menjadi 2 tahap:

  1. Desain HDL
  2. Simulasi HDL

Kedua langkah ini sangat penting untuk keberhasilan pengembangan FPGA. Terkadang desainer FPGA yang terdesak waktu akan mencoba melewati langkah kedua, simulasi kode mereka. Namun ini adalah langkah yang sangat penting! Tanpa simulasi yang tepat, Anda akan dipaksa untuk men-debug kode Anda pada perangkat keras yang dapat menjadi upaya yang sangat sulit dan memakan waktu.

Persyaratan Proyek:

Rancang kode HDL yang akan mengedipkan LED pada frekuensi tertentu 100 Hz, 50 Hz, 10 Hz, atau 1 Hz. Untuk setiap frekuensi kedipan, LED akan diatur ke siklus kerja 50% (akan menyala separuh waktu). Frekuensi LED akan dipilih melalui dua sakelar yang merupakan input ke FPGA. Ada sakelar tambahan yang disebut LED_EN yang harus '1' untuk menyalakan LED. FPGA akan digerakkan oleh osilator 25 MHz.

Mari kita menggambar tabel kebenaran untuk pemilih frekuensi:

Aktifkan Beralih 1 Beralih 2 Frekuensi Drive LED 0 - - (dinonaktifkan) 1 0 0 100 Hz 1 0 1 50 Hz 1 1 0 10 Hz 1 1 1 1 Hz

Agar ini berfungsi dengan benar, akan ada 4 input dan 1 output. Sinyalnya adalah:

Nama Sinyal Arah Deskripsi i_clock Input 25 MHz Clock i_enable Input Saklar Enable (Logika 0 =Tanpa Drive LED) i_switch_1 Saklar Input 1 pada Tabel Kebenaran di atas i_switch_2 Saklar Input 2 pada Tabel Kebenaran di atas o_led_drive Output Sinyal yang menggerakkan LED

Untuk perancangan terdapat empat proses counter yang berjalan secara bersamaan. Ini berarti bahwa mereka semua berjalan pada waktu yang sama. Tugas mereka adalah melacak jumlah pulsa clock yang terlihat untuk setiap frekuensi yang berbeda. Bahkan jika sakelar tidak memilih frekuensi tertentu, penghitung masih berjalan! Inilah keindahan Desain Perangkat Keras dan konkurensi. Semuanya berjalan sepanjang waktu! Mungkin sulit untuk memahami ini pada awalnya, tetapi ini adalah konsep inti yang perlu Anda kuasai.

Sakelar hanya berfungsi untuk memilih keluaran mana yang akan digunakan. Mereka menciptakan apa yang dikenal sebagai multiplexer. Multiplexer atau mux untuk jangka pendek adalah pemilih yang akan memilih salah satu dari sejumlah input untuk menyebarkan atau meneruskan ke output. Ini adalah bagian logika kombinatorial, artinya tidak memerlukan jam untuk beroperasi. Di bawah ini adalah diagram blok dari desain. Luangkan waktu untuk memikirkan bagaimana Anda dapat menerapkan desain ini. Coba tulis kodenya sendiri. Cara yang saya pilih dapat ditemukan di bawah ini.

Diagram Blok - Program LED Blink

Kode VHDL untuk desain, 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;

Kode Verilog untuk desain, 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 - Program C# Pertama Anda
  2. Desain tersemat dengan FPGA:Membangun proyek
  3. Menyederhanakan desain dengan teknologi FPGA tertanam
  4. Cara membuat program VHDL pertama Anda:Halo Dunia!
  5. Maksimalkan program analisis pelumas Anda
  6. Tutorial Verilog
  7. Cara Merancang Program Pemeliharaan Pencegahan untuk Peralatan Anda
  8. 10 Peretasan untuk Membuat Program PM Anda Lebih Baik
  9. Tutorial Desain PCB Ultraboard
  10. Tutorial Desain PCB KiCAD