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

Cara membuat Mesin Finite-State di VHDL

Mesin finite-state (FSM) adalah mekanisme yang outputnya tidak hanya bergantung pada status input saat ini, tetapi juga pada nilai input dan output masa lalu.

Kapan pun Anda perlu membuat semacam algoritme yang bergantung pada waktu dalam VHDL, atau jika Anda menghadapi masalah dalam mengimplementasikan program komputer dalam FPGA, biasanya dapat diselesaikan dengan menggunakan FSM.

State-machine dalam VHDL adalah proses clock yang outputnya dikendalikan oleh nilai sinyal state. Sinyal status berfungsi sebagai memori internal dari apa yang terjadi pada iterasi sebelumnya.

Pos blog ini adalah bagian dari seri Tutorial VHDL Dasar.

Pertimbangkan keadaan lampu lalu lintas di persimpangan ini:

Lampu lalu lintas memiliki jumlah negara bagian yang terbatas, yang telah kami berikan nama yang dapat diidentifikasi. Contoh mesin keadaan kami tidak memiliki input pengontrol, outputnya adalah keadaan lampu di arah utara/selatan dan barat/timur. Ini adalah waktu yang telah berlalu dan keadaan keluaran sebelumnya yang memajukan mesin keadaan ini.

Kami dapat merepresentasikan status dalam VHDL menggunakan tipe enumerated . Ini adalah tipe data seperti signed atau unsigned , tetapi alih-alih bilangan bulat, kami dapat menyediakan daftar nilai yang memungkinkan. Sebenarnya, jika Anda melihat paket std_logic_1164, Anda akan menemukan bahwa std_ulogic type tidak lebih dari tipe enumerated dengan nilai 'U' , 'X' , '0' , '1' , 'Z' , 'W' , 'L' , 'H' , dan '-' terdaftar sebagai nilai enumerasi.

Setelah kami memiliki tipe enumerasi kami, kami dapat mendeklarasikan sinyal tipe baru yang dapat digunakan untuk melacak status FSM saat ini.

Sintaks untuk mendeklarasikan sinyal dengan tipe enumerated di VHDL adalah:
type <type_name> is (<state_name1>, <state_name2>, ...);
signal <signal_name> : <type_name>;

Menggunakan sinyal keadaan, mesin keadaan hingga kemudian dapat diimplementasikan dalam suatu proses dengan pernyataan Kasus. Statemen Case berisi statemen When untuk setiap state yang mungkin, menyebabkan program mengambil jalur yang berbeda untuk setiap state. Pernyataan When juga dapat berisi kode yang harus dijalankan saat dalam keadaan tertentu. Keadaan kemudian biasanya akan berubah ketika kondisi yang telah ditentukan terpenuhi.

Ini adalah template untuk mesin status satu proses:
process(Clk) is
begin
    if rising_edge(Clk) then
        if nRst = '0' then
            State <= <reset_state>;
        else
            case State is
                when <state_name> =>
                    <set_outputs_for_this_state_here>
                    if <state_change_condition_is_true> then
                        State <= <next_state_name>;
                    end if;
                ...
            end case;
        end if;
    end if;
end process;

Catatan:
Ada beberapa cara untuk membuat FSM di VHDL. Baca tentang gaya yang berbeda di sini:
Mesin status satu proses vs dua proses vs tiga proses

Olahraga

Dalam tutorial video ini kita akan belajar cara membuat mesin keadaan hingga di VHDL:

Kode terakhir untuk mesin negara testbench :

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

entity T20_FiniteStateMachineTb is
end entity;

architecture sim of T20_FiniteStateMachineTb is

    -- We are using a low clock frequency to speed up the simulation
    constant ClockFrequencyHz : integer := 100; -- 100 Hz
    constant ClockPeriod : time := 1000 ms / ClockFrequencyHz;

    signal Clk         : std_logic := '1';
    signal nRst        : std_logic := '0';
    signal NorthRed    : std_logic;
    signal NorthYellow : std_logic;
    signal NorthGreen  : std_logic;
    signal WestRed     : std_logic;
    signal WestYellow  : std_logic;
    signal WestGreen   : std_logic;

begin

    -- The Device Under Test (DUT)
    i_TrafficLights : entity work.T20_TrafficLights(rtl)
    generic map(ClockFrequencyHz => ClockFrequencyHz)
    port map (
        Clk         => Clk,
        nRst        => nRst,
        NorthRed    => NorthRed,
        NorthYellow => NorthYellow,
        NorthGreen  => NorthGreen,
        WestRed     => WestRed,
        WestYellow  => WestYellow,
        WestGreen   => WestGreen);

    -- Process for generating clock
    Clk <= not Clk after ClockPeriod / 2;

    -- Testbench sequence
    process is
    begin
        wait until rising_edge(Clk);
        wait until rising_edge(Clk);

        -- Take the DUT out of reset
        nRst <= '1';

        wait;
    end process;

end architecture;

Kode terakhir untuk mesin negara modul :

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

entity T20_TrafficLights is
generic(ClockFrequencyHz : integer);
port(
    Clk         : in std_logic;
    nRst        : in std_logic; -- Negative reset
    NorthRed    : out std_logic;
    NorthYellow : out std_logic;
    NorthGreen  : out std_logic;
    WestRed     : out std_logic;
    WestYellow  : out std_logic;
    WestGreen   : out std_logic);
end entity;

architecture rtl of T20_TrafficLights is

    -- Enumerated type declaration and state signal declaration
    type t_State is (NorthNext, StartNorth, North, StopNorth,
                        WestNext, StartWest, West, StopWest);
    signal State : t_State;

    -- Counter for counting clock periods, 1 minute max
    signal Counter : integer range 0 to ClockFrequencyHz * 60;

begin

    process(Clk) is
    begin
        if rising_edge(Clk) then
            if nRst = '0' then
                -- Reset values
                State   <= NorthNext;
                Counter <= 0;
                NorthRed    <= '1';
                NorthYellow <= '0';
                NorthGreen  <= '0';
                WestRed     <= '1';
                WestYellow  <= '0';
                WestGreen   <= '0';

            else
                -- Default values
                NorthRed    <= '0';
                NorthYellow <= '0';
                NorthGreen  <= '0';
                WestRed     <= '0';
                WestYellow  <= '0';
                WestGreen   <= '0';

                Counter <= Counter + 1;

                case State is

                    -- Red in all directions
                    when NorthNext =>
                        NorthRed <= '1';
                        WestRed  <= '1';
                        -- If 5 seconds have passed
                        if Counter = ClockFrequencyHz * 5 -1 then
                            Counter <= 0;
                            State   <= StartNorth;
                        end if;

                    -- Red and yellow in north/south direction
                    when StartNorth =>
                        NorthRed    <= '1';
                        NorthYellow <= '1';
                        WestRed     <= '1';
                        -- If 5 seconds have passed
                        if Counter = ClockFrequencyHz * 5 -1 then
                            Counter <= 0;
                            State   <= North;
                        end if;

                    -- Green in north/south direction
                    when North =>
                        NorthGreen <= '1';
                        WestRed    <= '1';
                        -- If 1 minute has passed
                        if Counter = ClockFrequencyHz * 60 -1 then
                            Counter <= 0;
                            State   <= StopNorth;
                        end if;

                    -- Yellow in north/south direction
                    when StopNorth =>
                        NorthYellow <= '1';
                        WestRed     <= '1';
                        -- If 5 seconds have passed
                        if Counter = ClockFrequencyHz * 5 -1 then
                            Counter <= 0;
                            State   <= WestNext;
                        end if;

                    -- Red in all directions
                    when WestNext =>
                        NorthRed <= '1';
                        WestRed  <= '1';
                        -- If 5 seconds have passed
                        if Counter = ClockFrequencyHz * 5 -1 then
                            Counter <= 0;
                            State   <= StartWest;
                        end if;

                    -- Red and yellow in west/east direction
                    when StartWest =>
                        NorthRed   <= '1';
                        WestRed    <= '1';
                        WestYellow <= '1';
                        -- If 5 seconds have passed
                        if Counter = ClockFrequencyHz * 5 -1 then
                            Counter <= 0;
                            State   <= West;
                        end if;

                    -- Green in west/east direction
                    when West =>
                        NorthRed  <= '1';
                        WestGreen <= '1';
                        -- If 1 minute has passed
                        if Counter = ClockFrequencyHz * 60 -1 then
                            Counter <= 0;
                            State   <= StopWest;
                        end if;

                    -- Yellow in west/east direction
                    when StopWest =>
                        NorthRed   <= '1';
                        WestYellow <= '1';
                        -- If 5 seconds have passed
                        if Counter = ClockFrequencyHz * 5 -1 then
                            Counter <= 0;
                            State   <= NorthNext;
                        end if;

                end case;

            end if;
        end if;
    end process;

end architecture;

Bentuk gelombang setelah kita memasukkan run 5 min perintah di konsol ModelSim:

Analisis

Kami mendeklarasikan tipe enumerasi dengan delapan status lampu lalu lintas kami yang berbeda. Kemudian, kami mendeklarasikan state sinyal tipe baru ini yang kami buat. Ini berarti bahwa sinyal hanya dapat memiliki satu dari delapan nilai status yang disebutkan, dan tidak ada nilai lainnya.

FSM diimplementasikan menggunakan Case-statement dalam proses clock. Pada setiap tepi naik jam, proses bangun, dan state sinyal dievaluasi. Kode tepat di dalam salah satu when pilihan (cabang) diizinkan untuk berjalan, tergantung pada keadaan saat ini.

Dalam kode kami, itu adalah nilai dari Counter sinyal yang memicu perubahan status. Ketika Penghitung mencapai nilai yang telah ditentukan, mewakili 5 detik atau 1 menit, pengkodean status baru ditetapkan ke State sinyal. Kemudian, ketika proses bangun di tepi naik berikutnya dari jam setelah nilai status diperbarui, FSM berada dalam status yang berbeda.

Perhatikan bahwa kami tidak menetapkan '0' ke sinyal apa pun di salah satu when pilihan. Ini karena kami telah memberikan semua sinyal output nilai default '0' di awal proses. Anda mungkin ingat dari tutorial sebelumnya bahwa itu adalah nilai terakhir yang diberikan ke sinyal yang menjadi efektif. Penetapan sinyal menjadi efektif hanya setelah proses berakhir. Jika kita menetapkan '0' ke sinyal di awal proses, lalu '1' di salah satu when pilihan, sinyal akan mendapatkan nilai '1' .

Kita dapat melihat dari bentuk gelombang bahwa State siklus sinyal melalui delapan negara. Status hijau stabil berlangsung selama satu menit, oleh karena itu gambar bentuk gelombang telah dipotong dalam North dan West negara bagian.

Bawa Pulang

Pergi ke tutorial berikutnya »


VHDL

  1. Mesin Keadaan Hingga
  2. Cara memastikan kinerja mesin status Qt terbaik
  3. Cara membuat daftar string di VHDL
  4. Cara membuat testbench berbasis Tcl untuk modul kunci kode VHDL
  5. Bagaimana menghentikan simulasi di testbench VHDL
  6. Cara membuat pengontrol PWM di VHDL
  7. Cara menghasilkan angka acak di VHDL
  8. Cara membuat testbench pemeriksaan mandiri
  9. Cara membuat Daftar Tertaut di VHDL
  10. Bagaimana Mesin Laser CNC OMNI Membuat Hadiah Natal yang Dipersonalisasi?