Altifigence Academy

57 / 63 · Konsep

FIFO satu clock: pointer dan kebijakan batas

Implementasikan pointer dan occupancy FIFO empat tempat dengan penerimaan eksplisit saat kosong dan penuh.

Menjaga urutan tanpa memindahkan data

FIFOFIFO Antrean yang mengeluarkan data masuk pertama lebih dahulu. Aturan penuh, kosong, dan baca/tulis bersamaan merupakan bagian kontrak. mengeluarkan data yang masuk dahulu. Di sini satu tepi clock menentukan baca/tulis, dengan DEPTH=4 dan data delapan bit. rptr menunjuk elemen berikutnya untuk dikeluarkan, wptr posisi berikutnya untuk ditulis. Masing-masing dua bit berputar alami dari 3 ke 0. Okupansi 0–4 memerlukan tiga bit.

rptr=wptr dapat terjadi saat kosong maupun penuh. Menentukan empty hanya dari kesamaan ini menghilangkan data FIFO penuh. Simpan jumlah CC: empty=(C=0)\mathrm{empty}=(C=0), full=(C=4)\mathrm{full}=(C=4). Untuk kedalaman D=4D=4, lebar alamat WaddrW_{\mathrm{addr}} dan lebar jumlah WcountW_{\mathrm{count}} adalah:

Waddr=⌈log⁡2D⌉=2Wcount=⌈log⁡2(D+1)⌉=3\begin{aligned} W_{\mathrm{addr}}&=\lceil\log_2 D\rceil=2\\ W_{\mathrm{count}}&=\lceil\log_2(D+1)\rceil=3 \end{aligned}

Bedakan permintaan dan penerimaan pada batas

push dan pop adalah permintaan. p serta q adalah penerimaan aktualnya, dihitung dari keadaan sebelum tepi tanpa reset:

q=pop∧(C>0)p=push∧((C<4)∨q)C+=C+p−q\begin{aligned} q&=\mathrm{pop}\land(C>0)\\ p&=\mathrm{push}\land((C<4)\lor q)\\ C^{+}&=C+p-q \end{aligned}

Saat kosong, dua permintaan hanya menerima push karena tidak ada data lama; data baru tidak langsung keluar. Saat penuh, pop membebaskan posisi head lama sehingga keduanya diterima. full berarti “empat elemen sedang tersimpan”, bukan larangan push mutlak.

Keadaan sebelum tepipush sajapop sajapush dan pop
C=0Simpan satuDitolakpush saja, C=1
0<C<4C+1C−1Keduanya, C tetap
C=4DitolakC=3Keduanya, C=4

Periksa batas dengan memajukan clock

Mulai dengan push dan pop bersamaan saat kosong: hanya push diterima. Matikan pop dan isi empat tempat. Aktifkan keduanya dengan data baru: okupansi tetap 4, head lama keluar dan tail baru tersimpan.

Jalankan FIFO per clock

FIFO empat slot. Awalnya kosong; pointer baca dan tulis bernilai 0. Terima pop ketika tidak kosong. Terima push jika ada ruang atau pop diterima pada tepi yang sama.

Model menunjukkan keadaan setelah setiap tepi naikTepi naik Saat clock berubah 0 ke 1, berbeda dari tingkat yang mencakup seluruh interval CLK=1. Selengkapnya. Pop diterima membuat output valid=1; jika tepi berikutnya tidak menerima pop, data registerRegister Rangkaian penyimpan beberapa bit keadaan. Register sinkron mata kuliah ini menangkap masukan yang ditentukan pada tepi clock. Selengkapnya tetap tetapi valid=0. Bit lama pada slot kosong disembunyikan. “Mulai ulang” menginisialisasi seluruh praktikum, bukan menunjukkan resetReset Kontrol yang mengembalikan keadaan ke nilai awal tertentu. Sifat sinkron/asinkron dan prioritas terhadap kontrol lain harus ditetapkan. Selengkapnya memori RTL.

RTL dengan keluaran berregister

SystemVerilog
module fifo4 (
  input  logic       clk, rst, push, pop,
  input  logic [7:0] din,
  output logic [7:0] dout,
  output logic       dout_valid, full, empty,
  output logic [2:0] occupancy
);
  timeunit 1ns;
  timeprecision 1ps;
  logic [7:0] mem [0:3];
  logic [1:0] rptr, wptr;
  logic take_push, take_pop;

  assign empty = (occupancy == 3'd0);
  assign full  = (occupancy == 3'd4);
  assign take_pop  = !rst && pop && !empty;
  assign take_push = !rst && push && (!full || take_pop);

  always_ff @(posedge clk) begin
    if (rst) begin
      rptr <= 2'd0;
      wptr <= 2'd0;
      occupancy <= 3'd0;
      dout_valid <= 1'b0;
    end else begin
      dout_valid <= take_pop;
      if (take_push) begin
        mem[wptr] <= din;
        wptr <= wptr + 2'd1;
      end
      if (take_pop) begin
        dout <= mem[rptr];
        rptr <= rptr + 2'd1;
      end
      case ({take_push, take_pop})
        2'b10: occupancy <= occupancy + 3'd1;
        2'b01: occupancy <= occupancy - 3'd1;
        default: occupancy <= occupancy;
      endcase
    end
  end
endmodule

occupancy tidak dinaikkan dan diturunkan melalui dua if independen: dua penugasan nonblockingNonblocking Penugasan <= pada RTL sekuensial: sisi kanan dievaluasi lalu pembaruan dijadwalkan, sehingga register pada tepi sama menghitung dari keadaan lama. Selengkapnya pada register sama akan menyisakan penugasan terakhir. Setiap pointer maju ketika diterima; count menentukan empat kasus sekaligus. Kondisi juga mencegah penurunan dari 0 atau kenaikan dari 4.

Baca dan tulis slot sama saat penuh

Setelah A,B,C,D, rptr=wptr=0 dan occupancy=4. Dengan pop=push=1,din=E, setelah tepi dout=A,dout_valid=1 dan antrean logis [B,C,D,E]. Kedua pointer menjadi 1 dan count tetap 4. mem[0] menjadi E, tetapi dout membaca A lama dari sisi kanan nonblocking. Konflik read-first ini wajib untuk penggantian saat penuh.

Pop saja berikutnya mengeluarkan B dan jumlah menjadi 3. Sebaliknya, saat kosong, kedua permintaan dengan din=Z memberi occupancy=1,dout_valid=0; diperlukan pop pada tepi berikutnya untuk mengeluarkan Z. Penerusan langsung saat kosong dan penggantian saat penuh adalah pilihan berbeda.

Reset sinkron active-high menginisialisasi pointer, count, dan dout_valid, bukan memori atau dout. Setelah reset, empty melarang pop bit lama dan hanya posisi yang baru ditulis dibaca kemudian: reset seluruh array tidak diperlukan untuk operasi normal. Jangan konsumsi dout saat valid=0. valid=1 adalah respons pop diterima; tanpa ready keluaran, konsumen harus menerima respons itu.

Kedalaman bukan pangkat dua tidak dapat memakai wrap alami sama: untuk kedalaman 3, alamat 2 harus eksplisit kembali ke 0. Jika sintesis memakai RAM, periksa perilaku old-data pada konflik. Kode ini satu clock, bukan pengganti sinkronisasi pointer FIFO asinkron.

Coba sendiri

Setelah reset, berikan tiap tepi: (1) push A dan pop, (2) push B, (3) push C, (4) push D, (5) push E dan pop, (6) pop. Tentukan antrean, occupancy, dout_valid, dan data valid tiap langkah. Mengapa read-first diperlukan pada langkah 5?

Baca penjelasan

(1) [A],1,valid=0. (2) [A,B],2,valid=0. (3) [A,B,C],3,valid=0. (4) [A,B,C,D],4,valid=0. (5) [B,C,D,E],4,valid=1,dout=A. (6) [C,D,E],3,valid=1,dout=B. Langkah pertama tidak memiliki data lama sehingga pop ditolak. Langkah kelima rptr=wptr=0 dan slot sama dibaca/ditulis: A lama harus keluar. Write-first yang mengembalikan E merusak urutan serta isi FIFO. Keluaran valid=0 tidak dinilai.

Pilihan berlaku di peramban ini. Ubah kapan saja di bagian bawah halaman.