Altifigence Academy

22 / 24 · Praktikum

Praktikum proyek akhir: FIFO dan kalkulator aliran dua tahap

Hubungkan FIFO masukan berkedalaman dua, dua tahap elastis, dan scoreboard.

Gabungkan penyimpanan, komputasi, dan pengiriman

Proyek akhir memiliki FIFO masukan dua entri dan dua tahap komputasi elastis. Tahap pertama menyimpan jumlah sembilan bit a+b; tahap kedua menyimpan 3×sum modulo 256. Tag mengikuti setiap nilai. Kapasitas total adalah empat transaksi. Tekanan balik merambat dari keluaran sementara slot kosong masih dapat diisi. Asumsikan satu clock, FIFO berregister, pop/push serentak, dan tidak ada pelewatan langsung ke keluaran.

Simpan capstone-model.mjs secara manual dan jalankan node capstone-model.mjs. Hitung seluruh kesiapan dan nilai tahap berikutnya dari keadaan lama sebelum memperbarui FIFO dan register. Larik JavaScript merupakan antrean fungsional, bukan HDL yang dapat disintesis.

javascript
import assert from 'node:assert/strict';
const input = [[0,0],[1,2],[250,10],[255,255],
               [128,128],[17,240],[90,90],[4,8]];
const q = [], expected = [], seen = [];
let s1 = null, s2 = null, issued = 0, delivered = 0;
for (let edge = 0; edge < 50; edge++) {
  const ready = edge >= 25 || ![2,3,4].includes(edge % 7);
  const old1 = s1, old2 = s2;
  const r2 = old2 === null || ready;
  const r1 = old1 === null || r2;
  const pop = q.length > 0 && r1;
  const inReady = q.length < 2 || pop;
  if (old2 !== null && ready) {
    assert.deepEqual(old2, expected.shift());
    seen.push(old2.y);
    delivered++;
  }
  const n2 = r2 ? (old1 === null ? null :
    { tag: old1.tag, y: old1.sum * 3 % 256 }) : old2;
  const n1 = r1 ? (pop ?
    { tag: q[0].tag, sum: q[0].a + q[0].b } : null) : old1;
  if (pop) q.shift();
  if (issued < input.length && inReady) {
    const [a,b] = input[issued];
    q.push({ tag: issued, a, b });
    expected.push({ tag: issued, y: (3*a + 3*b) % 256 });
    issued++;
  }
  s1 = n1; s2 = n2;
  if (old2 !== null && !ready) assert.deepEqual(s2, old2);
  assert.ok(q.length <= 2);
  assert.equal(issued - delivered,
    q.length + Number(s1 !== null) + Number(s2 !== null));
}
assert.equal(issued, input.length);
assert.equal(delivered, input.length);
assert.deepEqual(seen, [0,9,12,250,0,3,28,36]);
assert.equal(expected.length + q.length, 0);
assert.equal(s1, null); assert.equal(s2, null);
console.log('CAPSTONE PASS: 8 ordered outputs, drained');
Taga,bHasil lebary
2250,1078012
3255,2551530250
517,2407713

Masukan pertama masuk ke FIFO pada tepi 0, s1 pada tepi 1, dan s2 pada tepi 2. Penundaan penerima pada tepi 2,3,4 menunda pengirimannya hingga tepi 5. Latensi tanpa penundaan adalah tiga tepi; transaksi ini membutuhkan lima. Penyimpanan kosong lainnya terisi sementara s2 menahan nilai.

Antrean acuan menghitung nilai harapan hanya saat penerimaan. Bandingkan tag dan hasil saat pengiriman serta periksa okupansi pada setiap tepi. Setelah tepi 25, kuras semuanya. Eksekusi Node memeriksa delapan hasil berurutan; berkas SystemVerilog di bawah secara independen menguji register FIFO dan pipeline sebenarnya.

Bangun dan simulasikan RTL

Unduh dp_stream_calculator.sv dan tb_dp_stream_calculator.sv ke satu folder. Antarmuka a,b,tag delapan bit tak bertanda menerima pada in-valid/in-ready dan mengirim y bersama tag pada out-valid/out-ready. Jumlah sembilan bit dan nilai berskala sebelas bit dipersempit hanya pada keluaran. Reset mengosongkan penyimpanan dan menekan transfer.

Jalankan dengan Icarus Verilog terpasang:

text
iverilog -g2012 -Wall -s tb_dp_stream_calculator -o dp-test.vvp dp_stream_calculator.sv tb_dp_stream_calculator.sv
vvp dp-test.vvp

Verifikasi oleh penulis berhasil mengompilasi dan mensimulasikan berkas ini:

text
RTL PASS: accepted=527 delivered=523 canceled=4 stalls=517 full_replace=64 wraps=262 reset_with_work=1 zero=3

Testbench memeriksa aritmetika, tag, urutan, penundaan, penggantian saat penuh, perputaran penunjuk, pembatalan empat item saat reset, dan pengurasan. Ubah durasi penundaan dan bandingkan latensi dengan tiga siklus tanpa penundaan. Ini memverifikasi simulasi RTL Icarus, bukan sintesis, pewaktuan fisik, atau eksekusi DDS.

Coba sendiri

Dengan penerima selalu siap, pada tepi mana tag0 ditransfer? Jika kedalaman FIFO menjadi satu, apa yang terjadi pada latensi tanpa penundaan dan kapasitas total?

Baca penjelasan

Tag0 ditransfer pada tepi 3 setelah penerimaan pada 0, s1 pada 1, dan s2 pada 2. Mempertahankan FIFO berregister menjaga latensi tiga tepi; kapasitas turun menjadi 1+1+1=3 transaksi. Ubah batas kedalaman input-ready dan periksa kembali model.

Lesson files

capstone-model.mjs ↓dp_stream_calculator.sv ↓tb_dp_stream_calculator.sv ↓

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