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

Implementasi AXI FIFO di Block RAM dengan Handshake Ready/Valid

Saat pertama kali saya menemui antarmuka AXI saat merancang modul, saya terkejut dengan pendekatan kontrol aliran yang efisien. Berbeda dengan protokol tradisional yang bergantung pada pasangan busy/valid, full/valid, atau empty/valid, AXI hanya menggunakan dua sinyal: ready dan valid. Apa yang dimulai sebagai kegelisahan dengan cepat menjadi kesukaran.

AXI menyematkan kontrol aliran langsung dalam jabatannya, menghilangkan kebutuhan akan baris status tambahan. Sementara aturan dasarnya sederhana, perhatian hati-hati diperlukan saat memetakan protokol ke perangkat keras FPGA. Dalam tutorial ini, saya memandu Anda melalui implementasi VHDL dari AXI FIFO yang berjalan di block RAM.

AXI memecahkan masalah tertunda satu siklus

Mencegah over-read dan overwrite adalah tantangan umum ketika dua modul yang disinkronkan clock bertukar aliran data. Inti masalahnya adalah setiap modul hanya dapat mengamati output modul lain satu siklus clock setelah terjadi.

Implementasi AXI FIFO di Block RAM dengan Handshake Ready/Valid

Diagram di atas menggambarkan modul sekuensial yang menulis ke FIFO yang menggunakan skema sinyal klasik write enable/full. Penulis mengajukan wr_en untuk mendorong data ke FIFO, sementara FIFO mengajukan full ketika tidak ada ruang lagi yang tersedia. Masalahnya adalah full diajukan tepat pada tepi naik clock, jadi penulis tidak lagi dapat bereaksi padanya dalam siklus yang sama. Solusinya adalah memberikan sinyal look-ahead seperti almost_empty, memberikan logika upstream awal.

Jatuh tangan ready/valid

Antarmuka aliran AXI memecahkan dilema waktu ini dengan jabat dua sinyal: ready dan valid. Penerima mengajukan ready; nilai tinggi menunjukkan bahwa ia siap menerima datum baru. Pengirim mengajukan valid; nilai tinggi berarti data pada bus stabil dan dapat diambil. Transfer hanya terjadi ketika kedua sinyal tinggi pada tepi naik yang sama.

Implementasi AXI FIFO di Block RAM dengan Handshake Ready/Valid

Gelombang menunjukkan transfer satu item data. Data diambil pada tepi naik clock, sama seperti dalam desain sinkron konvensional.

Implementasi

Ada beberapa cara untuk membangun AXI FIFO dalam VHDL. Sementara shift register akan bekerja, ring buffer yang didukung block RAM adalah pilihan paling efisien dan scalable. Di bawah ini, saya menyajikan desain modular yang memisahkan logika ke dalam proses terpadu untuk kejelasan dan ramah sintesis.

Entitas

Entitas menentukan dua parameter generik – ram_width dan ram_depth – yang menetapkan lebar kata dan kedalaman FIFO. Kapasitas efektif adalah ram_depth - 1, karena satu slot dicadangkan untuk membedakan FIFO penuh dari FIFO kosong.

entity axi_fifo is generic ( ram_width : natural; ram_depth : natural ); port ( clk : in std_logic; rst : in std_logic; -- AXI input interface in_ready : out std_logic; in_valid : in std_logic; in_data : in std_logic_vector(ram_width - 1 downto 0); -- AXI output interface out_ready : in std_logic; out_valid : out std_logic; out_data : out std_logic_vector(ram_width - 1 downto 0) ); end axi_fifo; 

Antarmuka mengikuti konvensi AXI: sisi input menggunakan in_ready dan in_valid, sementara sisi output mencerminkan sinyal dengan arah yang terbalik. Simetri ini memungkinkan beberapa FIFO dirantai dengan lancar.

Deklarasi Sinyal

Pertama, kita mendefinisikan tipe RAM yang cocok dengan lebar dan kedalaman generik, lalu kita membuat instance array:

-- The FIFO is full when the RAM contains ram_depth - 1 elements type ram_type is array (0 to ram_depth - 1) of std_logic_vector(in_data'range); signal ram : ram_type; 

Selanjutnya, kita mendeklarasikan subtype indeks yang dapat mewakili alamat apa pun dalam RAM, dan empat sinyal inti: head, tail, count, dan salinan tertunda count_p1:

subtype index_type is natural range ram_type'range; signal head : index_type; signal tail : index_type; signal count : index_type; signal count_p1 : index_type; 

Kami juga menyimpan versi internal siaran ready dan valid untuk menghindari membaca sinyal out di dalam arsitektur:

signal in_ready_i : std_logic; signal out_valid_i : std_logic; 

Sinyal pembantu melacak saat pembacaan dan penulisan bersamaan terjadi dalam siklus sebelumnya, yang penting untuk menyetel out_valid dengan benar ketika FIFO hampir kosong:

signal read_while_write_p1 : std_logic; 

Subprogram

Fungsi next_index menentukan alamat berikutnya berdasarkan apakah jabat baca atau tulis baru saja selesai. Ia membungkus ketika akhir array tercapai.

function next_index( index : index_type; ready : std_logic; valid : std_logic) return index_type is begin if ready = '1' and valid = '1' then if index = index_type'high then return index_type'low; else return index + 1; end if; end if; return index; end function; 

Prosedur index_proc mengemas logika sinkron yang memperbarui pointer head atau tail. Ini menghindari duplikasi kode dan menjaga arsitektur tetap rapi.

procedure index_proc( signal clk : in std_logic; signal rst : in std_logic; signal index : inout index_type; signal ready : in std_logic; signal valid : in std_logic) is begin if rising_edge(clk) then if rst = '1' then index <= index_type'low; else index <= next_index(index, ready, valid); end if; end if; end procedure; 

Salin Sinyal Internal ke Output

in_ready <= in_ready_i; out_valid <= out_valid_i; 

Perbarui Head dan Tail

Kami membuat instance prosedur pembantu dua kali – sekali untuk pointer tulis (head) dan sekali untuk pointer baca (tail):

PROC_HEAD : index_proc(clk, rst, head, in_ready_i, in_valid); PROC_TAIL : index_proc(clk, rst, tail, out_ready, out_valid_i); 

Simpulkan Block RAM

Block RAM di sebagian besar FPGA adalah sinkron. Untuk memungkinkan sintesis menyimpulkan primitif RAM, kita menjaga operasi baca dan tulis di dalam proses terkoordinasi dan menghindari sinyal enable eksplisit:

PROC_RAM : process(clk) begin if rising_edge(clk) then ram(head) <= in_data; out_data <= ram(next_index(tail, out_ready, out_valid_i)); end if; end process; 

Tulis terjadi tanpa syarat pada siklus ketika in_valid tinggi, dan data baca diperbarui setiap siklus sehingga konsumen dapat mengamati kata yang valid setiap kali FIFO berisi data.

Hitung Jumlah Elemen dalam FIFO

Sinyal count mencerminkan kepaduan saat ini. Ketika head di depan tail, jumlahnya adalah selisihnya; jika head telah membungkus, kita tambahkan kedalaman total:

PROC_COUNT : process(head, tail) begin if head < tail then count <= head - tail + ram_depth; else count <= head - tail; end if; end process; 

Salinan tertunda count_p1 diperlukan untuk mendeteksi ketika FIFO kosong dalam siklus sebelumnya, yang mempengaruhi out_valid:

PROC_COUNT_P1 : process(clk) begin if rising_edge(clk) then if rst = '1' then count_p1 <= 0; else count_p1 <= count; end if; end if; end process; 

Perbarui Output Ready

Penulis harus diberitahu kapan FIFO dapat menerima lebih banyak data. Sinyal ready tinggi setiap kali jumlahnya kurang dari ram_depth - 1:

PROC_IN_READY : process(count) begin if count < ram_depth - 1 then in_ready_i <= '1'; else in_ready_i <= '0'; end if; end process; 

Deteksi Baca dan Tulis Bersamaan

Ketika baca dan tulis terjadi dalam siklus yang sama, FIFO tidak mengubah kepaduan tetapi keadaan internal harus mencerminkan bahwa nilai akan tersedia hanya setelah dua siklus ketika FIFO hampir kosong. Oleh karena itu kita menangkap peristiwa ini di read_while_write_p1:

PROC_READ_WHILE_WRITE_P1: process(clk) begin if rising_edge(clk) then if rst = '1' then read_while_write_p1 <= '0'; else read_while_write_p1 <= '0'; if in_ready_i = '1' and in_valid = '1' and out_ready = '1' and out_valid_i = '1' then read_while_write_p1 <= '1'; end if; end if; end if; end process; 

Perbarui Output Valid

Sinyal out_valid memberitahu logika downstream kapan out_data menyimpan kata yang dapat digunakan. Proses kombinatorial di bawah ini menyetelnya tinggi secara default tetapi menghapusnya dalam dua kasus sudut:

PROC_OUT_VALID : process(count, count_p1, read_while_write_p1) begin out_valid_i <= '1'; -- Jika FIFO kosong atau kosong dalam siklus sebelumnya if count = 0 or count_p1 = 0 then out_valid_i <= '0'; end if; -- Jika baca dan tulis bersamaan terjadi ketika FIFO hanya memiliki satu item if count = 1 and read_while_write_p1 = '1' then out_valid_i <= '0'; end if; end process; 

Kondisi pertama menjamin bahwa out_valid tetap rendah selama penundaan propagasi setelah tulis pertama. Kedua melindungi dari situasi di mana FIFO tampaknya tetap penuh untuk satu siklus tetapi sebenarnya tidak menyimpan data untuk dioutput.

Mensintesis di Vivado

Untuk mensintesis desain ini di Xilinx Vivado, berikan nilai konkret untuk generik. Dalam dialog Settings (General → Generics/Parameters), pilih kedalaman yang cocok dengan primitif RAMB36E1 untuk perangkat Zynq target. Setelah implementasi, penggunaan sumber daya cukup sederhana – satu block RAM plus beberapa LUT dan FF.

Implementasi AXI FIFO di Block RAM dengan Handshake Ready/Valid

Implementasi AXI FIFO di Block RAM dengan Handshake Ready/Valid

AXI lebih dari sekedar ready/valid

AXI (Advanced eXtensible Interface) adalah komponen dari arsitektur bus ARM AMBA dan menawarkan serangkaian fitur yang kaya di luar jabat sederhana ready/valid. Untuk pemahaman yang lebih dalam, pertimbangkan sumber daya berikut:


VHDL

  1. Revolusi Cloud: Bagaimana Komputasi Cloud Mengubah IT, Keamanan, dan Karir
  2. Membuka Data IoT: Bagaimana Manajemen Aturan Bisnis Mendorong Nilai Perusahaan
  3. Menginisialisasi Block RAM FPGA dari Berkas Teks dengan Pustaka TEXTIO VHDL
  4. Menyiapkan Operasi Manufaktur Anda untuk AI dengan IoT
  5. Internet Industri: Merevolusi Manajemen Aset Melalui Konektivitas, Analitik, dan Pengalaman Pengguna
  6. Praktik Terbaik Pelacakan Aset: Membuka Nilai Data Aset Anda
  7. Meningkatkan Wawasan tentang Internet of Things: Memanfaatkan Visualisasi Data dan Database Graf
  8. Memaksimalkan IoT untuk Restoran: Tingkatkan Efisiensi, Kurangi Limbah, dan Kenyati Pelanggan
  9. Rantai Pasok Berbasis Data: Memberdayakan Logistik Masa Depan
  10. Memastikan Data Rantai Pasokan yang Terpercaya: Strategi Terbukti