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

Cara menggunakan Prosedur dalam Proses di VHDL

Dimungkinkan untuk menggerakkan sinyal eksternal dari suatu prosedur. Selama sinyal berada dalam ruang lingkup prosedur, sinyal tersebut dapat diakses untuk dibaca atau ditulis, meskipun tidak tercantum dalam daftar parameter.

Prosedur yang dideklarasikan di wilayah deklaratif arsitektur, tidak dapat menggerakkan sinyal eksternal apa pun. Ini hanya karena tidak ada sinyal dalam cakupannya pada waktu kompilasi. Sebaliknya, prosedur yang dideklarasikan dalam suatu proses akan memiliki akses ke semua sinyal yang dapat dilihat oleh proses tersebut.

Pos blog ini adalah bagian dari seri Tutorial VHDL Dasar.

Prosedur tersebut dapat digunakan untuk mendeklarasikan algoritma dalam proses di mana operasi yang sama terjadi beberapa kali. Kita bisa menggunakan prosedur normal di mana semua input dan output ditetapkan ke sinyal lokal saat Anda memanggilnya, tapi bukan itu intinya. Dengan menghilangkan sinyal input dan output dari panggilan prosedur, kita harus mengetik lebih sedikit, dan yang lebih penting, kita membuat kode lebih mudah dibaca.

Bayangkan sebuah proses yang mengimplementasikan protokol komunikasi yang kompleks. Akan jauh lebih mudah untuk memahami alur eksekusi algoritme utama jika beberapa operasi diganti dengan pemanggilan prosedur seperti RequestToSend() atau SendAutorizationHeader() . Anda akan tahu apa yang dilakukan baris-baris itu hanya dengan melihat nama prosedurnya.

Olahraga

Dalam tutorial sebelumnya, kami menyederhanakan kode finite-state machine (FSM) kami dengan menggunakan fungsi tidak murni. Kami mengendarai Counter sinyal dari fungsi tidak murni, dan kami menggunakan nilai balik untuk menentukan kapan harus mengubah status. Tapi bagaimana jika kita ingin memindahkan tugas State sinyal ke fungsi juga, dan abaikan nilai baliknya?

Tidak mungkin memanggil fungsi tanpa menetapkan nilai kembalian ke sesuatu di VHDL. Jika kita mencoba melakukannya, ModelSim akan menghasilkan kesalahan kompilasi: Tidak ada entri yang layak untuk subprogram “CounterExpired”.

Sebagai gantinya, kita dapat menggunakan prosedur untuk ini. Prosedur yang dideklarasikan dalam suatu proses dapat mengakses sinyal apa pun dalam lingkup proses itu. Ini mirip dengan fungsi tidak murni, tetapi karena ini adalah prosedur, tidak ada nilai kembalian.

Dalam tutorial video ini kami akan menyederhanakan kode FSM dengan menggunakan prosedur yang dideklarasikan dalam suatu proses:

Kode terakhir untuk Prosedur dalam Proses testbench :

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

entity T23_ProcedureInProcessTb is
end entity;

architecture sim of T23_ProcedureInProcessTb 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.T23_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 modul Lampu Lalu Lintas :

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

entity T23_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 T23_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

        -- Procedure for changing state after a given time
        procedure ChangeState(ToState : t_State;
                              Minutes : integer := 0;
                              Seconds : integer := 0) is
            variable TotalSeconds : integer;
            variable ClockCycles  : integer;
        begin
            TotalSeconds := Seconds + Minutes * 60;
            ClockCycles  := TotalSeconds * ClockFrequencyHz -1;
            if Counter = ClockCycles then
                Counter <= 0;
                State   <= ToState;
            end if;
        end procedure;

    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';
                        ChangeState(StartNorth, Seconds => 5);

                    -- Red and yellow in north/south direction
                    when StartNorth =>
                        NorthRed    <= '1';
                        NorthYellow <= '1';
                        WestRed     <= '1';
                        ChangeState(North, Seconds => 5);

                    -- Green in north/south direction
                    when North =>
                        NorthGreen <= '1';
                        WestRed    <= '1';
                        ChangeState(StopNorth, Minutes => 1);

                    -- Yellow in north/south direction
                    when StopNorth =>
                        NorthYellow <= '1';
                        WestRed     <= '1';
                        ChangeState(WestNext, Seconds => 5);

                    -- Red in all directions
                    when WestNext =>
                        NorthRed <= '1';
                        WestRed  <= '1';
                        ChangeState(StartWest, Seconds => 5);

                    -- Red and yellow in west/east direction
                    when StartWest =>
                        NorthRed   <= '1';
                        WestRed    <= '1';
                        WestYellow <= '1';
                        ChangeState(West, Seconds => 5);

                    -- Green in west/east direction
                    when West =>
                        NorthRed  <= '1';
                        WestGreen <= '1';
                        ChangeState(StopWest, Minutes => 1);

                    -- Yellow in west/east direction
                    when StopWest =>
                        NorthRed   <= '1';
                        WestYellow <= '1';
                        ChangeState(NorthNext, Seconds => 5);

                end case;

            end if;
        end if;
    end process;

end architecture;

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

Analisis

Kami belum mengubah perilaku modul, dan kami dapat melihat bahwa bentuk gelombang tidak berubah.

Dibandingkan dengan kode dari tutorial di mana kita pertama kali membuat modul lampu lalu lintas, kode FSM jauh lebih mudah dibaca sekarang. Anda dapat dengan mudah mengikuti algoritme yang diterapkannya dengan membaca kode. Memiliki logika penghitung waktu dan perubahan status dalam satu prosedur bermanfaat karena memastikan bahwa itu diterapkan secara merata di mana pun digunakan.

Bawa Pulang


VHDL

  1. Tutorial - Pengantar VHDL
  2. Pernyataan Prosedur - Contoh VHDL
  3. Bagaimana Kami Menggunakan Molibdenum?
  4. Cara membuat daftar string di VHDL
  5. Cara menggunakan Fungsi Tidak Murni di VHDL
  6. Cara menggunakan Fungsi di VHDL
  7. Cara menggunakan Prosedur di VHDL
  8. Cara membuat pengatur waktu di VHDL
  9. Cara membuat Proses Berjam di VHDL
  10. Cara Menggunakan Penggiling Pemotong