RAM (Random Access Memory) adalah memori baca-tulis yang menyimpan banyak kata dengan waktu akses yang sama untuk setiap alamat. Dari sudut pandang perangkat keras, RAM bukan komponen yang misterius, melainkan larik besar dari register multi-bit beserta mekanisme alamat untuk memilih satu kata di antaranya. Topik ini membahas jalur alamat, decoder, chip select, kapasitas dalam kata, dan waktu akses, lalu menutupnya dengan simulasi kelas Ram pada memori 16 kata.
Memori sebagai larik register#
Bayangkan 16 register 8 bit yang disusun berjajar dan berbagi clock yang sama. Larik itulah bentuk dasar sebuah RAM kecil. Setiap posisi penyimpanan disebut kata memori (memory word) dan dijangkau melalui nomor urutnya yang disebut alamat. Perbedaannya dengan register file terletak pada skala dan tujuan, yaitu register file berada rapat di samping ALU dan hanya memuat sedikit register, sedangkan RAM menampung jutaan hingga miliaran kata untuk program dan data.
Karena setiap kata berperilaku seperti register, penulisan ke RAM hanya berlaku pada tepi naik clock, dan nilai yang sudah tertulis bertahan selama catu daya tersedia. Sifat bertahan selama daya tersedia inilah yang membuat RAM disebut memori volatil (volatile), yaitu memori yang seluruh isinya hilang ketika daya dimatikan. Perilaku baca pun tetap dalam disiplin clock, sehingga pembacaan satu kata dan pembacaan kata lain memakan satu langkah yang identik. Keseragaman itulah yang membuat kata “acak” pada namanya bermakna, yaitu alamat mana pun dijangkau dengan waktu yang sama.
Alamat dan decoder#
Alamat dinyatakan sebagai deretan bit, dan jumlah bit itu menentukan kapasitas yang dapat dijangkau. Sebuah memori dengan n bit alamat menampung kata, sehingga 8 bit alamat menjangkau 256 kata dan 16 bit menjangkau 65.536 kata. Kebalikannya berlaku saat merancang kapasitas, yaitu memori berkapasitas m kata membutuhkan bit alamat. Memori 16 kata membutuhkan 4 bit alamat karena .
Decoder menerjemahkan nilai alamat menjadi pilihan yang tidak ambigu. Komponen ini menerima 4 bit alamat dan mengaktifkan tepat satu dari 16 garis keluaran, yaitu garis yang nomornya sama dengan nilai alamat. Hanya kata yang terhubung ke garis aktif itu yang membuka gerbang baca dan tulisnya, sedangkan kata lain tetap terkunci. Pola satu-dari-banyak ini menjamin satu alamat memilih tepat satu kata pada setiap tepi clock, dan fragmen berikut menunjukkan polanya dalam satu baris Python.
alamat = 0b0101 # nilai alamat 4 bit, yaitu 5
garis = [1 if nomor == alamat else 0 for nomor in range(16)]
print("garis aktif:", "".join(str(b) for b in garis))garis aktif: 0000010000000000Keluaran di atas memperlihatkan bit 1 tepat pada posisi kelima, dihitung dari nol, dan nol di tempat lain. Pada silikon sungguhan, garis-garis itu adalah jalur fisik yang masing-masing menyentuh satu kata. Nilai alamat pada satu tepi dengan demikian cukup untuk membuka satu kata dan mengunci seluruh kata lain.
Chip select#
Memori besar pada sistem nyata disusun dari beberapa chip yang lebih kecil, misalnya empat chip 16 kata yang membentuk 64 kata. Setiap chip diberi sinyal chip select, yaitu sakelar yang menentukan apakah chip itu merespons alamat yang sedang beredar di bus. Bila chip select aktif, chip membaca dan menulis seperti biasa, sedangkan bila nonaktif, seluruh kata memori di dalamnya terputus dari bus. Decoder pada tingkat sistem memilih chip, dan decoder di dalam chip memilih kata, sehingga alamat efektifnya terbagi menjadi dua bagian.
Tanpa chip select, dua chip yang dipasang paralel pada bus yang sama akan saling bertabrakan, karena keduanya mencoba menyalurkan keluaran pada saat yang bersamaan. Sinyal ini sekaligus berperan sebagai proteksi, karena tulisan hanya menyentuh chip yang dipilih dan isi chip yang tidak dipilih tetap aman. Dengan mekanisme ini, kapasitas memori dapat ditambah dengan menambah chip, tanpa mengubah cara kata di dalam setiap chip dijangkau. Pada simulasi di bagian akhir, satu penulisan sengaja dijalankan dengan chip select 0 untuk menunjukkan bahwa isi pada alamat yang dituju tidak berubah sama sekali.
Waktu akses dan biayanya#
Waktu akses (access time) adalah jeda dari alamat yang stabil sampai data keluar dengan benar. Pada RAM, jeda itu tersusun dari beberapa tahap yang ditempuh berurutan, yaitu decoder memilih garis, sel memori pada garis itu membuka jalurnya, lalu sinyal yang lemah dipenguat menjadi nilai 0 atau 1 yang andal. Setiap tahap membawa penundaan propagasi, dan jumlahnya jauh melampaui satu gerbang tunggal.
Register berada dalam situasi yang jauh lebih menguntungkan. Register file hanya memuat sedikit kata, jalurnya pendek, dan semuanya berada rapat di samping ALU, sehingga baca dan tulisnya selesai dalam satu langkah clock prosesor. RAM harus mengendalikan jutaan sel di atas luas silikon yang jauh lebih besar, sehingga jalurnya panjang dan beban kapasitifnya tinggi. Inilah alasan mendasar mengapa satu akses RAM memakan waktu puluhan hingga ratusan kali akses register.
Modul hierarki memori menyingkap mengapa kelambatan RAM berdampak besar pada performa dan menelusuri cache sebagai jawaban atas masalah itu. Untuk keperluan jalur ini, model yang dipakai cukup menyatakan satu akses RAM sebagai satu langkah penuh, dengan kesadaran bahwa langkah itu mahal. Penyederhanaan seperti ini sudah cukup untuk membangun CPU yang benar, sedangkan pengoptimalan kecepatannya dikerjakan pada tingkat yang lebih tinggi.
Simulasi RAM#
Kelas Ram memodelkan memori 16 kata berukuran 8 bit. Penulisan hanya dilakukan pada tepi naik dan hanya bila chip select aktif, sedangkan pembacaan dimodelkan sebagai pencarian larik Python. Jumlah bit alamat dihitung dari kapasitas memakai rumus logaritma yang sudah dibahas, dan satu penulisan dijadwalkan dengan chip select 0.
# Simulasi RAM kecil: larik kata 8 bit yang dipilih melalui alamat.
# Penulisan terjadi pada tepi naik dan hanya bila chip select aktif.
class Ram:
"""RAM dengan kapasitas tertentu dalam kata berukuran 8 bit."""
def __init__(self, jumlah_kata):
self.kata = [0] * jumlah_kata # seluruh isi dimulai dari nol
self.bit_alamat = (jumlah_kata - 1).bit_length()
def tulis(self, alamat, nilai, chip_select=1):
"""Tulis satu kata pada tepi naik, hanya bila chip dipilih."""
self._periksa(alamat)
if chip_select == 1:
self.kata[alamat] = nilai & 0xFF
def baca(self, alamat):
"""Baca nilai satu kata pada alamat yang diberikan."""
self._periksa(alamat)
return self.kata[alamat]
def _periksa(self, alamat):
if not 0 <= alamat < len(self.kata):
raise ValueError(f"alamat {alamat} di luar jangkauan")
memori = Ram(16) # 16 kata membutuhkan 4 bit alamat
print(f"{memori.bit_alamat} bit alamat untuk {len(memori.kata)} kata")
memori.tulis(3, 42)
memori.tulis(0, 7)
memori.tulis(15, 255)
memori.tulis(8, 100)
memori.tulis(4, 11, chip_select=0) # chip tidak dipilih, tulisan diabaikan
print("\nBaca kembali beberapa alamat:")
for alamat in (0, 3, 4, 8, 15):
print(f" alamat {alamat:2d} -> {memori.baca(alamat):3d}")
print("\nIsi seluruh memori:")
for alamat, isi in enumerate(memori.kata):
print(f" alamat {alamat:2d} : {isi:3d}")4 bit alamat untuk 16 kata
Baca kembali beberapa alamat:
alamat 0 -> 7
alamat 3 -> 42
alamat 4 -> 0
alamat 8 -> 100
alamat 15 -> 255
Isi seluruh memori:
alamat 0 : 7
alamat 1 : 0
alamat 2 : 0
alamat 3 : 42
alamat 4 : 0
alamat 5 : 0
alamat 6 : 0
alamat 7 : 0
alamat 8 : 100
alamat 9 : 0
alamat 10 : 0
alamat 11 : 0
alamat 12 : 0
alamat 13 : 0
alamat 14 : 0
alamat 15 : 255Bacaan pada alamat 4 mengembalikan 0, karena satu-satunya tulisan ke alamat itu dijalankan dengan chip select 0 dan oleh karena itu diabaikan. Tulisan ke alamat 15 menunjukkan bahwa alamat tertinggi yang sah untuk 16 kata adalah 15, bukan 16, karena penomoran dimulai dari 0. Pemeriksaan jangkauan pada metode _periksa menolak alamat di luar 0 sampai 15 dengan melempar error, dan kegagalan yang muncul sedini itu jauh lebih mudah dilacak daripada penimpaan yang terjadi diam-diam. Keluaran juga menunjukkan bahwa tulisan ke alamat yang sudah berisi data menimpa nilai lamanya tanpa jejak, karena memori tidak menyimpan riwayat penulisan. Di tingkat ini, satu-satunya nama yang dimiliki sebuah kata memang angka alamatnya, jauh berbeda dari variabel bernama pada bahasa pemrograman.
Kesalahan umum#
Tiga kesalahan berikut paling sering muncul ketika memori dimodelkan atau ketika program menyentuh memori secara langsung.
- Menukar alamat dengan isi. Keduanya berupa angka sehingga mudah tertukar saat membaca jejak eksekusi. Perbaikannya adalah konsistensi penyebutan, yaitu alamat untuk posisi dan isi atau nilai untuk data yang tersimpan di posisi itu.
- Menulis di luar batas alamat. Pada memori 16 kata, alamat yang sah adalah 0 sampai 15, dan tulisan ke alamat 16 pada perangkat nyata tidak pernah dijawab, sedangkan model tanpa pemeriksaan justru menimpa kata lain tanpa sinyal apa pun. Perbaikannya adalah memvalidasi jangkauan sejak operasi pertama, seperti yang dilakukan metode
_periksapada simulasi. - Mengabaikan chip select ketika beberapa chip digabungkan. Tulisan tanpa seleksi dapat menyentuh chip yang salah dan merusak data yang seharusnya aman. Perbaikannya adalah menyertakan sinyal seleksi pada setiap operasi baca dan tulis dalam model, bukan hanya pada operasi yang sedang diuji.
Ringkasan#
- RAM adalah larik kata yang masing-masing berperilaku seperti register, ditulis pada tepi naik, dan bertahan selama daya tersedia.
- n bit alamat menjangkau kata, dan decoder menerjemahkan alamat menjadi satu garis aktif di antara semua kata.
- Chip select memilih chip yang merespons bus, sehingga beberapa chip dapat dipasang paralel tanpa saling bertabrakan.
- Waktu akses RAM jauh melampaui waktu akses register karena decoder, jalur panjang, dan penguatan sinyal yang harus ditempuh pada setiap akses.
Referensi#
- Computer Systems: A Programmer’s Perspective — Randal Bryant dan David O’Hallaron — Buku yang membahas memori, latensi akses, dan hierarki memori dari sudut pandang pemrogram.
- Nand to Tetris — Shimon Schocken dan Noam Nisan — Proyek pembelajaran yang membangun chip memori dari register dan logika alamat.