ISA opcodes --- Dari mana asalnya?

13

Ketika insinyur merancang arsitektur kumpulan instruksi, dengan prosedur atau protokol apa, jika ada, yang mereka ikuti ketika menunjuk kode biner tertentu sebagai instruksi. Sebagai contoh, jika saya memiliki ISA yang mengatakan 10110 adalah instruksi muatan, dari mana angka biner itu berasal? Apakah itu dimodelkan dari tabel keadaan untuk mesin keadaan terbatas yang mewakili operasi beban?

Sunting: Setelah melakukan penelitian lebih lanjut, saya percaya apa yang saya coba tanyakan berkaitan dengan bagaimana opcodes untuk berbagai instruksi CPU ditugaskan. ADD mungkin ditunjuk dengan opcode 10011; instruksi pemuatan mungkin ditetapkan sebagai 10110. Proses pemikiran apa yang digunakan untuk menetapkan opcode biner ini untuk set instruksi?

Steven
sumber
8
Monte Dalrymple, "Desain Mikroprosesor Menggunakan Verilog HDL," memberikan pendekatan desain yang sangat rinci untuk CPU Z80 dan dari sana saya pikir Anda akan belajar banyak tentang pertanyaan Anda. Tetapi ada banyak pertimbangan yang masuk ke dalam pilihan tertentu, termasuk analisis statistik dari set instruksi lain, output kompiler, dll. Saya sarankan mulai dengan buku itu. Meskipun dimulai dengan desain yang dikenal, dia masuk ke detail intim tentang hal itu dan saya pikir Anda akan mengambil beberapa hal. Buku bagus.
Jonk
Atau, mungkin, Anda bertanya tentang desain mesin eksekusi dan bertanya-tanya bagaimana bit dalam instruksi dapat berperan dalam hal itu? Tidak yakin dari kata-kata Anda.
Jonk
2
Orang lain menanyakan pertanyaan ini. Harus hari Selasa.
Ignacio Vazquez-Abrams
5
@ Sebelas Pikirkan tentang itu. Jika Anda harus merancang ISA, apa yang akan Anda pikirkan? Jika instruksi Anda tidak sama panjang, bagaimana Anda memilih kata instruksi yang lebih pendek atau lebih lama, untuk instruksi yang mana? Jika Anda harus merancang tahap decode , apa yang akan Anda inginkan untuk ISA Anda terlihat seperti? Saya pikir pertanyaannya tidak perlu luas (dan dengan demikian, hampir tidak mungkin untuk menjawab sepenuhnya), tetapi Anda dapat memperbaikinya banyak dengan memasukkan lebih banyak pemikiran sendiri ke dalamnya dan mengajukan pertanyaan yang tepat yang tidak mengharuskan kita untuk menulis buku untuk menjawab Itu.
Marcus Müller
4
Spesifikasi RISC-V berbicara tentang keputusan desain yang mereka buat di semua tingkatan, termasuk sedikit tentang pengkodean instruksi mesin. (Ini tidak biasa untuk manual prosesor; RISC-V adalah latihan akademis pertama dan arsitektur CPU kedua, tidak seperti kebanyakan.)
zwol

Jawaban:

6

Dalam banyak kasus, pilihannya cukup sewenang-wenang atau didasarkan pada "di mana pun itu paling cocok" karena ISA tumbuh seiring waktu. Namun, MOS 6502 adalah contoh luar biasa dari sebuah chip di mana desain ISA sangat dipengaruhi oleh upaya untuk memeras sebanyak mungkin dari transistor terbatas.

Lihat video ini menjelaskan bagaimana 6502 direkayasa balik , khususnya mulai 34:20 dan seterusnya.

6502 adalah mikroprosesor 8-bit yang diperkenalkan pada tahun 1975. Walaupun memiliki gerbang 60% lebih sedikit daripada Z80, tetapi dua kali lebih cepat, dan meskipun lebih terbatas (dalam hal register dll), itu dibuat untuk itu dengan set instruksi yang elegan.

Ini berisi hanya 3.510 transistor, yang ditarik, dengan tangan , oleh tim kecil orang yang merangkak di atas beberapa lembaran plastik besar yang kemudian secara optik menyusut, membentuk berbagai lapisan 6502.

Seperti yang Anda lihat di bawah, 6502 meneruskan opcode instruksi dan data timing ke dalam decode ROM, kemudian meneruskannya ke komponen "random control logic" yang tujuannya mungkin untuk mengesampingkan output ROM dalam situasi kompleks tertentu.

6502 diagram blok

Pada pukul 37:00 dalam video Anda dapat melihat tabel ROM decode yang menunjukkan kondisi apa yang harus dipenuhi input untuk mendapatkan "1" untuk output kontrol yang diberikan. Anda juga dapat menemukannya di halaman ini .

Anda dapat melihat bahwa sebagian besar hal dalam tabel ini memiliki Xs di berbagai posisi. Mari kita ambil contoh

011XXXXX 2 X RORRORA

Ini berarti 3 bit pertama opcode haruslah 011, dan G harus 2; tidak ada hal lain yang penting. Jika demikian, output bernama RORRORA akan menjadi kenyataan. Semua opcode ROR dimulai dengan 011; tetapi ada instruksi lain yang dimulai dengan 011 juga. Ini mungkin perlu disaring oleh unit "logika kontrol acak".

Jadi pada dasarnya, opcodes dipilih sehingga instruksi yang diperlukan untuk melakukan hal yang sama satu sama lain memiliki kesamaan di seluruh pola bit mereka. Anda dapat melihat ini dengan melihat tabel opcode ; semua instruksi ATAU mulai dengan 000, semua instruksi Store mulai dengan 010, semua instruksi yang menggunakan pengalamatan halaman nol adalah dalam bentuk xxxx01xx. Tentu saja, beberapa instruksi sepertinya tidak "pas", karena tujuannya bukan untuk memiliki format opcode yang benar-benar biasa, melainkan untuk menyediakan set instruksi yang kuat. Dan inilah mengapa "logika kontrol acak" diperlukan.

Halaman yang saya sebutkan di atas mengatakan bahwa beberapa garis output dalam ROM muncul dua kali, "Kami menganggap ini telah dilakukan karena mereka tidak memiliki cara untuk merutekan output dari beberapa baris di mana yang mereka inginkan, sehingga mereka meletakkan baris yang sama di tempat yang berbeda. lokasi lagi. " Saya bisa membayangkan para insinyur menggambar gerbang-gerbang itu satu per satu dan tiba-tiba menyadari kekurangan dalam desain dan mencoba mencari cara untuk menghindari memulai kembali seluruh proses.

Artelius
sumber
22

Tergantung berapa umur ISA.

Pada hari-hari awal desain tangan, dan bahkan lebih lagi ketika CPU dikumpulkan dari logika diskrit, desain logika akan menjadi yang pertama, dan telah diperkecil secara luas, dan kemudian pola bit ISA akan menjadi nilai apa pun yang diperlukan untuk membuat nilai minimal kerja logika.

Jadi mungkin ada pola tertentu dari sinyal kontrol yang memungkinkan beberapa multiplexer untuk menghubungkan output ALU ke input file register GP, beberapa sinyal kontrol lagi yang menginstruksikan ALU untuk menambah, mengurangi, DAN, ATAU dll, dan beberapa bit alamat ke dalam file register. Tiga kelompok sinyal ini akan membentuk bidang dalam instruksi. Setiap kelompok akan disimpan bersama, dan makna terperinci mereka muncul dari desain untuk unit itu (ALU dll) tetapi kelompok-kelompok itu mungkin dalam urutan apa pun, hingga Anda mendesain decoder instruksi. (x86 sudah cukup tua sehingga Anda dapat mendeteksi beberapa ini jika Anda melihat di tempat yang tepat - itu bukan desain yang sama sekali baru, tetapi menarik dari 8080 yang lebih tua)

Kemudian SPA dapat "dibersihkan" dan dibuat lebih teratur dan lebih mudah untuk digunakan, dengan perangkat keras untuk menerjemahkan antara mereka dan sinyal kontrol tingkat perangkat keras yang sebenarnya, kadang-kadang melalui "mikrokode". Ini disebut "CISC" atau "Pengesetan Set Instruksi Kompleks". Awalan instruksi "Rep" x86 adalah contoh sederhana dari ini - ini menyebabkan instruksi berikut diulang beberapa kali, untuk menghemat keharusan menulis loop FOR.

Kemudian masih (pada 1980-an) datang gerakan kembali ke gaya yang lebih sederhana dari pengkodean langsung (RISC - Reduced Instruction Set Coding) yang dapat Anda lihat dalam prosesor ARM. Ini didorong oleh ukuran kecil ASIC pada saat itu, dan keinginan untuk menempatkan CPU 32-bit pada mereka, maka tidak ada kapasitas cadangan untuk decoder set instruksi yang kompleks, untuk membuat CPU lengkap turun menjadi sekitar 20.000 gerbang. (Ada juga peningkatan kinerja sementara, karena orang belum mengembangkan teknik untuk membuat decoder CISC cepat - yang datang sekitar 1995 dengan Pentium Pro)

Dan saat ini tidak masalah - CPU membaca beberapa instruksi sekaligus, dan mencurahkan jutaan transistor untuk mendekode mereka, memesan kembali, dan mengeksekusi sebanyak mungkin sekaligus, untuk mempercepat program yang mungkin telah ditulis untuk yang tertua gaya ISA.

Brian Drummond
sumber
2
Saya tidak yakin saya benar-benar akan memanggil CISC "lebih mudah digunakan". Itu mungkin niat asli, tetapi 30 tahun kemudian mereka agak antitesis "mudah digunakan" (dibandingkan dengan RISC ISA, setidaknya).
tonysdg
2
Ada hal-hal di mana mereka lebih mudah digunakan ... baik keteraturan (ortogonalitas adalah topik besar) kembali ketika kompiler adalah program yang relatif sepele, atau melalui mendukung operasi tingkat yang lebih tinggi secara langsung, membutuhkan lebih sedikit terjemahan dari kompiler. Tapi itu adalah PANJANG yang lalu dan CISC yang masih hidup memiliki begitu banyak lapisan revisi di atas set instruksi aslinya. Kompiler telah berubah dari semua pengenalan juga - ribuan atau lebih melewati optimasi yang dilakukan oleh gcc tidak akan terpikirkan saat itu. Jadi apa yang "mudah" dulu dan sekarang hanya memiliki sedikit hubungan.
Brian Drummond
4
Perbedaannya telah terkikis ("RISC" set menambah lebih banyak instruksi) dan digantikan oleh arsitektur baru yang bahkan lebih kompleks seperti VLIW; benar-benar satu-satunya konsensus adalah bahwa x86 (16 dan 32 bit) sulit digunakan
pjc50
1
@tonysdg: Ada yang sulit untuk menggunakan RISC dan sulit untuk menggunakan CISC. Perbandingan "keramahan programmer" yang bagus adalah membandingkan 68k vs ARM. ARM dirancang untuk kompiler sehingga Anda harus melakukan banyak pekerjaan manual untuk mendapatkan data dari RAM dan menulis kembali ke RAM. 68k dirancang untuk programer perakitan dan memungkinkan Anda untuk beroperasi secara langsung pada data dalam RAM. Jika Anda melihat 68k ISA Anda akan menemukan bahwa itu sangat mirip dengan RISC ISA modern dengan satu pengecualian - Anda dapat beroperasi secara langsung pada RAM sedangkan RISC hanya memungkinkan Anda untuk beroperasi pada register.
slebetman
1
Microcode terutama merupakan atribut CISC. Namun Anda dapat mengimplementasikan CISC tanpa mikrokode: decoder instruksi akan lebih rumit. Anda juga akan melihat beberapa CISC dari Pentium-Pro dan seterusnya digambarkan sebagai RISC secara internal; menerjemahkan setiap instruksi CISC ke dalam satu atau lebih operasi RISC internal: nama lain untuk mikrokode (meskipun perbedaannya kabur dalam unit eksekusi superscalar)
Brian Drummond
9

Jika Anda mengelompokkan instruksi yang serupa bersama-sama, pola akan muncul. Ini sangat jelas dalam ARM, di mana manual ISA benar-benar menunjukkan Anda sedikit kata instruksi yang sesuai dengan fungsi, pilihan register, dll. Tetapi juga dapat disimpulkan untuk X86 .

Pada akhirnya bagian "function" dari opcode masuk ke beberapa decoder biner-ke-satu yang benar-benar mengaktifkan fungsi atau urutan tertentu dari operasi pipelined. Biasanya tidak terkait dengan konten mesin negara mana pun, kecuali kami mempertimbangkan instruksi panjang variabel yang membutuhkan mesin negara untuk memecahkan kode.

pjc50
sumber
Anda pada dasarnya mengatakan mereka memacu untuk menghitung transistor serendah mungkin pada chip. Saya sepenuhnya setuju dalam konteks pertanyaan OP, di mana mereka tidak mampu membeli ratusan transistor tambahan untuk satu set instruksi yang lebih rapi. Jutaan-transistor CPU tidak memiliki alasan untuk peduli, tetapi tentu saja banyak yang mempertahankannya untuk kompatibilitas.
Harper - Reinstate Monica
@ Harper Masih ada alasan, karena sementara transistor semakin kecil, mereka masih memiliki ukuran - dan laju jam meningkat banyak sementara itu. Jadi decoder instruksi yang terlalu besar masih bisa menjadi penghambat kinerja (salah satu alasan banyak CPU memilih untuk pra- dekode instruksi, sebelumnya). Ini bukan (hanya) tentang jumlah transistor, tetapi lebih lanjut tentang laju jam dalam kombinasi dengan area mati. Informasi masih membutuhkan waktu untuk disebarkan, dan walaupun CPU modern tidak berjalan pada kecepatan cahaya, mereka tidak cukup jauh dari batas kecepatan untuk mengharapkan peningkatan yang signifikan.
Luaan
@Luaan: Sebenarnya, "apa yang kita lakukan dengan semua transistor ini" adalah pertanyaan nyata saat ini. Lihatlah semua cache L2 / L3 yang dilemparkan saat ini. Itu adalah pengakuan bisu yang tidak kita gunakan dengan lebih baik untuk jutaan transistor itu. Xeon mendedikasikan lebih dari 2 miliar transistor untuk cache!
MSalters
6

Seseorang pada suatu titik duduk dan mendefinisikannya.

ISA yang baik akan membuat decoder sesederhana mungkin.

Misalnya dengan instruksi ALU Anda dapat membiarkan beberapa bit opcode dikirim langsung ke baris kontrol ALU.

aneh ratchet
sumber
Terima kasih untuk semua jawaban yang luar biasa. Anda semua telah membantu saya memahami hal ini dengan lebih baik.
Steven
4
Sebenarnya ada beberapa faktor selain kesederhanaan decoder untuk dipertimbangkan. Bergantung pada keadaan dan tujuan penggunaan, yang lain (mis., Kepadatan kode) mungkin lebih penting daripada kesederhanaan dekoder. Dalam prosesor modern, kerapatan kode mungkin melebihi kesederhanaan decoder dalam kebanyakan kasus.
Jerry Coffin
5

Biasanya, Anda akan membagi ISA Anda menjadi kelompok fungsional. Masuk akal (baik untuk optimasi logika atau hanya rapi) bahwa pasangan pelengkap dibedakan oleh perubahan bit tunggal (load vs store), dan bahwa Anda memiliki beberapa hierarki bit yang memengaruhi pohon keputusan dekode.

Pada akhirnya, alokasi bit yang sewenang-wenang untuk blok fungsi (sebagai lawan menempatkan bidang 'data' dalam instruksi hanya akan berdampak kecil pada efisiensi desain keseluruhan Anda - tetapi Anda memiliki banyak pilihan tentang cara 'optimalkan' penyandian ISA Anda tergantung pada apa yang Anda rasakan sebagai parameter penting.

Sean Houlihane
sumber
1

Pengkodean instruksi adalah kompromi yang buruk antara.

Membuat decode sederhana, untuk ini Anda ingin satu set bidang sederhana yang masing-masing dapat diterjemahkan secara terpisah dan dialihkan ke bagian terpisah dari mesin eksekusi.

Mengemas fungsionalitas sebanyak mungkin ke dalam kata instruksi ukuran terbatas. Ini mengarah pada hal-hal seperti format konstan khusus yang dapat menyandikan berbagai angka umum.

Maju dan mundur kompatibilitas. Jika Anda menetapkan fungsionalitas untuk setiap opcode yang mungkin, Anda tidak punya ruang untuk memperluas arsitektur nanti. Jika Anda menambahkan ke arsitektur yang sudah ada, Anda harus memasukkan instruksi baru Anda ke dalam opcode cadangan.

Peter Green
sumber
1

Randy Hyde luar biasa (jika agak ketinggalan jaman) Seni Majelis masuk ke instruksi x86 diatur dalam beberapa detail dalam bab 3.3.4 Unit Kontrol dan Set Instruksi dan berikut.

Program-program pada sistem komputer awal (pra-Von Neumann) sering kali "diprogram" ke dalam sirkuit. Artinya, kabel komputer menentukan masalah apa yang akan dipecahkan komputer. Seseorang harus memperbaiki sirkuit untuk mengubah program. Tugas yang sangat sulit. Kemajuan berikutnya dalam desain komputer adalah sistem komputer yang dapat diprogram, yang memungkinkan seorang programmer komputer untuk dengan mudah "memperbaiki" sistem komputer menggunakan urutan soket dan kabel steker. Program komputer terdiri dari serangkaian baris lubang (soket), setiap baris mewakili satu operasi selama pelaksanaan program. Pemrogram dapat memilih salah satu dari beberapa instruksi dengan menancapkan kawat ke soket tertentu untuk instruksi yang diinginkan.

Dia kemudian menunjukkan cukup menarik dan panjang lebar bagaimana pasangan pertama colokan berdiri untuk instruksi, colokan berikutnya menyandikan sumber dan tujuan. Tentu saja, hari ini tidak ada lagi "colokan", tetapi untuk ISA yang benar-benar tua, bit-bit pada opcode pada dasarnya melakukan pekerjaan yang sama dengan colokan sebelumnya.

Anda berakhir dengan sesuatu seperti ini:

masukkan deskripsi gambar di sini

DevSolar
sumber
Terima kasih atas tautan dari Hyde! Ini sangat informatif dan ia tampaknya memiliki gaya mengajar yang sangat baik.
Steven