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 manual | Opcode | Operasi | Setara dengan Brainfuck | Deskripsi |
---|
tambahkan m16 | 0X XX | AP ← AP + m16 | '+' (Ulangi m16 kali) | Menambahkan basis ke nilai saat ini dari sel yang dipilih |
sub m16 | 1X XX | AP ← AP - m16 | '-' (Ulangi m16 kali) | Oleh karena itu, mengurangi basis dari |
ada m16 | 2X XX | AP ← AP + m16 | '>' (Ulangi m16 kali) | Meningkatkan nilai alamat |
iklan m16 | 3X XX | AP ← AP - m16 | '<' (Ulangi m16 kali) | Mengurangi nilai alamat. |
jz m16 | 4X XX | (* AP == 0)? IP ← IP + m16: IP ← IP | '[' | Pergi ke IP + m16 jika nilai sel saat ini adalah nol |
jz m16 | 5X XX | (* AP == 0)? IP ← IP - m16: IP ← IP | Tidak | Pergi ke IP - m16 jika nilai sel saat ini adalah nol |
jnz m16 | 6X XX | (* AP! = 0)? IP ← IP + m16: IP ← IP | Tidak | Buka IP + m16 jika nilai sel saat ini tidak nol |
jnz m16 | 7X XX | (* AP! = 0)? IP ← IP - m16: IP ← IP | ']' | Pergi ke IP - m16 jika nilai sel saat ini tidak nol |
dan m16 | 8X XX | AP ← AP DAN m16 | Tidak | Logis DAN dengan angka positif |
dan m16 | 9X XX | AP ← AP DAN m16 | Tidak | Logis DAN dengan angka negatif (orang lain harus membentuk 4 bit tinggi) |
atau m16 | aX XX | AP ← AP ATAU m16 | Tidak | Logis ATAU dengan konstanta positif |
atau m16 | bX XX | AP ← AP ATAU m16 | Tidak | Logis ATAU dengan konstanta negatif |
masuk | c0 00 | * AP ← CIN | ',' | Baca satu karakter m8 dari konsol. Jika buffer input kosong, tunggu. |
keluar | c0 01 | COUT ← * AP | '.' | Cetak karakter m8 ke konsol |
clr.ap | d0 01 | AP ← 0 | Tidak | Hapus register AP. Perintah ini memungkinkan kombinasi |
clr.ip | d0 02 | IP ← 0 | Tidak | Hapus daftar IP. Perintah ini memungkinkan kombinasi |
clr.dp | d0 04 | * AP ← 0 | '[+]' atau '[-]' | Bersihkan sel memori. Perintah ini memungkinkan kombinasi |
set.ap | d0 10 | AP ← * AP | Tidak | Tulis nilai saat ini ke register AP |
set.ip | d0 20 | IP ← * AP | Tidak | Tulis nilai saat ini ke register IP |
get.ap | d1 00 | * AP ← AP | Tidak | Baca nilai saat ini dari register AP |
get.ip | d2 00 | * AP ← IP | Tidak | Baca nilai saat ini dari daftar IP |
mode.b8 | e1 00 | | Tidak | Aktivasi 8-bit (1) |
mode.b16 | e2 00 | | Tidak | Aktivasi 16-bit |
berhenti | f0 00 | | Tidak | Hentikan mesin |
- AP - Alamat Register
- IP - Instruksi Daftar
- * AP - Lokasi memori saat ini
- CIN - Input Konsol
- COUT - Output Konsol
- 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 - bitwise Dan, - 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-bit adder dengan transfer - 16 pcs;
- Modul 5AND untuk sirkuit transfer paralel - 32 pcs;
- Modul D-flip-flop - 64 pcs per register, ditambah sedikit logika;
- Modul 4x2AND_SW, untuk mengatur kait. Hanya ada 4 relay penutup;
- Modul 4x2AND, untuk mengatur kait. Ada 3 dari 4 relay dengan kontak changeover. Pada 4 relay tidak ada pin output yang cukup;
- Modul ini adalah dioda, 8 dioda D226D. Untuk mengatur multi-input OR
- 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. :
- https://github.com/radiolok/RelayComputer2 - repositori dengan diagram skematik dan tata letak PCB. Tautan ke repositori firmware papan memori akan saya tambahkan nanti
- https://github.com/radiolok/RelayComputer2/blob/master/roadmap.md Saya akan secara terpisah mencatat halaman ini dengan peta jalan proyek tempat perubahan kunci dicatat.
- 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.
- https://github.com/radiolok/bfutils compiler dan emulator.