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:
- t (ASR) = 0ns
- / RAS: H
- /DINHEIRO
- A0-9: RA
- / W: H
- t (RAH) = 10ns
- / RAS: L
- /DINHEIRO
- A0-9: RA
- / W: H
- t (ASC) = 0ns
- / RAS: L
- /DINHEIRO
- A0-9: CA
- / W: H
- t (CAH) = 15ns
- / RAS: L
- / CAS: L
- A0-9: CA
- / W: H
- t (CAC) - t (CAH) =?
- / RAS: L
- / CAS: L
- A0-9: X
- / W: H (dados disponíveis)
- t (RP) = 40ns
- / RAS: H
- / CAS: L
- A0-9: X
- / W: X
- t (CP) = 10ns
- / RAS: H
- /DINHEIRO
- A0-9: X
- / W: X
Os horários a que me refiro estão no diagrama a seguir.
(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.
Respostas:
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.
fonte
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.
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.
fonte
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:
fonte