Un artículo del sitio del loco ingeniero casero Chris Fenton
Conozca el ZedRipper, una bestia de 16 núcleos que funciona a 83 MHz con procesadores Z80, tan portátil como poco práctico. Este es mi intento más reciente de ensamblar una computadora por diversión, y haber satisfecho varios deseos a la vez:
- Finalmente, use el FPGA gigante, que estaba acostado conmigo inactivo.
- Juega una historia alternativa de creación de computadoras, abordando el tema de la multitarea desde la perspectiva del hierro.
- Arme una computadora en la que pueda escribir programas cortos divertidos de camino al trabajo en el tren.
- Arme una plataforma en la que se puedan llevar a cabo experimentos relativamente simples con la arquitectura de la computadora.
Fotos glamorosas
Si no tiene tiempo para leer una hoja de texto sobre arquitectura de computadora poco práctica ...






Entonces, ¿qué es esta bestia?

ZedRipper es el resultado de un intento de construir la computadora más genial con CP / M 2.2:
- 16 procesadores Z80 que funcionan a una frecuencia de 83,33 MHz.
- 64 KB de memoria dedicada para cada Z80.
- Acelerador de terminal compatible con ANSI con 16 salidas.
- Todos los procesadores y dispositivos están conectados por una red de anillo unidireccional totalmente síncrona que funciona a 83 MHz.
- Unidad de 128 MB en una tarjeta SD (unidades de 16 x 8 MB en CP / M).
- Un núcleo de "servidor" que se inicia en CP / M 2.2 y ejecuta el servidor de archivos CP / NET (escrito en Turbo Pascal 3 en la computadora), que proporciona acceso compartido a la tarjeta SD.
- 15 núcleos "cliente" que inician CP / NOS desde ROM. Cada cliente tiene acceso a un repositorio común, y todos pueden ejecutar cualquier programa CP / M 2.2 sin competir por los recursos con otros núcleos.
Otro camino
¿Es el ajedrez y Planetfall lo que me distrae de mi editor de Turbo Pascal?Después de mis aventuras con
portar juegos a Kaypro , tuve una impresión sorprendentemente cálida de este primitivo sistema operativo hace 40 años, y tuve una idea que decidí desarrollar: ¿qué pasaría si la historia girara en la dirección opuesta y la PC continuara? ¿Rutas de desarrollo con múltiples CPU de inmediato? Incluso en la década de 1980, los procesadores mismos (y pronto RAM) eran relativamente baratos, pero la multitarea de PC se basaba únicamente en la reducción de tiempo cuando un recurso grande (RAM o CPU) se dividía entre programas competidores. Iron no pudo hacer frente a esto (y fue muy difícil lograr que los programas se comporten bien en sistemas operativos como DOS) hasta que nos adentramos en la era de los 386 y las computadoras con más de 4 MB de memoria.
Durante mis pasatiempos históricos con las computadoras, me encontré con algo muy interesante para mí: en las primeras etapas de desarrollo, el
CP / M OS soportaba una versión de "red" llamada CP / NET. La mayoría de la gente todavía conoce su idea hoy: poner en la oficina una o dos máquinas "reales" con grandes unidades e impresoras, cuyos recursos se compartirían entre clientes ligeros, terminales con CPU y RAM. Cada usuario trabajaría como si tuviera su propia máquina con CP / M con acceso a discos e impresoras grandes.
Como mencioné, la CPU y la RAM (generalmente el Z80 tenía 64 KB de DRAM) no eran particularmente costosas, pero todos los problemas externos necesarios para crear una computadora útil (discos, impresoras, monitores, etc.) sumaban el costo total. En ese momento, agregar múltiples CPU / RAM a una computadora parecía un enfoque algo decadente para proporcionar a un usuario múltiples CPU y RAM. Incluso CP / M ha tomado el camino de dividir los períodos de tiempo para MP / M OS.
Descubrí que Exidy se acercaba más a esto: en 1981 lanzaron su máquina Multi-NET 80, que permitía agregar hasta 16 tarjetas, cada una de las cuales tenía una Z80 y RAM. Sin embargo, fue diseñado para trabajar con hasta 16 usuarios individuales, y no para el trabajo de un solo usuario que lanzó simultáneamente 16 programas.
Tan cerca ...Avance rápido 40 años: los transistores han bajado de precio. Después del cierre del laboratorio, heredé varios FPGA monstruosos (Stratix IV 530GX), y pensé que sería muy interesante hacerlo con uno de ellos. En algún momento, me encontré con un proyecto muy interesante de Grant Searle
Multi-Comp , y fue bastante fácil ensamblar una máquina en funcionamiento con CP / M y una CPU. Pero necesitaba más. Decidí ver si podía crear una máquina multinúcleo en CP / M con multitarea real, nada complicado, solo fuerza bruta.
Configuramos y lanzamos software
En este proyecto, me concentré principalmente en hardware y no escribí una sola línea de código en ensamblador. La CPU 0 se carga directamente desde la ROM, que tomé de Grant, y los nodos restantes se cargan desde la ROM CP / NOS de 4KB, que tomé del simulador Atari.
Ambas ROM esperan una conexión a un terminal en serie a través de una interfaz estándar, mientras que los clientes CP / NOS esperan otro puerto en serie conectado a un servidor. Es fácil diseñar su propia lógica en tan grandes FPGA. Desarrollé mi lógica de decodificación de direcciones, gracias a la cual el anillo Z para cada CPU aparece en el esquema de mapeo de direcciones cuando es necesario.
Por dentro

El corazón del ZedRipper es uno de estos enormes FPGA Stratix IV 530GX. La tarjeta HSMC se utiliza para mostrar, recibir datos del controlador del teclado y conectarse a la tarjeta SD. Ethernet se usa para descargar el firmware, por lo que hay un puerto en el costado de la caja, junto con un adaptador de tarjeta SD y una ranura para un puerto serie externo (aún no se usa).
Teclado y controlador
Teclado y orificio en primer plano, donde se instalará un dispositivo de posicionamiento más tardeTenía un teclado PS / 2 compacto por ahí (de uno de mis proyectos anteriores con una computadora portátil), y quería conectarlo a la E / S de 2.5 V de mi FPGA. Decidí seguir el camino fácil y agregar un microcontrolador Teensy 2.0 al paquete.
Controlador de pegamento caliente en la parte inferior del tecladoEsto hizo posible traducir PS / 2 a ASCII, así como marcar fácilmente algunas de las teclas adicionales (F1-F12) en secuencias "mágicas" de comandos de terminal, para mayor comodidad. El controlador proporciona Z80 bytes para UART a 9600 baudios (usando un divisor de voltaje simple que cambia de 5 V a 2.5 V para FPGA). Dado que este proyecto fue ensamblado a partir de varias basuras en mi taller, fue una solución conveniente que se mostró bien en el trabajo.
Display
La pantalla de carga, el servidor se ejecuta en la esquina superior izquierda y tres programas de usuario diferentes funcionan en núcleos separadosCaracterísticas de la pantalla: 1280 × 800 10.1 ″, y entiende VGA. FPGA utiliza una red simple de resistencias para entregar hasta 64 colores (R2G2B2). La pantalla requiere un temporizador de 83.33 MHz (1280 × 800 @ 60Hz), por lo que, para simplificar, todo el circuito funciona a esta frecuencia.
El proyecto de Grant, Multicomp, tenía un código VHDL para un terminal simple compatible con ANSI. Reescribí su lógica en Verilog, y luego desarrollé un controlador de video con soporte para 16 terminales independientes conectados a través de un nodo Z-Ring. Una pantalla de 1280 × 800 se considera una pantalla de 160x50 caracteres (con fuente de 8x16), y cada terminal funciona como un "sprite" de 80x25 que se puede mover a cualquier lugar de la pantalla (con una lista de prioridades que ajusta la secuencia de representación del terminal). Dado que cada terminal funciona independientemente de los demás, tiene su propia máquina de estados, con 2 KB de RAM para caracteres y 2 KB de "atributos" (para almacenar información de color). Cada personaje admite colores de fondo y caracteres de 4 bits. Dado que todos los terminales deben tener los mismos caracteres de sangría, y solo un carácter puede estar contenido en una "celda" de 8x16, todos los terminales pueden usar la misma ROM de 2 KB que contiene una fuente. En general, la lógica de visualización utiliza aproximadamente 66 KB de RAM de bloque.
En general, obtengo un administrador de ventanas muy simple para mis terminales CP / M, que funciona casi completamente debido al hardware. Esta es una de las áreas más ricas para la investigación: hasta ahora, solo la CPU del servidor puede reorganizar los terminales, pero tengo planes de largo alcance para agregar un dispositivo de posicionamiento como un mouse, que permite usar el hardware de Windows solo para arrastrar ventanas y cambiar la prioridad de las pantallas.
Dado que el controlador de terminal es solo uno de los nodos Z-Ring (y redirigir esta interfaz a cualquiera de los Z80 es muy simple), entre los planes futuros es posible agregar un terminal de "pantalla completa" 160x50 (posiblemente como "fondo") y una pantalla real de 1280x800x64 colores con SRAM externo rápido en el tablero.
Anillo Z
¿Cómo armar un montón de Z80? En mi trabajo, aprendí firmemente una cosa: desarrollar redes es difícil. Los objetivos generales de esta red fueron:
- Implementación simple.
- Interfaz simple
- Extensibilidad arbitraria.
- Rendimiento adecuado.
Como ya mencioné, mis Z80 esperan conectarse a puertos serie, por lo que la interfaz fue bastante simple de hacer: ¡tenía que disfrazarse de puerto serie! Esencialmente, Z-Ring es una red de anillo sincrónica y unidireccional que utiliza "créditos" para controlar el flujo. Cada nodo tiene un búfer entrante de 1 byte para cada uno de los otros nodos en la red. Después de un reinicio, cada nodo tiene 1 "crédito" para cada uno de los nodos de red restantes. El esquema está parametrizado, por lo tanto, es fácilmente escalable a cientos de nodos con la adición de una cantidad muy pequeña de lógica, sin embargo, hoy Z-Ring admite hasta 32 nodos (por lo tanto, cada nodo necesita un búfer de 32 bytes).
El "bus" en sí consiste en un bit de validez, un ID de "fuente", un ID de "destino" y una carga útil de 1 byte (19 bits). Creo que sería bastante simple implementarlo usando la lógica TTL (si una persona hubiera fallado en 1981 y no pudiera encontrar un FPGA). Cada "nodo" tiene 2 canales para los activadores de bus (etapas 0 y 1) y cuando ingresa un mensaje, espera hasta que la etapa 0 esté vacía y luego se fusiona con la 1ra. Los mensajes se ingresan en el nodo de origen y viajan alrededor del anillo hasta que alcanzan el objetivo, después de lo cual se encuentran en el búfer apropiado y actualizan el indicador de disponibilidad de datos. Cuando el nodo receptor lee el búfer, vuelve a ingresar el mensaje original, que continúa viajando alrededor del anillo hasta que llega a la fuente nuevamente, devolviendo el "crédito". Si envía el paquete a una dirección inexistente, el préstamo se devolverá automáticamente después de un círculo completo.
Dado que cada parada en el anillo consta de dos etapas de transporte, y no hay contrapresión, cada mensaje no requiere más de 2 * (número de nodos) ciclos de entrega. La implementación actual tiene 17 nodos (16 CPU + controlador de pantalla / teclado), y funciona en un temporizador de 12 ns, por lo que se necesitan unos 400 ns para entregar un mensaje y devolver un préstamo. El controlador de pantalla puede enviar tráfico con una velocidad de llegada, por lo que cada CPU tiene un ancho de banda de 2-2.5 Mb / s a su terminal (el bus pasa lo suficiente como para proporcionar las 16 CPU), que es bastante para las terminales.
Todo funciona bien en la configuración actual, pero hay algunas mejoras obvias:
- Para profundizar las memorias intermedias receptoras, lo que aumentará el rendimiento de los nodos: en el FPGA hay muchos bloques libres de 1 KB de RAM, que admitirán 32 nodos con 32 créditos, por lo que cada CPU en teoría puede saturar el bus.
- Agregar soporte para el modo de dirección. Agregar direcciones de 16 bits (o más) permitirá el acceso directo a la memoria (DMA) (y agregar DMA a cada nodo será simple). FPGA tiene una gran cantidad de hardware adicional (unos pocos megabytes de RAM estática y aproximadamente un gigabyte de DDR3).
- Agregue control de flujo (y almacenamiento en búfer) entre nodos.
Pero todo esto puede esperar hasta tiempos mejores.
Nutrición!
Una placa de depuración con FPGA requiere una potencia de entrada de 12-20 V, la pantalla necesita 12 V, y el teclado y el controlador necesitan 5 V. Es conveniente que el FPGA tenga controladores de 3.3, 5 y 12 V, que son bastante fáciles de conectar, así que El FPGA recibe energía directamente de una batería de polímero de litio a 5000 mAh con un voltaje de 14.4 V, y luego distribuye energía a todos los demás dispositivos. Una de las dificultades fue que no quería desmontar la computadora portátil cada vez que se cargaba, pero la batería tenía un conector de alimentación normal + / -, así como un conector de "equilibrio" que se conectaba a cada celda individual. Mi solución imperfecta es que el botón de encendido cambia la conexión de la batería entre la alimentación FPGA y el conector de carga ubicado en el hueco cerrado por una cubierta deslizante. No es muy conveniente, pero puede simplemente deslizar la tapa y extraer los conectores desde allí para conectarlos a la carga sin usar las llaves hexagonales.
La carga se ve raraNo he probado la batería a fondo, pero dura al menos 3 horas (que es más que suficiente para cubrir mis viajes en tren). Lo más probable es que dure aproximadamente 6 horas sin ninguna optimización del consumo. No admite el uso al mismo tiempo que la carga, sin embargo, la computadora portátil funciona con batería el tiempo suficiente para que esto no sea un problema.
Vivienda
La carcasa del diseño estándar "hacker" es una combinación de madera contrachapada de corte láser de 3 mm y plástico impreso en una impresora 3D. Cargué por resorte las bisagras de la pantalla, por lo que, de hecho, se siente como una computadora portátil normal, aunque algo lenta. Quería darle el aspecto de la década de 1980, por lo que las esquinas superiores de la pantalla son un poco como Cray, y el soporte de cuero falso está hecho debajo de las muñecas. El borde de la madera contrachapada cortada con láser es muy desagradable para las manos, por lo que este soporte fue sorprendentemente funcional.
Velocidad
No he probado un solo punto de referencia específicamente para CP / M (supongo que sí, pero no lo busqué especialmente). Como esta máquina estaba hecha para escribir programas en Turbo Pascal, probé varias micropruebas de velocidad. Resultó 15-35 K operaciones de punto flotante por segundo (usando el tipo Real de 48 bits en TP), y aproximadamente 1 millón de operaciones enteras por segundo (con el tipo Entero de 16 bits). No está mal para una CPU de 8 bits y un entorno de programación lo suficientemente conveniente.
Un proyecto interesante para el futuro puede ser el desarrollo de un acelerador para operaciones de coma flotante.
Eliminación de FPGA
Toda la lógica, como ya dije, es bastante liviana y consume solo alrededor del 7% de los recursos del chip (aunque el 40% de la RAM total del bloque y el 100% de la RAM M144k).
- ALUT combinacionales 31,808 / 424,960 (7%)
- ALUT de memoria 0 / 212,480 (0%)
- Registros lógicos dedicados 10,231 / 424,960 (2%)
- Utilización lógica 10%
- Registros totales 10231
- Total de bits de memoria de bloque 9,005,056 / 21,233,664 (42%)
- Bloque DSP elementos de 18 bits 0 / 1.024 (0%)
Planes futuros
En mis planes inmediatos (es decir, el hierro ya está en el taller, solo necesita encontrar el tiempo para soldar):
- Colorea todo. La computadora portátil está hecha de madera contrachapada, y realmente quiero cubrirla con algo.
- Dispositivo de posicionamiento de joystick Conéctelo al controlador del teclado.
- Seguimiento de batería. ADC en el controlador del teclado hace que sea bastante fácil rastrear la batería, para que pueda entender a qué nivel de carga.
- WiFi: ¡tengo ESP32 por ahí para lanzar Zimodem! Junto con el teléfono en el modo de punto de acceso, esto debería permitirme conectarme en línea sobre la marcha. Hay buenas aplicaciones de terminal para CP / M, pero sería bueno escribir algo como un cliente IRC o un simple navegador web. También será conveniente usar el protocolo de transferencia de archivos Kermit a una computadora Linux moderna.
- El puerto serie, accesible desde el exterior, para conectarse a otra máquina (ya se ha impreso un conector para él, solo necesita ser soldado).
- LED que indica el estado actual. Para él, ya hay un agujero en el frente, ahora planeo conectarlo a la señal de acceso a la tarjeta SD.
A largo plazo, espero varias ideas de hierro, con las cuales será divertido experimentar:
- ¿Cuánto puedes overclockear el Z80? El primer paso es desatar la velocidad del procesador del temporizador de píxeles, sin embargo, también será interesante intentar aplicar técnicas informáticas modernas al Z80 (tuberías, cambio de nombre de registro, predictor de transición, etc.).
- Puede ser interesante agregar aceleradores especiales para cosas como operaciones de punto flotante. Hay 1024 bloques DSP no utilizados en el chip, y creo que nadie ha intentado construir un acelerador para el formato Real de 48 bits en TP.
- ¡Use hierro existente! Todavía tengo un montón de memoria no utilizada, a saber:
- 512 MB de SDRAM DDR3 con un bus de datos de 64 bits
- 128 MB DDR3 SDRAM con un bus de datos de 16 bits
- Dos SRAM QDR II + de 4 MB con buses de datos de 18 bits
- 64 MB de flash
- SSRAM de 2 MB
- ¡Mejora el video! El primer paso es agregar soporte para el terminal de "pantalla completa" 160x50, y la capacidad de escalar a un terminal regular 80x25 2 veces. El uso de una SSRAM externa simplemente agregará el modo 1280 × 800 a 6 bits.
- Amplíe las capacidades del terminal actual. Creo que puedo agregar compatibilidad con un terminal como ADM-3A (y agregar soporte de gráficos), que se usa en Kaypro / 84, luego tendré acceso a una gama más amplia de software (y no tendré que portar DD9).
Resumen
Hasta ahora, el automóvil ha estado funcionando solo unos pocos días, pero puedo decir que realmente me gusta todo. La pantalla es bonita y clara, el teclado es grande y cómodo, el cuerpo es voluminoso, pero pesa poco (y cabe en una mochila). El portátil era incluso sorprendentemente ergonómico para trabajar en un tren.
Creo que estoy en el camino correcto. La capacidad de abrir un editor de texto en una ventana para tomar notas mientras se depura el código en TP en otra es extremadamente conveniente (¡o la capacidad de tomar notas mientras se juega Zork!). Se cree que tal enfoque para la creación de computadoras multitarea de bajo costo basadas en CP / M podría existir.
¿Quieres construir lo mismo?
Hasta ahora, no tengo una manera fácil de obtener archivos de la máquina, por lo que la parte más útil del software (servidor de archivos CP / Net escrito en Turbo Pascal) está atrapado. Quédese con nosotros y esté atento (o escríbame
un correo electrónico si no puede esperar).
En algún momento, probablemente me uniré al siglo XXI y abriré una cuenta en github. Por desgracia, todo se basa en ese mismo "tiempo libre".