Um artigo do site do louco engenheiro caseiro Chris Fenton
Conheça o ZedRipper, um monstro de 16 núcleos rodando a 83 MHz, equipado com processadores Z80, tão portátil quanto impraticável. Esta é minha tentativa mais recente de montar um computador por diversão e tendo satisfeito vários desejos ao mesmo tempo:
- Finalmente, use o FPGA gigante, que estava ao meu lado ocioso.
- Jogue uma história alternativa de criação de computadores, abordando a questão da multitarefa da perspectiva do ferro.
- Monte um computador no qual eu possa escrever programas curtos e engraçados a caminho do trabalho no trem.
- Monte uma plataforma na qual experimentos relativamente simples com arquitetura de computadores possam ser realizados.
Fotos glamourosas
Se você não tem tempo para ler uma folha de texto sobre arquitetura de computadores impraticável ...






Então, o que é essa fera?

O ZedRipper é o resultado de uma tentativa de construir o computador mais bacana com o CP / M 2.2:
- 16 processadores Z80 operando a uma frequência de 83,33 MHz.
- 64 KB de memória dedicada para cada Z80.
- Acelerador de terminal compatível com ANSI com 16 saídas.
- Todos os processadores e dispositivos são conectados por uma rede em anel unidirecional totalmente síncrona, operando a 83 MHz.
- Unidade de 128 MB em um cartão SD (unidades de 16 x 8 MB em CP / M).
- Um kernel de “servidor” que inicializa no CP / M 2.2 e executa o servidor de arquivos CP / NET (escrito em Turbo Pascal 3 no próprio computador!), Que fornece acesso compartilhado ao cartão SD.
- 15 kernels "cliente" iniciando o CP / NOS a partir da ROM. Cada cliente tem acesso a um repositório comum e todos podem executar qualquer programa do CP / M 2.2 sem competir por recursos com outros kernels.
Outra estrada
É o xadrez e a queda do planeta que me distraem do meu editor do Turbo Pascal?Após minhas aventuras ao
portar jogos para a Kaypro , tive uma impressão surpreendentemente calorosa desse sistema operacional primitivo, 40 anos atrás, e tive uma idéia que decidi desenvolver: e se a história mudasse na direção oposta e o PC continuasse caminhos de desenvolvimento com várias CPUs imediatamente? Mesmo na década de 1980, os próprios processadores (e logo a RAM) eram relativamente baratos, mas a multitarefa de PCs se baseava apenas em períodos de tempo em que um grande recurso (RAM ou CPU) era dividido entre os programas concorrentes. Iron não conseguiu lidar com isso (e era muito difícil fazer com que os programas se comportassem bem em sistemas operacionais como o DOS) até que passássemos para a era dos 386s e computadores com mais de 4 MB de memória.
Durante meus hobbies históricos com computadores, me deparei com algo muito interessante para mim: nos estágios iniciais de desenvolvimento, o
CP / M OS suportava uma versão em "rede" chamada CP / NET. A maioria das pessoas ainda conhece sua idéia hoje - colocar no escritório uma ou duas máquinas "reais" com grandes unidades e impressoras, cujos recursos seriam compartilhados entre thin clients, terminais com CPU e RAM. Cada usuário trabalhava como se tivesse sua própria máquina executando o CP / M com acesso a grandes discos e impressoras.
Como mencionei, CPU e RAM (geralmente o Z80 tinha 64 KB de DRAM) não eram particularmente caras, mas todos os membros externos necessários para criar um computador útil (discos, impressoras, monitores, etc.) somavam o custo total. Naquele tempo, adicionar várias CPUs / RAMs a um computador parecia uma abordagem um tanto decadente para fornecer a um usuário várias CPUs e RAMs. Até o CP / M dividiu o período de tempo do MP / M OS.
Descobri que a Exidy chegou mais perto disso - em 1981, eles lançaram sua máquina Multi-NET 80, que permitia adicionar até 16 placas, cada uma com Z80 e RAM. No entanto, ele foi projetado para funcionar com até 16 usuários individuais, e não para o trabalho de um único usuário que lançou simultaneamente 16 programas.
Tão perto ...Avanço rápido de 40 anos - os transistores caíram de preço. Após o fechamento do laboratório, herdei vários FPGAs monstruosos (Stratix IV 530GX) e achei que seria tão interessante fazer com um deles. Em algum momento, deparei-me com um projeto muito interessante de Grant Searle
Multi-Comp , e foi bastante fácil montar uma máquina que funcionava com CP / M e uma CPU. Mas eu precisava de mais. Decidi ver se era possível criar uma máquina com vários núcleos no CP / M com multitarefa real - nada complicado, apenas força bruta.
Configuramos e lançamos software
Neste projeto, concentrei-me principalmente no hardware e não escrevi uma única linha de código no assembler. A CPU 0 é carregada diretamente da ROM, que eu peguei de Grant, e os nós restantes são carregados da ROM de 4KB CP / NOS, que eu peguei do simulador Atari.
Ambas as ROMs aguardam uma conexão com um terminal serial por meio de uma interface padrão, enquanto os clientes CP / NOS esperam outra porta serial conectada a um servidor. É fácil projetar sua própria lógica em FPGAs tão grandes. Desenvolvi minha lógica de decodificação de endereços, graças à qual o Z-Ring para cada CPU aparece no esquema de mapeamento de endereços, quando necessário.
Interior

O coração do ZedRipper é um desses enormes FPGAs Stratix IV 530GX. O cartão HSMC é usado para exibição, recebendo dados do controlador do teclado e conectando ao cartão SD. A Ethernet é usada para baixar o firmware; portanto, existe uma porta na lateral do gabinete, juntamente com um adaptador de cartão SD e um slot para uma porta serial externa (ainda não usada).
Teclado e controlador
Teclado e orifício em primeiro plano, onde um dispositivo de posicionamento será instalado posteriormenteEu tinha um teclado PS / 2 compacto por aí (de um de meus projetos antigos com um laptop) e queria conectá-lo às E / S de 2,5 V do meu FPGA. Decidi seguir o caminho mais fácil e adicionar um microcontrolador Teensy 2.0 ao pacote.
Controlador de cola quente na parte inferior do tecladoIsso tornou possível converter o PS / 2 em ASCII, além de marcar facilmente algumas das teclas adicionais (F1-F12) em sequências "mágicas" de comandos do terminal, para maior comodidade. O controlador fornece então Z80 bytes para UART a 9600 baud (usando um divisor de tensão simples que muda de 5 V a 2,5 V para FPGA). Dado que este projeto foi montado a partir de vários tipos de lixo na minha oficina, foi uma solução conveniente que se mostrou bem no trabalho.
Exibição
A tela de carregamento, o servidor está sendo executado no canto superior esquerdo e três programas de usuário diferentes funcionam em kernels separadosRecursos do monitor: 1280 × 800 10,1 ″ e entende VGA. O FPGA usa uma rede simples de resistores para fornecer até 64 cores (R2G2B2). O visor requer um temporizador de 83,33 MHz (1280 × 800 a 60Hz); portanto, para simplificar, todo o circuito opera nessa frequência.
O projeto de Grant, Multicomp, tinha código VHDL para um terminal simples compatível com ANSI. Reescrevi sua lógica no Verilog e desenvolvi um controlador de vídeo com suporte para 16 terminais independentes conectados através de um nó Z-Ring. A exibição de 1280 × 800 é considerada uma exibição de caracteres de 160x50 (com fonte 8x16) e cada terminal funciona como um "sprite" de 80x25 que pode ser movido para qualquer lugar na tela (com uma lista de prioridades que ajusta a sequência de renderização do terminal). Como cada terminal opera independentemente dos outros, ele possui sua própria máquina de estado, com 2 KB de RAM para caracteres e 2 KB de "atributos" (para armazenar informações de cores). Cada caractere suporta cores de fundo e de caracteres de 4 bits. Como todos os terminais devem ter os mesmos caracteres de indentação e uma célula de 8x16 pode conter apenas um caractere, todos os terminais podem usar a mesma ROM de 2 KB contendo uma fonte. Em geral, a lógica de exibição usa cerca de 66 KB de bloco de RAM.
Em geral, recebo um gerenciador de janelas muito simples para meus terminais CP / M, que funciona quase completamente devido ao hardware. Essa é uma das áreas mais ricas em pesquisa - até agora, apenas a CPU do servidor é capaz de reorganizar os terminais, mas tenho planos de adicionar um dispositivo de posicionamento como um mouse, que permite usar o hardware do Windows apenas para arrastar janelas e alterar a prioridade dos monitores.
Como o controlador de terminal é apenas um dos nós do Z-Ring (e o redirecionamento dessa interface para qualquer um dos Z80 é muito simples), entre os planos futuros, é possível adicionar um terminal de "tela cheia" 160x50 (possivelmente como um "plano de fundo") e uma exibição real de 1280x800x64 cores com SRAM externa rápida na placa.
Anel em Z
Como montar um monte de Z80? No meu trabalho, aprendi firmemente uma coisa: desenvolver redes é difícil. Os objetivos gerais desta rede foram:
- Implementação simples.
- Interface simples
- Extensibilidade arbitrária.
- Desempenho adequado.
Como eu já mencionei, meus Z80s esperam se conectar a portas seriais, então a interface era bem simples de fazer - tinha que ser disfarçada de porta serial! Essencialmente, o Z-Ring é uma rede de anéis síncrona e unidirecional que usa "créditos" para controlar o fluxo. Cada nó possui um buffer de entrada de 1 byte para cada um dos outros nós na rede. Após uma redefinição, cada nó possui 1 "crédito" para cada um dos nós de rede restantes. O esquema é parametrizado, portanto, é facilmente escalável para centenas de nós com a adição de uma quantidade muito pequena de lógica; no entanto, hoje o Z-Ring suporta até 32 nós (portanto, cada nó precisa de um buffer de 32 bytes).
O "barramento" em si consiste em um bit de validade, um ID de "origem", um ID de "destino" e uma carga útil de 1 byte (19 bits). Eu acho que seria bastante simples de implementar usando a lógica TTL (se uma pessoa tivesse falhado em 1981 e não conseguisse encontrar um FPGA). Cada "nó" possui 2 pipelines para acionadores de barramento - estágios 0 e 1 - e quando você digita uma mensagem, ele espera até que o 0º estágio esteja vazio e depois se funde com o 1º. As mensagens são inseridas no nó de origem e viajam pelo anel até atingirem o destino, após o que se encontram no buffer apropriado e atualizam o sinalizador de prontidão de dados. Quando o nó receptor lê o buffer, ele reinsere a mensagem original, que continua a percorrer o anel até chegar à fonte novamente, retornando o “crédito”. Se você enviar o pacote para um endereço inexistente, o empréstimo será devolvido automaticamente após um círculo completo.
Como cada parada no anel consiste em dois estágios do transportador e não há contrapressão, cada mensagem leva no máximo 2 * (número de nós) ciclos de entrega. A implementação atual tem 17 nós (16 CPU + monitor / teclado controlador) e funciona em um temporizador de 12 ns; portanto, são necessários cerca de 400 ns para entregar uma mensagem e devolver um empréstimo. O controlador de vídeo pode enviar tráfego com uma taxa de chegada, de modo que cada CPU tenha uma largura de banda de 2-2,5 Mb / s ao seu terminal (o barramento passa o suficiente para fornecer todas as 16 CPUs), o que é bastante para os terminais.
Na configuração atual, tudo funciona bem, mas você pode fazer algumas melhorias óbvias:
- Para aprofundar os buffers de recebimento, o que aumentará a taxa de transferência dos nós - no FPGA há muitos blocos livres de 1 KB de RAM, que suportam 32 nós com 32 créditos, para que cada CPU, em teoria, possa saturar o barramento.
- Adicione suporte ao modo de endereço. Adicionar endereços de 16 bits (ou mais) permitirá acesso direto à memória (DMA) (e adicionar DMA a cada nó será simples). O FPGA possui uma enorme quantidade de hardware adicional (alguns megabytes de RAM estática e cerca de um gigabyte de DDR3).
- Adicione controle de fluxo (e buffer) entre os nós.
Mas tudo isso pode esperar até tempos melhores.
Nutrição!
Uma placa de depuração com FPGA requer energia de entrada de 12 a 20 V, um monitor precisa de 12 V e um teclado e controlador precisa de 5 V. É conveniente que o FPGA tenha controladores de 3,3, 5 e 12 V, que são muito fáceis de conectar, portanto O FPGA recebe energia diretamente de uma bateria de polímero de lítio a 5000 mAh com uma voltagem de 14,4 V e depois distribui energia para todos os outros dispositivos. Uma das dificuldades era que eu não queria desmontar o laptop todas as vezes para carregar, mas a bateria tinha um conector de alimentação + / - normal, bem como um conector de "balanceamento" conectado a cada célula individual. Minha solução imperfeita é que o botão liga / desliga alterne a conexão da bateria entre a energia FPGA e o conector de carregamento localizado no recesso fechado por uma tampa deslizante. Não é muito conveniente, mas você pode simplesmente deslizar a tampa e puxar os conectores de lá para conectá-los à carga sem usar as chaves sextavadas.
O carregamento parece estranhoNão testei a bateria completamente, mas dura pelo menos três horas (o que é mais do que suficiente para cobrir minhas viagens de trem). Muito provavelmente, durará cerca de 6 horas sem qualquer otimização do consumo. Ele não suporta o uso ao mesmo tempo que o carregamento, no entanto, o laptop funciona com bateria por tempo suficiente para que isso não seja um problema.
Habitação
O gabinete do design padrão "hacker" é uma combinação de compensado de corte a laser de 3 mm e plástico impresso em uma impressora 3D. Carreguei as dobradiças da tela, de modo que, na verdade, parece um laptop comum, embora um pouco lento. Eu queria dar a aparência da década de 1980, para que os cantos superiores da tela sejam um pouco como Cray, e o suporte de couro falso seja feito sob os pulsos. A borda da madeira compensada cortada a laser é muito desagradável para as mãos, portanto esse suporte era surpreendentemente funcional.
Velocidade
Eu não tentei um único benchmark especificamente para CP / M (presumo que sim, mas não o procurei). Como esta máquina foi criada para escrever programas no Turbo Pascal, tentei vários microtestes de velocidade. Foram realizadas operações de ponto flutuante de 15 a 35 K por segundo (usando o tipo Real de 48 bits no TP) e cerca de 1 milhão de operações inteiras por segundo (com o tipo inteiro de 16 bits). Nada mal para uma CPU de 8 bits e um ambiente de programação conveniente o suficiente.
Um projeto interessante para o futuro pode ser o desenvolvimento de um acelerador para operações de ponto flutuante.
Eliminação de FPGA
Toda a lógica, como eu já disse, é bastante leve e consome apenas cerca de 7% dos recursos do chip (embora 40% da RAM total do bloco e 100% da RAM M144k).
- ALUTs combinados 31.808 / 424.960 (7%)
- ALUTs de memória 0 / 212.480 (0%)
- Registros lógicos dedicados 10.231 / 424.960 (2%)
- Utilização lógica 10%
- Total de registros 10231
- Total de bits de memória de bloco 9.005.056 / 21.233.664 (42%)
- Elementos DSP de 18 bits do bloco 0 / 1.024 (0%)
Planos futuros
Nos meus planos imediatos (ou seja, o ferro já está na oficina, você só precisa encontrar tempo para soldar):
- Colorir tudo. O laptop é feito de madeira compensada e eu realmente quero cobri-lo com alguma coisa.
- Dispositivo de posicionamento do joystick Conecte-o ao controlador do teclado.
- Rastreamento de bateria. O ADC no controlador do teclado facilita o rastreamento da bateria, para que eu possa entender em que nível a carga.
- WiFi - Eu tenho o ESP32 para lançar o Zimodem! Juntamente com o telefone no modo de ponto de acesso, isso deve permitir que eu fique on-line em qualquer lugar. Existem boas aplicações de terminal para CP / M, mas seria bom escrever algo como um cliente de IRC ou um simples navegador da web. Também será conveniente usar o protocolo de transferência de arquivos Kermit para um computador Linux moderno.
- A porta serial, acessível do lado de fora, para conectar a outra máquina (um conector já foi impresso para ela, ele precisa ser soldado apenas).
- LED indicando o status atual. Para ele, já existe um buraco na frente - agora pretendo conectá-lo ao sinal de acesso ao cartão SD.
A longo prazo, estou ansioso por várias idéias de ferro, que serão divertidas de experimentar:
- Quanto você pode fazer um overclock do Z80? O primeiro passo é desatar a velocidade do processador do temporizador de pixels, no entanto, também será interessante tentar aplicar técnicas modernas de computador ao Z80 (pipelines, renomeação de registros, preditor de transição etc.).
- Pode ser interessante adicionar aceleradores especiais para operações como ponto flutuante. Existem 1024 blocos DSP não utilizados no chip, e acho que ninguém tentou criar um acelerador para o formato Real de 48 bits no TP.
- Use ferro existente! Ainda tenho um monte de memória não utilizada, a saber:
- SDRAM DDR3 de 512 MB com um barramento de dados de 64 bits
- SDRAM DDR3 de 128 MB com um barramento de dados de 16 bits
- Dois SRAMs QDR II + de 4 MB com barramentos de dados de 18 bits
- 64 MB de flash
- SSRAM de 2 MB
- Melhore o vídeo! O primeiro passo é adicionar suporte para o terminal "tela cheia" 160x50 e a capacidade de escalar para um terminal regular 80x25 2 vezes. O uso de uma SSRAM externa simplesmente adiciona o modo 1280 × 800 a 6 bits.
- Expanda os recursos do terminal atual. Acho que posso adicionar compatibilidade com um terminal como o ADM-3A (e adicionar suporte gráfico), que é usado no Kaypro / 84, então terei acesso a uma gama mais ampla de software (e não precisarei portar DD9).
Sumário
Até agora, o carro trabalha há apenas alguns dias, mas posso dizer que gosto muito de tudo. A tela é agradável e clara, o teclado é grande e confortável, o corpo é volumoso, mas pesa pouco (e cabe em uma mochila). O laptop era surpreendentemente ergonômico para trabalhar em um trem.
Eu acho que estou no caminho certo. A capacidade de abrir um editor de texto em uma janela para fazer anotações durante a depuração de código no TP em outra é extremamente conveniente (ou a capacidade de fazer anotações enquanto estiver jogando o Zork!). Considera-se que tal abordagem para a criação de computadores multitarefas de baixo custo com base no CP / M poderia existir.
Deseja construir o mesmo?
Até o momento, não tenho uma maneira fácil de obter arquivos da máquina; portanto, a parte mais útil do software (servidor de arquivos CP / Net escrito em Turbo Pascal) fica presa. Fique conosco e fique ligado (ou escreva-me
um e-mail se não puder esperar). - , , XXI github. , « ».