Kami mengekstrak konstanta dari kristal coprocessor matematika 8087

Pada 1980, Intel memperkenalkan chip 8087 untuk mempercepat pemrosesan angka floating point pada prosesor 8086, dan digunakan pada PC IBM asli. Karena mikroprosesor pertama hanya bekerja dengan bilangan bulat, aritmatika dengan angka floating point lambat, dan dengan fungsi transendental seperti arctangent atau logaritma, segalanya menjadi lebih buruk. Menambahkan chip coprocessor 8087 ke sistem dapat mempercepat operasi dengan angka floating point hingga seratus kali.

Saya membuka chip 8087 dan mengambil beberapa foto di bawah mikroskop. Foto di bawah ini menunjukkan kristal chip silikon kecil. Pada sisinya, konduktor kecil menghubungkannya dengan 40 kaki eksternal. Markup dari blok fungsional utama dalam gambar dibuat oleh saya berkat teknik reverse. Jika Anda mempelajari chip dengan hati-hati, Anda dapat mengekstrak berbagai konstanta dari ROM-nya - angka-angka seperti π yang digunakan oleh chip dalam perhitungan. Chip Intel 8087 untuk operasi titik mengambang dengan blok fungsi utama yang ditandai. ROM dengan konstanta ditandai dengan warna hijau. Diklik.




Di bagian atas chip adalah sirkuit kontrol. Hingga 1000 langkah mungkin diperlukan untuk menjalankan instruksi floating point; 8087 menggunakan mikrokode untuk menggambarkan langkah-langkah ini. Dalam foto kristal Anda dapat melihat "mekanisme" yang meluncurkan program dari mikrokode; sebenarnya, ini adalah CPU sederhana. Di sebelahnya ada ROM besar, tempat mikrokode disimpan.

Di bagian bawah chip adalah sirkuit yang memproses angka floating point. Angka floating point terdiri dari bagian fraksional (juga dikenal sebagai bagian signifikan dari angka atau mantissa), eksponen, dan bit tanda. Dalam notasi desimal, angka 6,02 × 10 236.02 akan menjadi mantissa dan 23 akan menjadi eksponen. Pisahkan sirkuit chip secara bersamaan memproses mantissa dan eksponen. Skema pemrosesan mantissa mendukung nilai 67-bit - mantissa 64-bit dan tiga bit tambahan untuk akurasi. Dari kiri ke kanan, skema operasi mantissa terdiri dari ROM dengan konstanta, register geser, penambah / sub-karakter, dan tumpukan register. Topik artikel ini adalah ROM dengan konstanta, di foto disorot dengan warna hijau.

8087 bekerja sebagai coprocessor untuk prosesor 8086. Ketika prosesor 8086 menemukan instruksi khusus yang terkait dengan angka floating point, ia mengabaikannya dan memberi 8087 kesempatan untuk mengeksekusi secara paralel. Interaksi 8086 dan 8087 diatur dengan cara yang agak licik. Untuk menyederhanakan, 8087 melihat aliran instruksi 8086, dan mengeksekusi instruksi yang terkait dengan 8087. Kesulitannya adalah bahwa 8086 memiliki buffer instruksi pengambilan awal, sehingga instruksi yang diterima 8086 saat ini tidak cocok dengan yang dia melakukan. Oleh karena itu, 8087 menduplikasi buffer pengambilan preemptive instruksi 8086 (atau buffer preemptive mengambil instruksi 8088 yang lebih besar) untuk mengetahui apa yang dilakukan 8086 ( dijelaskan lebih rinci di sini) Kesulitan lain terkait dengan mode pengalamatan 8086 yang kompleks menggunakan register di dalam 8086. 8087 tidak dapat menjalankan mode pengalamatan ini karena tidak memiliki akses ke register 8086. Sebaliknya, ketika 8086 melihat instruksi untuk 8087, ia meminta data dari lokasi memori yang ditentukan dan mengabaikan hasilnya. Sementara itu, 8087 mengambil alamat dari bus, kalau-kalau dia membutuhkannya. Tampaknya bagi Anda bahwa perangkap akan terbentuk di tempat ini jika 8087 tidak dipasang - tetapi ini tidak akan terjadi. Pada sistem tanpa 8087, penghubung menulis ulang instruksi 8087, menggantikannya dengan panggilan subrutin dari perpustakaan emulasi.

Saya tidak akan memberi tahu secara detail cara kerja internal 8087, tetapi secara umum, operasi floating point diimplementasikan melalui penambahan, pengurangan, dan pergeseran bilangan bulat. Untuk menambah atau mengurangi dua angka floating-point, 8087 menggeser angka sampai koma biner disejajarkan (seperti titik desimal, hanya dalam sistem biner), dan kemudian menambah atau mengurangi mantissa. Penggandaan, pembagian dan pengambilan akar kuadrat dilakukan oleh perubahan dan penambahan / pengurangan berturut-turut. Fungsi transendental (tangen, arc tangent, logaritma, derajat) menggunakan algoritma CORDIC , yang menggunakan pergeseran dan penambahan konstanta khusus untuk meningkatkan efisiensi perhitungan.

Implementasi ROM


Artikel ini menjelaskan tentang ROM tempat menyimpan konstanta. Jangan bingung dengan ROM empat tingkat yang lebih besar tempat mikrokode disimpan - yang terakhir ini diimplementasikan menggunakan teknologi yang tidak biasa yang menyimpan dua bit per transistor. Ini dilakukan dengan menggunakan transistor dengan tiga ukuran berbeda atau tidak adanya transistor di setiap posisi. Keempat opsi ini mengindikasikan dua bit. Ini teknologi canggih diperlukan agar sesuai ROM besar ke sebuah 8087 keping.

ROM untuk konstanta menggunakan teknologi standar untuk menyimpan konstanta (seperti π, ln (2) dan √2) yang diperlukan oleh 8087 untuk perhitungan. Foto di bawah ini menunjukkan bagian dari ROM dengan konstanta. Untuk melihat kristal itu sendiri, lapisan logam telah dihapus darinya. Area merah muda adalah silikon dengan kotoran yang memberikan sifat berbeda, dan garis kemerahan dan kehijauan adalah polisilikon , jenis kabel silikon khusus yang terletak di atasnya. Perhatikan struktur ROM, mirip dengan kisi yang benar. ROM terdiri dari dua kolom transistor yang menyimpan bit. Untuk menjelaskan skema operasinya, saya akan mulai dengan skema operasi transistor.


Bagian dari ROM dengan konstanta, dengan lapisan logam yang dihapus. Tiga kolom transistor yang lebih besar digunakan untuk memilih baris.

High Density Integrated Circuits (ICs) pada tahun 1970-an biasanya dibuat dari transistor N-MOS. (Komputer modern terbuat dari CMOS, terdiri dari N-MOS dan P-MOS membalik polaritasnya). Diagram di bawah ini menunjukkan struktur transistor N-MOS. IC dirakit dari substrat silikon tempat transistor dibuat. Kotoran ditambahkan ke situs silikon, menciptakan daerah "menyebar" dengan sifat listrik yang diinginkan. Transistor dapat dianggap sebagai saklar yang memungkinkan arus mengalir antara dua bagian difusi, yang disebut sumber dan tiriskan. Transistor dikendalikan oleh gerbang yang terbuat dari jenis silikon-polisilikon khusus. Menerapkan voltase ke gerbang memungkinkan arus mengalir antara sumber dan tiriskan; jika tidak, arus tidak mengalir. The 8087 cukup kompleks, dengan sekitar 40.000 transistor di atasnya.

Sumber yang berbeda memberikan jumlah transistor yang berbeda untuk 8.087: Intel mengatakan sekitar 40.000, Wikipedia mengatakan sekitar 45.000. Mungkin semuanya ada dalam metode perhitungan yang berbeda. Karena jumlah transistor dalam ROM, PLA, atau struktur serupa lainnya tergantung pada data yang disimpan, sumber sering menunjukkan jumlah transistor "potensial" daripada yang asli. Anda juga dapat mempertimbangkan atau tidak mempertimbangkan pull-up transistor, atau menganggap driver arus tinggi sebagai satu transistor atau beberapa yang paralel.


Struktur MOS diimplementasikan dalam IP

Dengan memperbesar, masing-masing transistor ROM dapat dipertimbangkan. Daerah merah muda adalah silikon dengan kotoran yang membentuk sumber dan saluran air. Jalur bus vertikal pilih polisilikon dari gerbang transistor. Area yang ditandai dari silikon terhubung ke tanah, dan tarik ke bawah satu sisi setiap transistor. Lingkarannya adalah VIA , sebuah vilayer interlayer antara silikon dan ban logam di atas. Untuk foto, ban logam dilepas; lokasi salah satunya ditunjukkan oleh garis oranye.


Bagian dari ROM dengan konstanta. Setiap bus pengambilan sampel memilih konstanta tertentu. Transistor ditunjukkan dengan warna kuning. X menandai transistor yang hilang sesuai dengan bit 0. Garis oranye menunjukkan lokasi konduktor logam.

Fitur penting dari ROM adalah tidak adanya beberapa transistor - tidak ada yang pertama di baris atas, dan dua ditandai dengan X di baris bawah. Bit diprogram dalam ROM dengan mengubah sirkuit untuk menambahkan kotoran ke silikon, yang membuat transistor atau meninggalkan area isolasi. Setiap transistor yang tersedia atau hilang mewakili satu bit. Ketika bus pengambilan sampel diaktifkan, semua transistor dalam kolom ini terbuka, menarik turun bus keluaran yang sesuai. Tetapi jika tidak ada transistor dalam posisi yang dipilih, output yang sesuai akan tetap tinggi. Dengan demikian, nilainya dibaca dari ROM dengan mengaktifkan bus sampel, yang mengeluarkan nilai ini dari ROM ke bus keluaran.

Isi ROM


ROM dengan konstanta terdiri dari 143 baris dan 21 kolom. Ini berisi 134 baris 21 bit, kecuali satu potong 6 × 6 transistor di kiri atas. Oleh karena itu, ukuran fisik ROM dengan konstanta adalah 2946 bit.



Berdasarkan skema ROM, bagian yang hilang berarti bahwa 12 konstanta pertama adalah 64-bit, bukan 67-bit. Ini adalah konstanta yang tidak terkait dengan CORDIC, dan mereka tampaknya tidak memerlukan ketelitian tambahan.

Di bawah mikroskop, pola bit ROM terlihat, sehingga dapat dihapus dari sana. Namun, sama sekali tidak jelas bagaimana menafsirkan bit-bit ini nanti. Pertanyaan pertama adalah apakah kehadiran transistor menunjukkan 0 atau 1 (kemudian ternyata keberadaan transistor adalah 1). Masalah kedua adalah bagaimana menerjemahkan kisi 134 × 21 bit ke dalam nilai.

Pengkodean bit dapat didefinisikan dalam dua cara. Yang pertama adalah melacak sirkuit membaca data dari ROM dan melihat bagaimana itu digunakan. Yang kedua adalah mencari pola dalam data mentah dan mencoba memahaminya. Karena 8087 sangat kompleks, saya ingin menghindari teknik reverse penuh ketika mempelajari konstanta, jadi saya menggunakan pendekatan kedua.

Jalur data chip terdiri dari 67 baris horizontal, jadi jelas bahwa 134 baris dalam ROM berhubungan dengan dua set konstanta 67-bit. Saya mengekstrak satu set konstanta dari seri ganjil, dan yang lain dari seri genap, namun nilai yang diperoleh tidak masuk akal. Berpikir sedikit lagi, saya menyadari bahwa baris tidak bergantian, tetapi berjalan mengulangi urutan ABBA.

Baris masuk dalam urutan ABBAABBAABBA ..., di mana baris A berisi bit untuk satu set konstanta, dan baris B berisi bit untuk yang lain. Sirkuit seperti itu digunakan alih-alih hanya dengan ABAW bolak-balik, mungkin karena satu kontak dapat mengontrol dua transistor yang berdekatan. Artinya, satu konduktor dapat memilih masing-masing kelompok AA dan BB.

Ketika saya mempertimbangkan pesanan ABBA, saya mendapat banyak konstanta yang sudah dikenal, termasuk π dan 1. Diagram di bawah ini menunjukkan bit dari konstanta ini. Dalam foto, bit 1 adalah strip hijau, bit 0 berwarna merah. Dalam sistem biner, π adalah 11.001001 ..., dan nilai inilah yang terlihat di baris atas bit yang ditandai. Nilai yang lebih rendah adalah konstan 1. Baris


atas bit adalah angka π, yang lebih rendah adalah 1. Diagram ini diputar 90 ° dibandingkan yang lain.

Kesulitan berikutnya dengan interpretasi adalah bahwa hanya mantissa yang disimpan dalam ROM, tetapi bukan eksponen (sejauh ini saya belum menemukan ROM terpisah dengan eksponen). Dan saya bereksperimen dengan berbagai peserta pameran sampai saya mendapatkan nilai yang berarti. Beberapa langsung jelas: misalnya, konstanta 1,204120 memberikan log 10 (2) menggunakan eksponen 2 -2 . Yang lain lebih sulit untuk dipahami, misalnya, 1.734.723. Pada akhirnya, saya menyadari bahwa 1.734723 × 2 59 = 10 18 . Mengapa ada yang konstan di 8087? Mungkin karena 8087 mendukung kode desimal biner dikemas 18-karakter.

Beberapa eksponen sangat sulit ditemukan, dan saya menggunakan metode brute force untuk melihat apakah hasilnya akan menghasilkan logaritma atau tingkat bilangan apa pun. Yang paling sulit adalah menentukan konstanta untuk ln (2) / 3. Pentingnya angka ini tidak jelas bagi saya.

Berikut adalah daftar konstanta lengkap dari ROM. Kolom "makna" adalah deskripsi saya tentang artinya.

KonstantaNilai desimalBerarti
1.204120 × 2 -20,3010300log 10 (2)
1.386294 × 2 -10,6931472di (2)
1,442695 × 2 01.426950log 2 (e)
1.570796 × 2 13.1415927π
1,000000 × 2 01,0000001
1.660964 × 2 13.219281log 2 (10)
1.734723 × 2 591,00e + 1810 18
1.734723 × 2 591,00e + 1810 18
1.848392×2-30.2310491ln(2)/3
1.082021×224.2808513*log2(e)
1.442695×201.426950log2 (e)
1.414214×201.4142136√2
1.570796×2-10.7853982atan(20)
1.854590×2-20.4636476atan(2-1)
2.000000×2-150.0000610atan(2-14)
2.000000×2-160.0000305atan(2-15)
1.959829×2-30.2449787atan(2-2)
1.989680×2-40.1243550atan(2-3)
2.000000×2-130.0002441atan(2-12)
2.000000×2-140.0001221atan(2-13)
1.997402×2-50.0624188atan(2-4)
1.999349×2-60.0312398atan(2-5)
1.999999×2-110.0009766atan(2-10)
2.000000×2-120.0004883atan(2-11)
1.999837×2-70.0156237atan(2-6)
1.999959×2-80.0078123atan(2-7)
1.999990×2-90.0039062atan(2-8)
1.999997×2-100.0019531atan(2-9)
1.441288×2-90.0028150log2(1+2-9)
1.439885×2-80.0056245log2(1+2-8)
1.437089×2-70.0112273log2(1+2-7)
1.431540×2-60.0223678log2(1+2-6)
1.442343×2-110.0007043log2(1+2-11)
1.441991×2-100.0014082log2(1+2-10)
1.420612×2-50.0443941log2(1+2-5)
1.399405×2-40.0874628log2(1+2-4)
1.442607×2-130.0001761log2(1+2-13)
1.442519×2-120.0003522log2(1+2-12)
1.359400×2-30.1699250log2(1+2-3)
1.287712×2-20.3219281log2(1+2-2)
1.442673×2-150.0000440log2(1+2-15)
1.442651×2-140.0000881log2(1+2-14)


Tidak yakin mengapa 10 18 diulang - mungkin perbedaannya eksponensial.

Secara fisik, konstanta terletak dalam tiga kelompok. Grup pertama adalah nilai yang dapat dimuat pengguna (1, π, log 2 10, log 2 e, log 10 2, dan ln), serta nilai untuk penggunaan internal (10 18 , ln (2) / 3, 3 * log 2 (e), log 2 (e) dan √2). Kelompok kedua terdiri dari 16 konstanta arctangent, dan yang ketiga terdiri dari 14 konstanta log 2 .

Pada 8087, ada tujuh instruksi untuk memuat konstanta secara langsung. Instruksi FDLZ, FLD1, FLDPI, FLD2T, FLD2E, FLDLG2 dan FLDLN2 memuat konstanta 0, 1, π, log 2 10, log 2 ke stacke, log 10 2 dan ln 2, masing-masing. Semua konstanta ini kecuali 0 disimpan dalam ROM.

Dua kelompok konstanta terakhir digunakan untuk menghitung fungsi transendental menggunakan algoritma CORDIC.

Algoritma CORDIC


Dengan konstanta dari ROM, Anda dapat mengetahui beberapa detail operasi algoritma 8087. ROM berisi 16 nilai untuk arctangent, arctangents dari 2 -n . Juga ada 14 logaritma yang disimpan di pangkalan 2 (1 + 2 -n ). Nilai-nilai seperti itu mungkin tampak tidak biasa, tetapi mereka digunakan dalam algoritma CORDIC yang efisien, ditemukan pada tahun 1958.

Gagasan CORDIC adalah bahwa tangen dan arctangent dapat dihitung dengan memecah sudut menjadi yang lebih kecil dengan rotasi vektor oleh sudut-sudut ini. Kuncinya adalah bahwa jika Anda memilih sudut yang tepat lebih kecil, maka setiap rotasi dapat dihitung melalui perubahan dan penambahan efektif alih-alih fungsi trigonometri. Misalkan kita perlu mencari tan (z). Kita dapat membagi z menjadi jumlah sudut kecil: z small {atan (2 -1 ) atau 0} + {atan (2 -2) atau 0} + {atan (2 -3 ) atau 0} + ... + {atan (2 -16 atau 0}. Anda dapat memutar vektor dengan, katakanlah, atan (2 -2 ) dengan mengalikan dengan 2 -2 dan menambahkan. Intinya adalah bahwa mengalikan dengan 2 -2 dilakukan melalui pergeseran bitwise cepat. Dengan memperhitungkan semua ini, Anda dapat menghitung tan (z) dengan membandingkan z dengan konstanta atan, dan kemudian setelah melalui 16 siklus penambahan dan pergeseran, yang dilakukan dengan cepat pada besi. untuk atan sudah dihitung sebelumnya dan disimpan dalam ROM. Garis singgung busur dihitung dengan cara yang serupa, tetapi sebaliknya - dalam proses rotasi, sudut (dari ROM dengan konstanta) diringkas dan memberikan yang terakhir.

Saat menghitung logaritma dan eksponen, algoritma CORDIC dan konstanta logaritmik yang sesuai juga digunakan. Hal utama di sini adalah bahwa perkalian dengan (1 + 2 -n ) dapat dilakukan dengan cepat dengan bantuan shift dan penambahan. Logaritma dan eksponen dapat dihitung dengan mengalikan satu sisi persamaan dengan urutan nilai dan menambahkan konstanta logaritmik yang sesuai ke sisi yang lain. Menurut algoritma untuk menghitung logaritma dan eksponen dokumentasi untuk 8087, saya tidak menemukannya. Saya berpikir bahwa mereka mirip dengan yang dijelaskan dalam artikel berikutnya , hanya 8.087 menggunakan basis 2 bukannya E. Saya tidak mengerti mengapa 8087 tidak memiliki log 2 konstan (1 + 2 -1 ) yang diperlukan untuk algoritma itu.

Dukungan untuk fungsi transendental di 8087 tidak seluas yang Anda harapkan. Ini hanya mendukung garis singgung dan garis singgung, tanpa sinus dan cosinus. Untuk menghitung yang terakhir, perlu untuk menerapkan identitas trigonometri. Logaritma dan eksponen hanya mendukung basis 2 - untuk basis 10 atau e pengguna harus menerapkan faktor skala. Pada suatu waktu, 8087 memperluas batas kapasitas chip, sehingga jumlah instruksi diminimalkan.

Kesimpulan


8087 adalah chip yang kompleks, dan sekilas terlihat seperti labirin kusut yang putus asa. Namun, sebagian besar, dapat dipahami setelah studi yang cermat. Dalam ROM-nya, 42 konstanta disimpan, dan nilainya dapat diekstraksi menggunakan mikroskop. Beberapa konstanta (mis. Π) diharapkan, sementara yang lain (mis. Dalam (2) / 3) mengajukan lebih banyak pertanyaan. Banyak konstanta yang digunakan untuk menghitung garis singgung, arctangents, logaritma, dan derajat menggunakan algoritma CORDIC. Foto kristal 8087 tanpa lapisan logam. Diklik.




Meskipun Intel 8087 untuk operasi floating point diperkenalkan 40 tahun yang lalu, dampaknya masih terasa. Dia menelurkan standar IEEE 754 untuk angka floating point, digunakan dalam sebagian besar perhitungan aritmatika, dan instruksi 8087 tetap menjadi bagian dari prosesor x86 yang digunakan pada kebanyakan komputer.

All Articles