Relay kecilku: Komputer Brainfuck itu sihir

Pendahuluan


Suatu ketika, ketika semuanya besar di sekitar, dan saya masih kecil, saya membaca buku Wojciechowski Radio-electronic Toys, ingin menghidupkan perangkat yang dijelaskan di dalamnya. Jadi, pada tahun 2008 yang sudah jauh, dari puluhan relai elektromagnetik, ALU 4-bit ( RCVM1 - Relay Digital Computing Machine - versi 1 ) dirakit yang mampu menambah dan mengurangi. Dan kemudian saya berpikir - dan bagaimana jika saya merakit relay yang jauh lebih besar dan membangun komputer relay penuh? Hanya butuh 8 tahun untuk merakit relay di sana-sini secara perlahan sampai jumlah yang diperlukan, dan saya mulai membuat.


Izinkan saya memperkenalkan Anda pada proyek Anda untuk membuat versi kedua dari komputer relai digital, yang diberi nama kode "BrainfuckPC" - komputer 16-bit dengan arsitektur Von Neumann dan seperangkat instruksi untuk bahasa Brainfuck. Pekerjaan desain selesai, dan saya sedang dalam proses membuat monster ini.


1 Spesifikasi


  • Lebar Bus Alamat: 16 bit
  • Mengatasi: kata demi kata, 16 bit / kata
  • Kapasitas Memori: 64 Kiloslov (128KB)
  • Lebar Bus Data: 16 bit
  • Ruang Alamat Terpadu untuk Kode dan Data (Arsitektur Von Neumann)
  • Frekuensi jam (desain): 100 Hz, 1 instruksi / siklus
  • Set Instruksi: Brainfuck ++
  • Jumlah relay (desain): 792
  • Relai yang digunakan: sakelar buluh, RES55 (1p), RES64 (1z)

Detail digulung


Prinsip kerja umum


Pertimbangkan struktur umum komputer:



Gambar 1: Struktur Komputer Umum


Elemen sentral adalah penambah, dan tidak sederhana, tetapi dengan transfer paralel. Mengapa ini diperlukan - saya akan ceritakan sedikit di bawah ini.


Program dan data disimpan dalam blok memori. Akses ke mereka dilakukan di alamat yang dicatat dalam register instruksi IP, atau di register alamat AP, berdasarkan apa yang sekarang kita ingin baca - data di alamat yang ditentukan dalam AP, atau instruksi yang direkam di alamat IP.


Untuk mengoperasikan pita Turing ini (dan bahasa pemrograman Brainfuck mengidentifikasinya dengan tepat), kita harus dapat melakukan salah satu dari tiga tindakan:


  • Ubah nilai dalam sel data saat ini, yaitu, lakukan operasi Add / Sub. Di Brainfuck, nilai di dalam sel hanya bisa diubah oleh satu, yaitu. +1 atau -1. Tetapi memiliki penambah lengkap, adalah dosa untuk tidak menutup rantai panjang +++++++++++++ (------------) menjadi satu operasi AP + = N ( AP- = N) secara signifikan mempercepat proses perhitungan. (juga jangan lupa untuk mengubah [-] (atau [+]) menjadi * AP = 0);
  • Ubah jumlah sel data yang saat ini dipilih. Yaitu, berjalan melalui memori data (AP ++, AP--);
  • Ubah nomor instruksi saat ini. Pertama, setelah setiap instruksi, kita perlu meningkatkan nilai dalam register IP oleh satu. Kedua, ubah nilai ini jika ada cabang dalam kode (secara default untuk mengatur loop). Hanya ada satu flag kontrol - Z. Dengan demikian, ada perintah JumpIfZero dan JumpIfNotZero.

Secara total, kita harus dapat memasok ke satu input dari penambah nilai salah satu dari tiga blok berikut - register AP, register IP, bus DATA. Kami akan melakukan ini melalui register sementara, di mana kami akan menyimpan salah satu nilai yang diperlukan, menghubungkan yang diinginkan menggunakan kunci 16-bit.


Pada input kedua dari adder, kami akan mengirimkan nomor yang salah satu dari nilai-nilai ini harus berubah menjadi plus atau minus. Karena lebar instruksi yang terbatas, Anda hanya dapat mengubahnya dengan angka + -12 bit. Namun, untuk Brainfuck ini lebih dari cukup ("cukup untuk semua orang", ya).
Kami akan mengambil 12 bit ini dari register perintah, di hadapan perintah seperti itu wajar, karena bagian dari perintah tidak menggunakan penambah sama sekali. Jangan lupa bahwa angka negatif akan disajikan dalam kode augmented, dengan pengarsipan untuk tambahan. input transfer unit (mis. akan menjadi A + invB + 1)


Hasil perhitungan segera dimuat ke tempat kami mendapatkannya. Karena register sementara, kita dapat melakukan ini tanpa rasa sakit.


Lebih detail (saya bahkan akan mengatakan membosankan) tentang arsitektur dapat ditemukan di video ini:



Set instruksi


Setelah menggambar diagram skematik umum yang mampu mengimplementasikan 8 instruksi Brainfuck dasar, saya menyadari bahwa ia memiliki potensi yang jauh lebih besar. Oleh karena itu, saya mengembangkan serangkaian instruksi yang lebih luas yang kompatibel dengan Brainfuck, tetapi membutuhkan kompilasi setiap instruksi sumber Brainfuck menjadi instruksi komputer 16-bit.


Deskripsi Umum tentang Petunjuk


Semua instruksi 16-bit. Terbentuk dari beberapa bagian.


  • Bit 15, 14, 13 - tentukan kelas pengajaran
  • Bit 12 - Sign bit untuk instruksi tanda
  • Bit 11-0 - berisi 12 bit lebih rendah dari int-a yang ditandatangani. 4 bit yang paling signifikan dibentuk sesuai dengan nilai bit ke-12.

Tabel instruksi


Instruksi manualOpcodeOperasiSetara dengan BrainfuckDeskripsi
tambahkan m160X XXAP ← AP + m16'+' (Ulangi m16 kali)Menambahkan basis ke nilai saat ini dari sel yang dipilih
sub m161X XXAP ← AP - m16'-' (Ulangi m16 kali)Oleh karena itu, mengurangi basis dari
ada m162X XXAP ← AP + m16'>' (Ulangi m16 kali)Meningkatkan nilai alamat
iklan m163X XXAP ← AP - m16'<' (Ulangi m16 kali)Mengurangi nilai alamat.
jz m164X XX(* AP == 0)? IP ← IP + m16: IP ← IP'['Pergi ke IP + m16 jika nilai sel saat ini adalah nol
jz m165X XX(* AP == 0)? IP ← IP - m16: IP ← IPTidakPergi ke IP - m16 jika nilai sel saat ini adalah nol
jnz m166X XX(* AP! = 0)? IP ← IP + m16: IP ← IPTidakBuka IP + m16 jika nilai sel saat ini tidak nol
jnz m167X XX(* AP! = 0)? IP ← IP - m16: IP ← IP']'Pergi ke IP - m16 jika nilai sel saat ini tidak nol
dan m168X XXAP ← AP DAN m16TidakLogis DAN dengan angka positif
dan m169X XXAP ← AP DAN m16TidakLogis DAN dengan angka negatif (orang lain harus membentuk 4 bit tinggi)
atau m16aX XXAP ← AP ATAU m16TidakLogis ATAU dengan konstanta positif
atau m16bX XXAP ← AP ATAU m16TidakLogis ATAU dengan konstanta negatif
masukc0 00* AP ← CIN','Baca satu karakter m8 dari konsol. Jika buffer input kosong, tunggu.
keluarc0 01COUT ← * AP'.'Cetak karakter m8 ke konsol
clr.apd0 01AP ← 0TidakHapus register AP. Perintah ini memungkinkan kombinasi
clr.ipd0 02IP ← 0TidakHapus daftar IP. Perintah ini memungkinkan kombinasi
clr.dpd0 04* AP ← 0'[+]' atau '[-]'Bersihkan sel memori. Perintah ini memungkinkan kombinasi
set.apd0 10AP ← * APTidakTulis nilai saat ini ke register AP
set.ipd0 20IP ← * APTidakTulis nilai saat ini ke register IP
get.apd1 00* AP ← APTidakBaca nilai saat ini dari register AP
get.ipd2 00* AP ← IPTidakBaca nilai saat ini dari daftar IP
mode.b8e1 00TidakAktivasi 8-bit (1)
mode.b16e2 00TidakAktivasi 16-bit
berhentif0 00TidakHentikan mesin

  • AP - Alamat Register
  • IP - Instruksi Daftar
  • * AP - Lokasi memori saat ini
  • CIN - Input Konsol
  • COUT - Output Konsol

  1. Ketika mode 8-bit diaktifkan, penambah terus beroperasi dalam mode 16-bit. Namun, instruksi bersyarat (yaitu, menguji nilai sel memori saat ini untuk kesetaraan ke nol) menjadi 8-bit. ( AP & 0x00FF == 0)? dan ( AP & 0x00FF! = 0)? Input dan output konsol sejauh ini memutuskan untuk selalu meninggalkan 8-bit. Tidak di Unicode untuk mencetak pada akhirnya?

Dalam video ini, saya berbicara secara mendetail (tetapi hanya sedikit mengerti) tentang apa yang dilakukan oleh setiap instruksi dan apa yang berhubungan dengan instruksi yang berhubungan dengan:



Penambah paralel


Relai komputer tidak hanya merelay, tetapi juga cepat. Seperti komputer lainnya, komputer saya juga akan menjadi mesin sinkron, yang dilengkapi dengan generator jam. Secara alami, saya ingin tidak menyia-nyiakan siklus jam dan mencoba menyesuaikan setiap operasi menjadi satu siklus - yaitu, untuk naik dan turunnya tepi generator sinkron, saya dapat memuat perintah baru dan menjalankannya. Pada saat yang sama, diharapkan bahwa semua perintah dieksekusi untuk periode waktu yang sama.


Setiap relai memiliki penundaan tertentu dalam pengoperasian dan pelepasan, yang akan kami ambil untuk 1 satuan waktu konvensional (cu) Jika kami menggunakan relai RES22, 1u.e. akan sama dengan 12-15ms (informatif), RES64 - 1.3ms (informatif). Operasi paling mahal (dan paling sering) di mobil saya adalah penambah.
Dengan sendirinya, ini cukup sederhana dan cepat, tetapi "ada satu peringatan" yang terletak pada metode penghitungan dan transmisi sinyal transfer.



Gambar 2: Adder transfer serial.


Awalnya, saya berencana menggunakan adder carry berurutan. Pada penambah seperti itu, setiap pelepasan berikutnya tergantung pada keadaan sinyal transfer pelepasan dari yang sekarang. Akibatnya, durasi operasi perhitungan akan berfluktuasi antara 2 cu - N * 2 cu, dengan N adalah jumlah digit. Sebagai hasilnya, pengangkut sekuensial 16-bit akan memiliki penundaan maksimum 32 cu


Adder pengangkut paralel menawarkan kinerja maksimum. Mereka tidak memiliki proses penyebaran transfer dari debit ke debit. Di setiap kategori, nilai-nilai output secara bersamaan dihasilkan:



Gambar 3: Adder carry paralel


Kemampuan untuk membangun penambah dengan properti yang ditunjukkan didasarkan pada reproduksi jumlah dan fungsi transfer, yang hanya bergantung pada nilai-nilai persyaratan, terlepas dari lokasi pembuangan di grid pembuangan. Tangkapannya adalah bahwa skema transfer paralel itu sendiri menjadi lebih rumit dengan setiap debit berikutnya. Di sini, lihat apa yang terjadi:



Gambar 4: (Yang seharusnya dalam bentuk rumus LaTeX, tetapi tidak) Persamaan untuk menghitung sinyal transfer untuk bit. Dimana ki=ai cdotbi- bitwise Dan, hi=ai+bi- bitwise ATAU


Akibatnya, menerapkan migrasi paralel cukup mahal. Namun, dapat dicatat bahwa debit berikutnya berisi persamaan untuk menghitung yang sebelumnya (harus ada meme "oke ??" dengan Nicolas Cage), oleh karena itu, pada prinsipnya, akan cukup untuk membuat skema perhitungan transfer hanya untuk debit senior, dan mengumpulkan sisanya dari itu, menyediakan kesimpulan hasil antara.



Gambar 5: Diagram lengkap dari penambah paralel 16-bit


Pada Gambar 5, dua kolom pertama adalah adders itu sendiri. Kemudian ada blok 2AND dan 2OR, yang membentuk nilai-nilai menengah h dan k, yang ditunjukkan pada Gambar 4. Kehadiran mereka mendorong saya untuk memperluas daftar perintah dengan operasi logis penambahan dan perkalian, yang saya hanya perlu menambahkan beberapa kait dan mikrokode yang sesuai.


Yang lainnya adalah blok 5AND berdasarkan pada 4 relai RES64, yang dapat disolder sehingga satu modul dapat digunakan sebagai, misalnya, 2AND + 3AND. Untuk blok ini, setiap langkah AND logis adalah output melalui dioda, yang memungkinkan Anda untuk mengumpulkan sinyal transfer perantara.


Perkiraan waktu propagasi sinyal: adders mengatasi untuk 1 cu, saat ini sinyal dihasilkan pada output dari blok 2AND / 2OR, kemudian 1 cu - dengan perkalian dalam blok 5AND, penambahan logis pada dioda, tidak menyebabkan penundaan. Ya, yang terakhir dihabiskan untuk menghitung ulang penambah.


Total 3 cu versus 32, atau tidak lebih dari 4,5 ms untuk penambah.


Daftar


Ada empat register khusus 16-bit di dalam mesin. Tidak ada RON. Hanya pengikat yang ketat, hanya hardcore! Terdiri dari D-flip-flop, setiap D-flip-flop adalah modul terpisah pada 4 relay RES55 dengan sirkuit berikut:



Gambar 6: Diagram skematik modul D-flip-flop. Di suatu tempat masih ada konektor, tetapi di sini tidak penting, karena semuanya sudah ditandatangani.


Data datang ke input Data, relai yang menentukan ke mana sinyal sinkronisasi akan pergi - untuk mengatur ulang pemicu, atau untuk menginstalnya (yang mana dua relay lainnya bertanggung jawab, satu dengan penguncian sendiri). Relay keempat mendapatkan output switching Q. Fitur yang sangat berguna.


Papan memori



Gambar 7: Papan Memori. Dimensi papan 315x200mm


Elemen yang sangat kompleks dan penting, meskipun sirkuit memori itu sendiri adalah bagian kecil dari total pengisian blok. Tugas dewan ini adalah, pertama, untuk membawa 64 kilo dari total memori program dan data. Ini dirakit berdasarkan dua chip cache 64 Kbyte. Input alamat melalui sirkuit perlindungan dan sakelar terhubung ke bus alamat komputer, dan di sisi bus data sistem penyangga input dan driver output yang kompleks, juga dengan sakelar. Untuk membaca dan menulis ke memori, dua baris W / R dan Sinkronisasi bertanggung jawab. Yang pertama memilih apa yang akan kita lakukan, yang kedua - sebenarnya akan melakukannya.


Dan sementara Sinkronisasi ini sendiri tidak ada di sana, kartu memori secara alami menjalani hidupnya sendiri. Pada render, Anda dapat melihat dua matriks LED 16x16. Tampilan ini menunjukkan beberapa area memori. Semacam VideoRAM, ditentukan secara terprogram, omong-omong. Menginterogasi chip memori dan mengontrol output mikrokontroler Atmega1280.


Untuk sim, tugas-tugas mikrokontroler tidak berakhir di situ. Input dan output konsol bertahan di sana. Di mana akan dikeluarkan - saya belum memutuskan, oleh karena itu konverter USB-Serial untuk konsol reguler dan ESp8266 untuk Wi-Fi diceraikan di papan tulis. Menurut yang terakhir, dalam rencana yang paling mendesak untuk memiliki halaman web dengan kemampuan untuk mengunduh program untuk komputer ke dalam memori dan konsol itu sendiri. Ya, tugas MK juga termasuk pemuatan awal program ke dalam RAM, yang mana ia memiliki akses penuh ke RAM, serta EEPROM-in 1 Mbit kecil untuk menyimpan program.



Gambar 8: Diagram skematis kartu memori. Mikrokontroler dan diagram blok tidak ditampilkan


Blok logika


Saya tidak tahu bagaimana akhirnya dia akan terlihat. Versi terbaru hadir di sirkuit komputer umum, tetapi saya tidak menyukainya. Kemungkinan besar saya akan membuat sequencer 12-tahap dan dengan bantuan kunci saya akan mengirim sinyal ke blok individu.



Gambar 9: Segala sesuatu di sekitar blok 16-bit adalah blok logika


Konstruksi


Desain mesin adalah modular, bingkai balok. KDPV dengan jelas menunjukkan bagaimana mengisi mesin akan ditemukan. Tetapi hal pertama yang pertama:


Modul


Elemen dasar komputer adalah modul 60x44mm, dengan konektor 16-pin, membawa 4 relay, harness, dan 4 LED untuk menunjukkan:



Gambar 10: Model 3D modul


Modul dari berbagai jenis:


  1. 1-bit adder dengan transfer - 16 pcs;
  2. Modul 5AND untuk sirkuit transfer paralel - 32 pcs;
  3. Modul D-flip-flop - 64 pcs per register, ditambah sedikit logika;
  4. Modul 4x2AND_SW, untuk mengatur kait. Hanya ada 4 relay penutup;
  5. Modul 4x2AND, untuk mengatur kait. Ada 3 dari 4 relay dengan kontak changeover. Pada 4 relay tidak ada pin output yang cukup;
  6. Modul ini adalah dioda, 8 dioda D226D. Untuk mengatur multi-input OR
  7. Modul universal 2AND / 2OR, memungkinkan Anda membuat 2AND-NOT, 2OR-NOT, 4AND, 4AND-NOT, 4OR, 4OR-NOT, dan kombinasi apa pun. Berdasarkan 4 relay dengan switching kontak dan titik umum;

Karena saya, meskipun saya datang dengan blok logika kontrol, sudah ditolak, saya tidak tahu jumlah pasti dari setiap jenis modul. Saya akan mencari tahu di jalan. Estimasi jumlah modul adalah 192 buah.


Blokir


Kami mengambil papan 150x200mm, solder 32 konektor di atasnya dengan 16 pin, tetapi tidak yang sederhana, tetapi untuk membungkus dan menginstal modul kami di dalamnya dalam matriks 8x4, mendapatkan blok seperti itu:



Gambar 11: Blok


Di mobil saya akan ada 6 blok seperti itu - dua blok per adder, dua blok per register dan dua blok per logika. Saya menggaruk lobak tentang beberapa blok kait lagi, tetapi jika ada, maka mereka rata dan disolder


Instalasi sampul dipilih karena: pertama, sirkuit masing-masing papan dasar, meskipun diketahui sebelumnya, dapat berubah dan dapat mengalami kesalahan. Kedua, pada prinsipnya, tidak mungkin untuk secara benar memisahkan blok logika pertama kali, dan jika semuanya jelas untuk blok register dan Anda dapat membuat kesalahan dengan, katakanlah, garis sinkronisasi, maka Anda harus mengulang logika seribu satu kali. Akan jauh lebih baik jika Anda mengumpulkan setiap komponen dari blok logika secara bertahap. Ketiga, faktor murni mekanis - secara fisik tidak mungkin memisahkan blok-blok ini pada papan dua lapis :) Ban 16-bit berbeda dalam banyak arah, yang berulang kali saling berpotongan.


Secara total, setiap unit berisi 32 modul, dengan jumlah total relay sebanyak 128 buah. Kekuatan setiap unit adalah 5V 2A.


Komputer


Pada bingkai besar, dimensi 640x480 mm (sebenarnya sedikit lebih, tetapi jumlahnya indah) ada enam blok relai dan papan memori:



Gambar 12: Lokasi Blok Mesin


Seluruh komputer dimasukkan ke dalam bingkai kayu yang terbuat dari kayu berharga, dengan kaca depan dan belakang.


Pembuatan


Meskipun tanggal saat ini, proyek ini sebenarnya ada :-) Dan itu bukan dalam tahap paling aktif, tetapi masih pembuatan.


Relay


Saya memilikinya. Dalam jumlah besar, tetapi masalahnya adalah bahwa ada tiga ratus lebih dari seribu stok - relay dari 27 Volts dan 5-volt RES55 mungkin tidak cukup untuk saya. Saya akhirnya tidak bisa memperkirakan skala bencana, tetapi saya pikir pada waktu berikutnya bahwa saya akan mengumpulkan mesin neraka ini masalah akan hilang karena pengisian dari luar.



Gambar 13: Relay Relay. 800 buah relay - baru, berhasil disita di pasar radio Mitsa seharga satu sen


Salah satu sumber pengisian adalah papan relai DAC dari catu daya laboratorium. Ini dia:



Gambar 14: Papan dari catu daya jenis PSU dibeli di pasar radio (tidak, saya tidak


Papan sirkuit tercetak


Saya memutuskan untuk mengerjakan sendiri semua papan sirkuit cetak. Saya menjepit 300 dolar untuk orang Cina dan selama 4 bulan saya telah melakukan pekerjaan menutupi kekosongan dengan photoresist, tembus cahaya, etsa, tutup dengan topeng solder, pengembangan, pengeboran dan penggilingan.



Gambar 15: Panel berukir dari berbagai jenis


Saya membuat papan di piring, 9 modul di piring 200x150mm. Tergores 30 piring dan terjebak pada penerapan topeng solder. Saya tidak akan memulai dengan cara apa pun. Topeng solder FSR-8000 saya berwarna biru, dua komponen dan saya sudah pernah mengatasinya sebelumnya.


Piring 200x150mm tidak dipilih secara kebetulan - kami memilikinya di pasar radio, di satu tempat rahasia, mereka telah dijual dengan stabil selama bertahun-tahun, dan seluruh perangkat saya disesuaikan dengan format ini.


Singkatnya, saya mulai menerapkan photoresist (MPF-VSC dari Diazonium) menggunakan laminator dan ini hanyalah keajaiban. Kualitas pengeleman telah tumbuh secara signifikan.


Maka akan perlu untuk memotong dan mengebor papan ini, yang saya bahkan punya pemotong penggilingan 3D.



Gambar 16: Mesin Penggilingan 3D DIY Cina 2020CNC Cina


Saya mengambilnya untuk 175 dolar sederhana khusus untuk elektronik. Sudah cukup untuk mengebor dan menggiling papan, dan saya sudah melihat set bola-bola + rel untuk mesin 3D. Siap untuk membeli sedikit mahal, tetapi untuk merakit sendiri ketika mulai diperlukan - itu saja.


:




, . ( ) Elf. , ( ). //TODO — , .


: . , . . Segmentation Fault!


, . — . leBrainfuck , .
, , Brainfuck . +-<>, [-] . , . , .


. 8 . :



— 10 . LLVM 0,9 . Intel Vtune Amplifier 120 10 .


. , 3 brainfuck-. 100 50 347 — .. , ! , , . .


, , ,



.



-6 , , . — , . — . - — 30-40 - 6 .


????777



Referensi


openSource. :


  1. https://github.com/radiolok/RelayComputer2 - repositori dengan diagram skematik dan tata letak PCB. Tautan ke repositori firmware papan memori akan saya tambahkan nanti
  2. https://github.com/radiolok/RelayComputer2/blob/master/roadmap.md Saya akan secara terpisah mencatat halaman ini dengan peta jalan proyek tempat perubahan kunci dicatat.
  3. https://hackaday.io/project/18599-brainfuck-relay-computer di halaman ini saya menerbitkan laporan terperinci tentang apa yang telah dilakukan. Menurut seperangkat massa kritis, mereka akan berubah menjadi artikel tentang GT.
  4. https://github.com/radiolok/bfutils compiler dan emulator.

Source: https://habr.com/ru/post/id402629/


All Articles