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
Algoritma biasanya diimplementasikan sebagai mesin keadaan-terbatas (FSM)
Sebuah FSM dapat diimplementasikan dengan menggunakan pernyataan kasus dalam proses clock
Status FSM dapat diimplementasikan dalam tipe enumerated