Gerbang (gate) adalah komponen perangkat keras yang mengimplementasikan satu operasi boolean atas sinyal listrik, dengan masukan berupa nilai 0 atau 1 dan keluaran yang mengikuti tabel kebenaran operasinya. Topik ini mendefinisikan gerbang NOT, AND, OR, NAND, dan XOR secara mekanis dari tabel kebenarannya, menyusun keempat gerbang lainnya dari NAND dalam program Python, lalu menguji perilakunya melalui demo interaktif. Setelah topik ini, perilaku setiap gerbang dapat diprediksi dari tabel kebenarannya, dan cara menyusun gerbang apa pun dari NAND sudah tampak dalam kode.
Definisi mekanis dari tabel kebenaran#
Sebuah gerbang didefinisikan sepenuhnya oleh tabel kebenarannya, tanpa perlu mengetahui isi fisik di dalamnya. Masukan berjumlah satu bit atau lebih, dan setiap baris tabel menetapkan keluaran untuk satu kombinasi masukan. Gerbang dengan dua masukan memiliki empat baris karena dua bit menghasilkan kombinasi. Tabel berikut merangkum kelima gerbang yang dipakai di sepanjang modul ini.
| 0 | 0 | 1 | 0 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 | 1 | 1 | 1 |
| 1 | 1 | 0 | 1 | 1 | 0 | 0 |
Tabel itu adalah kontrak lengkap sebuah gerbang. Keluaran NOT hanya bergantung pada , sedangkan empat gerbang lain membaca kedua masukan. Sebutan NAND merupakan singkatan dari not AND, yaitu AND yang keluarannya dinegasikan, sehingga kolom NAND menjadi kebalikan kolom AND pada setiap baris. NOT dipandang sebagai gerbang satu masukan yang berperan sebagai pembalik sinyal pada rangkaian nyata. Dengan lima definisi ini, pembahasan tidak perlu turun ke tingkat transistor, karena seluruh perilakunya sudah terikat oleh tabel.
NAND sebagai gerbang universal#
NAND menempati posisi istimewa karena empat gerbang lain dapat disusun dari NAND saja. Sifat ini disebut sifat universal, dan seluruh jalur ini menjadikannya fondasi pembangunan chip. NOT diperoleh dengan menghubungkan kedua masukan NAND ke sinyal yang sama. AND diperoleh dengan membalik kembali keluaran NAND lewat NOT, sedangkan OR diperoleh lewat hukum de Morgan, . XOR disusun dari dua suku mintermnya, yaitu dan , yang masing-masing dibangun dari NOT dan AND lalu digabungkan oleh OR.
Alasan NAND dipilih sebagai fondasi bersifat teknis dan ekonomis. NAND umumnya memerlukan lebih sedikit transistor dan bekerja lebih cepat daripada gerbang AND atau OR yang setara, sehingga NAND menjadi gerbang yang paling murah untuk diproduksi. Dengan satu jenis gerbang saja, seluruh rangkaian kombinasional (rangkaian yang keluarannya hanya ditentukan oleh kombinasi masukan) dapat dibangun, dan cukup satu jenis itulah yang harus dipercaya pada tingkat fisik. Tiga bentukan dasar dari NAND, yaitu NOT, AND, dan OR, karenanya perlu dikuasai sebelum maju ke chip yang lebih besar.
Implementasi kelima gerbang dalam Python#
Python dapat memperagakan kelima gerbang tersebut sebagai fungsi biasa yang bekerja pada nilai 0 dan 1. Fungsi nand() menjadi satu-satunya primitif, dan fungsi tidak(), dan(), atau(), serta xor() didefinisikan hanya dengan memanggil nand(), persis seperti susunan gerbang pada bagian sebelumnya. Program berikut mencetak tabel kebenaran kelima gerbang itu.
"""Gerbang dasar yang disusun dari satu gerbang NAND.
Fungsi tidak(), dan(), atau(), dan xor() didefinisikan hanya melalui
fungsi nand(), meniru cara chip pada modul ini dibangun dari NAND.
"""
def nand(a, b):
"""Keluaran 0 hanya apabila kedua masukan bernilai 1."""
return 1 - (a & b)
def tidak(a):
"""NOT dari NAND dengan kedua masukan yang sama."""
return nand(a, a)
def dan(a, b):
"""AND dari NAND yang keluarannya dinegasikan kembali."""
return nand(nand(a, b), nand(a, b))
def atau(a, b):
"""OR dari NAND atas dua masukan yang sudah dinegasikan."""
return nand(tidak(a), tidak(b))
def xor(a, b):
"""XOR dari dua suku mintermnya."""
return atau(dan(a, tidak(b)), dan(tidak(a), b))
def tampilkan(nama, f, jumlah_masukan):
print(f"{nama}:")
if jumlah_masukan == 1:
for a in (0, 1):
print(f" {a} -> {f(a)}")
else:
for a in (0, 1):
for b in (0, 1):
print(f" {a} {b} -> {f(a, b)}")
tampilkan("NAND", nand, 2)
tampilkan("NOT", tidak, 1)
tampilkan("AND", dan, 2)
tampilkan("OR", atau, 2)
tampilkan("XOR", xor, 2)NAND:
0 0 -> 1
0 1 -> 1
1 0 -> 1
1 1 -> 0
NOT:
0 -> 1
1 -> 0
AND:
0 0 -> 0
0 1 -> 0
1 0 -> 0
1 1 -> 1
OR:
0 0 -> 0
0 1 -> 1
1 0 -> 1
1 1 -> 1
XOR:
0 0 -> 0
0 1 -> 1
1 0 -> 1
1 1 -> 0Setiap baris keluaran cocok dengan tabel kebenaran pada bagian pembuka. Nilai 0 dan 1 di sini adalah bilangan Python biasa, tetapi penamaan fungsinya mengikuti konvensi perangkat keras, sehingga penerjemahan menuju HDL menjadi langsung. Struktur programnya juga meniru susunan chip: satu primitif, lalu fungsi-fungsi yang tersusun di atasnya.
Mencoba gerbang secara interaktif#
Tabel kebenaran menjadi jauh lebih mudah diingat setelah perilakunya dicoba langsung. Jalankan demo berikut, klik tombol A dan B untuk mengganti nilai masukan dari 0 menjadi 1, lalu amati lampu keluaran yang menyala atau mati. Ganti pilihan gerbang pada menu AND, OR, NAND, dan XOR, kemudian bandingkan bagaimana kombinasi masukan yang sama menghasilkan keluaran yang berbeda. Amati pula pola NAND sebagai kebalikan AND, serta keluaran XOR yang hanya menyala apabila kedua masukan berbeda. Baris di bawah demo menampilkan persamaan yang sedang diuji, sehingga setiap keadaan lampu dapat dicocokkan dengan baris tabel kebenaran pada bagian pembuka.
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<title>Demo gerbang logika</title>
<style>
body { font-family: system-ui, sans-serif; margin: 0; padding: 14px; background: #f8fafc; color: #0f172a; }
.baris { display: flex; align-items: flex-start; gap: 18px; flex-wrap: wrap; justify-content: center; }
button.tombol { font-size: 16px; padding: 10px 18px; border-radius: 8px; border: 2px solid #64748b; background: #ffffff; cursor: pointer; }
button.tombol.satu { border-color: #b45309; background: #fde68a; }
select { font-size: 15px; padding: 9px 10px; border-radius: 8px; margin-top: 2px; }
.kolom { text-align: center; }
.lampu { width: 42px; height: 42px; border-radius: 50%; background: #1e293b; border: 3px solid #475569; display: inline-block; transition: background 0.15s, box-shadow 0.15s; }
.lampu.nyala { background: #fbbf24; box-shadow: 0 0 16px 4px #fbbf24; border-color: #b45309; }
.label { font-size: 13px; color: #475569; margin-top: 6px; }
.hasil { font-family: monospace; font-size: 15px; margin-top: 16px; text-align: center; }
</style>
</head>
<body>
<div class="baris">
<div class="kolom">
<button id="tombol-a" class="tombol" type="button" aria-pressed="false">A = 0</button>
<div class="label">masukan A</div>
</div>
<div class="kolom">
<select id="pilihan" aria-label="Pilihan gerbang">
<option value="AND">AND</option>
<option value="OR">OR</option>
<option value="NAND">NAND</option>
<option value="XOR">XOR</option>
</select>
<div class="label">pilihan gerbang</div>
</div>
<div class="kolom">
<button id="tombol-b" class="tombol" type="button" aria-pressed="false">B = 0</button>
<div class="label">masukan B</div>
</div>
<div class="kolom">
<div id="lampu" class="lampu" role="img" aria-label="Lampu keluaran mati"></div>
<div class="label">out</div>
</div>
</div>
<div id="hasil" class="hasil">0 AND 0 = 0</div>
<script>
var a = 0, b = 0;
var gerbang = {
AND: function (x, y) { return x & y; },
OR: function (x, y) { return x | y; },
NAND: function (x, y) { return 1 - (x & y); },
XOR: function (x, y) { return x ^ y; }
};
function perbarui() {
var nama = document.getElementById('pilihan').value;
var out = gerbang[nama](a, b);
var ta = document.getElementById('tombol-a');
var tb = document.getElementById('tombol-b');
ta.textContent = 'A = ' + a;
ta.classList.toggle('satu', a === 1);
ta.setAttribute('aria-pressed', a === 1 ? 'true' : 'false');
tb.textContent = 'B = ' + b;
tb.classList.toggle('satu', b === 1);
tb.setAttribute('aria-pressed', b === 1 ? 'true' : 'false');
var lampu = document.getElementById('lampu');
lampu.classList.toggle('nyala', out === 1);
lampu.setAttribute('aria-label', out === 1 ? 'Lampu keluaran menyala' : 'Lampu keluaran mati');
document.getElementById('hasil').textContent = a + ' ' + nama + ' ' + b + ' = ' + out;
}
document.getElementById('tombol-a').addEventListener('click', function () { a = 1 - a; perbarui(); });
document.getElementById('tombol-b').addEventListener('click', function () { b = 1 - b; perbarui(); });
document.getElementById('pilihan').addEventListener('change', perbarui);
perbarui();
</script>
</body>
</html>Kesalahan umum#
Membaca NAND sebagai AND yang disertai pembalik terpisah sering menimbulkan kekeliruan gambar rangkaian, padahal NAND adalah satu gerbang tunggal dengan satu simbol dan satu tabel kebenaran. Kekeliruan kedua adalah memperlakukan susunan gerbang sebagai langkah bernomor, seolah-olah rangkaian mengeksekusi gerbang satu per satu dari kiri ke kanan. Padahal seluruh gerbang pada rangkaian kombinasional bekerja serentak, dan hanya bentuk sambungan kabelnya yang menentukan hasil. Kekeliruan ketiga adalah mengabaikan urutan pengerjaan operator, misalnya membaca tanpa menyadari bahwa NOT bekerja lebih dahulu, kemudian AND, dan OR paling akhir. Apabila urutan ini diabaikan, tabel kebenaran yang dibaca menjadi berbeda dari rangkaian yang dibangun. Menggambar tabel kebenaran secara manual untuk setiap susunan baru tetap menjadi cara paling aman untuk memeriksa.
Ringkasan#
- Tabel kebenaran adalah definisi lengkap sebuah gerbang, dan gerbang dua masukan memiliki empat baris.
- NAND bersifat universal karena NOT, AND, OR, dan XOR dapat disusun dari NAND saja.
- Urutan pengerjaan NOT, AND, OR menentukan pembacaan ekspresi dan bentuk rangkaiannya.
- Fungsi Python pada nilai 0 dan 1 dapat meniru perilaku kelima gerbang secara persis.
Referensi#
- The Elements of Computing Systems, Second Edition — Nand2Tetris — Proyek 1 membimbing pembangunan seluruh gerbang dasar dimulai dari NAND.
- Computation Structures, Spring 2017 — MIT OpenCourseWare — Materi kuliah yang memperkenalkan gerbang logika dan tabel kebenarannya.