Mengetik deskripsi perangkat keras dengan teks adalah cara industri membangun chip modern, dan bahasa yang dipakai untuk itu disebut hardware description language (HDL), yakni bahasa deklarasi yang mendeskripsikan rangkaian sebagai daftar komponen beserta sambungannya. Topik ini membahas cara membaca HDL versi nand2tetris, membangun chip Not, And, Or, dan Xor dari NAND, lalu merancang dua gerbang majemuk, yaitu Mux dan DMux, lengkap dengan tabel kebenaran serta diagram arsitekturnya. Seluruh berkas .hdl di sini siap dimuat ke Hardware Simulator untuk disimulasikan.
HDL sebagai deskripsi, bukan program#
HDL terlihat seperti bahasa pemrograman, tetapi semantiknya berbeda secara mendasar. Sebuah program menjalankan pernyataan satu demi satu, sedangkan deskripsi HDL menetapkan sekumpulan komponen yang seluruhnya bekerja serentak. Urutan baris pada bagian PARTS tidak menentukan urutan kerja, melainkan hanya cara pembaca menata daftarnya. Blok IN dan OUT membentuk antarmuka chip, yaitu daftar pin masukan dan keluaran yang terlihat dari luar, sedangkan bagian PARTS berisi daftar subchip beserta pin mana yang tersambung ke pin mana. Perhitungan dilakukan oleh perangkat lunak simulator yang menghitung nilai setiap kabel dari nilai masukannya, sehingga perilaku chip dapat diuji tanpa membangunnya secara fisik.
Membaca struktur sebuah chip#
Struktur terkecil yang perlu dibaca adalah chip satu masukan. Berkas Not.hdl berikut mendefinisikan chip Not dari satu NAND dengan kedua masukannya disambungkan ke sinyal yang sama.
// tidak-dijalankan
// Not: out = kebalikan dari in.
CHIP Not {
IN in;
OUT out;
PARTS:
Nand(a=in, b=in, out=out);
}Blok IN mendeklarasikan pin masukan bernama in, blok OUT mendeklarasikan pin keluaran bernama out, dan bagian PARTS memuat satu baris pemanggilan subchip. Baris Nand(a=in, b=in, out=out) dibaca sebagai: sambungkan pin a dan pin b dari NAND ke kabel in, lalu sambungkan pin out dari NAND ke kabel out. Nama kabel yang sama boleh muncul di banyak tempat karena nama itu selalu berarti kabel yang sama persis. Dengan pola yang sama, chip And dan Or disusun berikut ini, dan keduanya memakai kabel internal yang muncul pertama kali sebagai keluaran sebuah subchip.
// tidak-dijalankan
// And: out = 1 hanya apabila a dan b sama-sama bernilai 1.
CHIP And {
IN a, b;
OUT out;
PARTS:
Nand(a=a, b=b, out=n);
Not(in=n, out=out);
}// tidak-dijalankan
// Or: out = 1 apabila salah satu masukan bernilai 1.
CHIP Or {
IN a, b;
OUT out;
PARTS:
Not(in=a, out=na);
Not(in=b, out=nb);
Nand(a=na, b=nb, out=out);
}Xor dari empat NAND#
Bentuk paling ringkas untuk XOR memakai empat NAND tanpa gerbang lain. Berkas Xor.hdl berikut memakai tiga kabel internal bernama t1, t2, dan t3.
// tidak-dijalankan
// Xor: out = 1 apabila kedua masukan berbeda.
CHIP Xor {
IN a, b;
OUT out;
PARTS:
Nand(a=a, b=b, out=t1);
Nand(a=a, b=t1, out=t2);
Nand(a=b, b=t1, out=t3);
Nand(a=t2, b=t3, out=out);
}Kabel internal (internal pin) adalah nama yang tidak dideklarasikan pada IN atau OUT, melainkan muncul pertama kali sebagai keluaran sebuah subchip dan kemudian dibaca oleh subchip lain. Baris pertama menghitung t1 sebagai NAND dari a dan b. Dua baris berikutnya menggabungkan t1 dengan a dan dengan b secara terpisah, dan baris terakhir menggabungkan t2 serta t3 menjadi out. Untuk kombinasi a=1 dan b=0, nilai t1 adalah 1, nilai t2 adalah 0, dan nilai t3 adalah 1, sehingga out bernilai 1 sesuai tabel kebenaran XOR. Pola empat NAND ini layak diingat karena bentuknya muncul kembali pada rangkaian aritmetika.
Mux dan DMux#
Mux (multiplexer) adalah gerbang majemuk dengan tiga masukan bernama a, b, dan sel. Keluarannya sama dengan a apabila sel bernilai 0 dan sama dengan b apabila sel bernilai 1, sehingga sel berperan memilih salah satu dari dua jalur data.
sel | out | ||
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 0 | 1 |
| 0 | 0 | 1 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 |
Bentukan Mux didapat langsung dari tabelnya, yaitu . Berkas Mux.hdl memuat satu Not, dua And, dan satu Or.
// tidak-dijalankan
// Mux: out = a apabila sel = 0, out = b apabila sel = 1.
CHIP Mux {
IN a, b, sel;
OUT out;
PARTS:
Not(in=sel, out=nsel);
And(a=a, b=nsel, out=w1);
And(a=b, b=sel, out=w2);
Or(a=w1, b=w2, out=out);
}Diagram berikut menggambarkan arsitektur itu. Perhatikan kabel nsel yang membawa kebalikan sel menuju AND pertama, dan perhatikan bahwa kedua jalur AND bertemu pada OR terakhir. Dua persilangan kabel pada diagram hanya menandakan kabel yang saling melintasi tanpa sambungan, sesuai konvensi gambar skematik.
DMux (demultiplexer) melakukan kebalikannya, yaitu mengarahkan satu jalur data menuju salah satu dari dua keluaran. Apabila sel bernilai 0, keluaran a menyalin in dan keluaran b bernilai 0, sedangkan apabila sel bernilai 1, pembagiannya berbalik.
sel | a | b |
|---|---|---|
| 0 | in | 0 |
| 1 | 0 | in |
Bentukan untuk a dan untuk b menghasilkan berkas DMux.hdl berikut.
// tidak-dijalankan
// DMux: a = in dan b = 0 apabila sel = 0, a = 0 dan b = in apabila sel = 1.
CHIP DMux {
IN in, sel;
OUT a, b;
PARTS:
Not(in=sel, out=nsel);
And(a=in, b=nsel, out=a);
And(a=in, b=sel, out=b);
}Mux dan DMux menjadi sepasang alat pengarah jalur data yang dipakai hampir di semua chip yang lebih besar, mulai dari ALU yang memilih operasi sampai memori yang memilih lokasi.
Kesalahan umum#
Nama pin pada HDL bersifat peka huruf besar dan huruf kecil, sehingga pemanggilan Nand(A=in, b=in) ditolak oleh simulator dengan pesan error. Kesalahan kedua adalah memanggil pin dengan nama yang keliru, misalnya Nand(in=in) padahal pin masukan NAND bernama a dan b. Simulator melaporkan error pin yang tidak dikenal, dan pesan itu biasanya disertai nomor barisnya. Kesalahan ketiga adalah memperlakukan urutan baris PARTS sebagai urutan eksekusi, lalu kebingungan muncul ketika menata ulang baris ternyata tidak mengubah hasil. Penataan ulang memang sah karena seluruh subchip bekerja serentak. Kesalahan keempat adalah lupa menyambungkan keluaran sebuah subchip ke mana pun, sehingga kabel internal menggantung dan keluaran chip menjadi tidak lengkap. Membaca pesan error simulator dengan teliti jauh lebih cepat daripada menebak sambungan yang salah.
Ringkasan#
- HDL mendeskripsikan rangkaian sebagai daftar subchip yang bekerja serentak, dengan antarmuka IN dan OUT serta bagian PARTS.
- Not, And, Or, dan Xor dapat disusun dari NAND, dan Xor paling ringkas memakai empat NAND dengan tiga kabel internal.
- Mux memilih salah satu dari dua jalur data berdasarkan
sel, sedangkan DMux mengarahkan satu jalur menuju salah satu dari dua keluaran. - Kabel internal adalah nama yang dihitung oleh satu subchip dan dibaca oleh subchip lain.
Referensi#
- The Elements of Computing Systems, Second Edition — Nand2Tetris — Situs resmi yang menyediakan Hardware Simulator, spesifikasi HDL, dan proyek pembangunan chip.
- Computation Structures, Spring 2017 — MIT OpenCourseWare — Materi kuliah tentang multiplexer dan deskripsi rangkaian digital.