22 / 24 · Praktikum
Praktikum proyek akhir: FIFO dan kalkulator aliran dua tahap
Hubungkan FIFO masukan berkedalaman dua, dua tahap elastis, dan scoreboard.
Pelajaran dapat dibaca gratis. Daftar untuk menyimpan progres.
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.
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');| Tag | a,b | Hasil lebar | y |
|---|---|---|---|
| 2 | 250,10 | 780 | 12 |
| 3 | 255,255 | 1530 | 250 |
| 5 | 17,240 | 771 | 3 |
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:
iverilog -g2012 -Wall -s tb_dp_stream_calculator -o dp-test.vvp dp_stream_calculator.sv tb_dp_stream_calculator.sv
vvp dp-test.vvpVerifikasi oleh penulis berhasil mengompilasi dan mensimulasikan berkas ini:
RTL PASS: accepted=527 delivered=523 canceled=4 stalls=517 full_replace=64 wraps=262 reset_with_work=1 zero=3Testbench 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.