Como posso implementar um controlador DRAM assíncrono muito simples?

9

Eu gostaria de saber como criar um controlador DRAM assíncrono bare bones. Eu tenho alguns módulos de 30 pinos SIMM 70ns DRAM de 1MB e 30 MB (1Mx9 com paridade) que eu gostaria de usar em um projeto de computador retro homebrew. Infelizmente, não há uma folha de dados para eles, portanto, eu vou do Siemens HYM 91000S-70 e "Understanding DRAM Operation" da IBM.

A interface básica com a qual gostaria de terminar é

  • / CS: in, seleção de chip
  • R / W: entrada, leitura / não gravação
  • RDY: fora, ALTO quando os dados estão prontos
  • D: entrada / saída, barramento de dados de 8 bits
  • A: barramento de endereço de 20 bits

A atualização parece bem direta, com várias maneiras de fazê-lo corretamente. Eu deveria poder fazer a atualização distribuída (intercalada) somente RAS (ROR) durante o clock da CPU LOW (onde nenhum acesso à memória é feito nesse chip específico) usando qualquer contador antigo para o rastreamento de endereço de linha. Acredito que todas as linhas precisam ser atualizadas pelo menos a cada 64ms de acordo com o JEDEC (512 por 8ms de acordo com o datasheet Seimens, isto é, atualização padrão do ciclo / 15.6us), portanto, isso deve funcionar bem e, se eu ficar preso, postarei outra pergunta. Estou mais interessado em ler e escrever simples, correto e determinar o que devo esperar em termos de velocidade.

Primeiro, descreverei rapidamente como acho que funciona e as possíveis soluções que tenho encontrado até agora.

Basicamente, você divide um endereço de 20 bits pela metade, usando uma metade para a coluna e a outra para a linha. Você estroboscópica o endereço da linha e, em seguida, o endereço da coluna, se / W for ALTO quando / CAS for BAIXO, será uma leitura, caso contrário, será uma gravação. Se for uma gravação, os dados já deverão estar no barramento de dados nesse ponto. Após um período de tempo, se for uma leitura, os dados estarão disponíveis ou se for uma gravação, com certeza os dados foram gravados. Então / RAS e / CAS precisam ser trazidos ALTO novamente no período chamado "pré-carga" contra-intuitivamente. Isso completa o ciclo.

Então, basicamente é uma transição através de vários estados com atrasos específicos não uniformes entre cada transição. Eu listei isso como uma "tabela" indexada pela duração de cada fase da transação na ordem:

  1. t (ASR) = 0ns
    • / RAS: H
    • /DINHEIRO
    • A0-9: RA
    • / W: H
  2. t (RAH) = 10ns
    • / RAS: L
    • /DINHEIRO
    • A0-9: RA
    • / W: H
  3. t (ASC) = 0ns
    • / RAS: L
    • /DINHEIRO
    • A0-9: CA
    • / W: H
  4. t (CAH) = 15ns
    • / RAS: L
    • / CAS: L
    • A0-9: CA
    • / W: H
  5. t (CAC) - t (CAH) =?
    • / RAS: L
    • / CAS: L
    • A0-9: X
    • / W: H (dados disponíveis)
  6. t (RP) = 40ns
    • / RAS: H
    • / CAS: L
    • A0-9: X
    • / W: X
  7. t (CP) = 10ns
    • / RAS: H
    • /DINHEIRO
    • A0-9: X
    • / W: X

Os horários a que me refiro estão no diagrama a seguir.

diagrama de tempo

(CA = endereço da coluna, RA = endereço da linha, X = não se importa)

Mesmo que não seja exatamente isso, é algo assim e acho que o mesmo tipo de solução funcionará. Então, eu tenho algumas idéias até agora, mas acho que apenas a última tem potencial e estou procurando por melhores idéias. Estou ignorando a atualização, verificação rápida de páginas e paridade / geração aqui.

A solução mais simples é usar um contador e uma ROM em que a saída do contador é a entrada do endereço da ROM e cada byte possui a saída de estado apropriada para o período de tempo ao qual o endereço corresponde. Isso não funcionará porque as ROMs são lentas. Até mesmo uma SRAM pré-carregada parece muito lenta para valer a pena.

A segunda idéia foi usar um GAL16V8 ou algo assim, mas acho que não os entendo direito o suficiente, os programadores são muito caros e o software de programação é de código fechado e Windows - somente até onde eu sei.

Minha última idéia é a única que acho que pode realmente funcionar. A família lógica 74ACT possui baixos atrasos de propagação e aceita altas frequências de clock. Estou pensando leitura e gravação poderia ser feito com alguma CD74ACT164E registrador de deslocamento e SN74ACT573N .

Basicamente, cada estado único obtém sua própria trava programada estaticamente usando trilhos de 5V e GND. Cada saída do registro de deslocamento vai para o pino de uma trava / OE. Se eu entendi direito as folhas de dados, o atraso entre cada estado poderia ser apenas 1 / SCLK, mas isso é muito melhor do que uma solução PROM ou 74HC.

Então, é provável que a última abordagem funcione? Existe uma maneira mais rápida, menor ou geralmente melhor de fazer isso? Acho que vi que o IBM PC / XT usava chips 7400 para algo relacionado à DRAM, mas só vi fotos de primeira linha, então não tenho certeza de como isso funcionou.

ps Gostaria que isso fosse possível no DIP e não "trapaceie" usando um FPGA ou um uC moderno.

Talvez usando o atraso do gate diretamente com a mesma abordagem de trava seja uma idéia melhor. Percebo que os métodos de registro de turno e atraso direto de porta / propagação variarão com a temperatura, mas eu aceito isso.

Para qualquer um que encontrar isso no futuro, essa discussão entre Bil Herd e André Fachat abrange vários dos projetos mencionados neste tópico e discute outros problemas, incluindo testes de DRAM.

Anthony
fonte
11
Qual CPU o seu computador retrô vai usar?
Anônimo
6502, a memória será depositada obviamente.
Anthony
É possível não inventar bicicletas para você, já existem modelos disponíveis usando DRAMs? Não estou familiarizado com esta família de máquinas, mas o C64 deve ser uma boa combinação. No entanto, originalmente usa o chip 6567 "VIC" para controlar a RAM. Mas, novamente, tenho certeza desde então que havia projetos relacionados ao que você quer fazer.
Anônimo
3
Uma sugestão um pouco distorcida: o Z80 tinha um controlador DRAM embutido o suficiente para lidar com a lógica de atualização. (Você ainda precisava endereço multiplexer embora)
Brian Drummond
3
@BrianDrummond Por favor, não recomendo ir para o lado sombrio. Nada de bom pode resultar disso.
pipe

Respostas:

6

Existem esquemas completos para o IBM PC / XT no manual de referência técnica do IBM Personal Computer XT (Apêndice D), que você pode encontrar on-line.

O problema aqui é que, dada uma linha estroboscópica que é ativada em uma leitura ou gravação de memória, você deseja gerar RAS, CAS e uma linha de controle (chamada MUX) para o multiplexador de endereço. Por uma questão de simplicidade, assumirei de maneira irrealista que o estroboscópio, o RAS e o CAS estão todos ativos alto.

Observando o esquema PC / XT e os esquemas de alguns outros computadores nesse período, vejo três estratégias básicas, que são aproximadamente as seguintes:

  • Use o estroboscópio para o RAS. Use uma linha de atraso (uma parte cuja saída é uma versão com atraso de sua entrada) no RAS para gerar MUX e use outra linha de atraso para gerar uma versão ainda mais recente do RAS, usada para CAS. Essa estratégia é usada pelo PC / XT e pelo TRS-80 Modelo II.

    Um exemplo (moderno) de parte da linha de atraso é o Maxim DS1100.

  • Use o estroboscópio para o RAS e adie-o para MUX e CAS, mas faça isso usando um registro de turno de alta velocidade em vez de uma linha de atraso. Essa estratégia é usada pelo TRS-80 Modelo I e pelo Apple II.

  • Use ICs personalizados. Esta é a estratégia do Commodore 64.

David Moews
fonte
Aparentemente, eu só encontrei um XT TR sem o Apêndice D ontem. Eu tenho agora, isso é ótimo. Eu não sabia que esses CIs de linha de atraso existiam e fiquei imaginando como eles lidavam com a temperatura. Obrigado por mencionar o exemplo moderno. +1 para várias soluções também.
15138 Anthony
5

Sua pergunta é complicada o suficiente para que eu nem tenha certeza do seu problema real, mas vou tentar!

O design de DRAM "mais limpo" baseado em 6502 que encontrei é do Commodore PET 2001-N . Ele tem um 6502 rodando a 1 MHz, mas a lógica DRAM tem clock de 16 MHz, provavelmente gerando todos os tempos.

Não analisei os detalhes, mas a ação principal parece ocorrer com um contador 74191 de 4 bits conectado a um registrador de deslocamento 74164. Isso gera 8 linhas separadas para um 74157 MUX, que é controlado pela linha R / W. A saída do MUX entra em um flip-flop 7474 e alguma lógica discreta para gerar os sinais RAS / CAS finais. Aqui está um trecho vinculado à página relevante no esquema de referência.

Página de referência do PET 2001-N 6

A atualização é tratada com um contador separado e cada linha de endereço é conectada a um multiplexador que seleciona o endereço "real" ou o endereço de atualização.

Partes dessa lógica também parecem gerar tempos para o subsistema de vídeo. Tenho certeza de que pode ser simplificado para suas necessidades específicas, mas acho que algo semelhante pode ser útil: um contador de alta frequência, registrador de turnos e multiplexadores.

tubo
fonte
Era nisso que eu estava pensando, mas eu era burro o suficiente para pensar em várias travas em vez de um MUX ou dois. O clock de 16Mhz me tropeça porque a) é muito maior que o clock da CPU, o que eu achei estranho, mas faz sentido eb) as fases podem ter no mínimo ~ 62ns mais atrasos de propagação que eu achava lento, mas agora eu veja que está na mesma ordem que o IBM PC / XT.
Anthony
O Apple II é muito semelhante, usando o relógio de vídeo de 14,318 MHz para cronometrar e compartilhar a memória entre a CPU e o vídeo em semiciclos alternativos sem contenção. Ele nem precisa de um contador de atualização separado, porque a atividade de atualização de vídeo serve para manter a memória atualizada também.
Dave Tweed
-2

ps Gostaria que isso fosse possível no DIP e não "trapaceie" usando um FPGA ou um uC moderno.

Embora eu compreenda completamente o espírito do seu projeto e seu desejo de usar peças não sofisticadas, eu definitivamente seguiria o caminho FPGA se fosse você .

Vários motivos:

  1. É uma oportunidade de aprendizado perfeita. Projetar um controlador DRAM não é um projeto "olá mundo" e, depois disso, você pode dizer com confiança que "pode ​​fazer" FPGA;
  2. Você pode extrair todo o desempenho dessa memória, principalmente se for um chip DRAM mais antigo. Não apenas você teria o seu PC baseado em 6502, mas também seria possível ter o PC mais rápido em 6502;
  3. Pode ser muito mais fácil depurar problemas ou fazer estatísticas das operações de memória que sua CPU emitiu. Você pode usar analisadores lógicos em barramentos paralelos, mas nunca é divertido (um amigo meu faz algo nesse sentido - ele quer escrever uma simulação de ciclo exato de 8088 e, por esse motivo, precisa coletar essas estatísticas sobre acessos e tempos de memória Ele usa o chipset original (8288, 8280, 8237) e usa um analisador lógico com muitos canais, mas, por sua experiência, posso dizer que é uma chatice).
anrieff
fonte
2
Não tenho certeza de como isso é uma resposta em vez de um comentário. 1) Ele não diz que quer aprender FPGAs. 2) DRAMs dos anos 80 já são lentas o suficiente para lógica discreta. 3) A depuração pode ser difícil. Por que não implementar tudo no FPGA, ou mesmo apenas em software? Por que usar a RAM em todos os ... :) #
pipe
11
@ tubulações: Sim, exatamente. Não quero gastar tempo aprendendo FPGAs no momento. Eu já tenho o suficiente no meu prato com um segundo projeto analógico não relacionado. Os FPGAs e PLDs em geral sentem que estão no caminho neste momento, mesmo que algum dia eu aprenderei a usá-los.
Anthony
11
@pipe: A recondicionamento de pranchas costuma ser difícil, demorada e frustrante, especialmente se alguém não é particularmente habilitado. O uso de alguns PLDs bastante simples (por exemplo, 22V10) para algumas partes do design facilitará o ajuste.
Supercat