Me gustaría saber cómo construir un controlador DRAM asíncrono básico. Tengo algunos módulos DRAM SIMM 70ns 1MB de 30 pines (1Mx9 con paridad) que me gustaría usar en un proyecto de computadora retro casero. Desafortunadamente, no hay una hoja de datos para ellos, así que he estado yendo del Siemens HYM 91000S-70 y "Entendiendo la operación DRAM" de IBM.
La interfaz básica con la que me gustaría terminar es
- / CS: en, selección de chip
- R / W: en, leer / no escribir
- RDY: fuera, ALTO cuando los datos están listos
- D: entrada / salida, bus de datos de 8 bits
- A: en, bus de direcciones de 20 bits
Actualizar parece bastante sencillo con varias formas de hacerlo bien. Debería poder hacer una actualización distribuida (intercalada) solo RAS (ROR) durante el reloj de la CPU BAJO (donde no se realiza acceso a la memoria en este chip en particular) usando cualquier contador antiguo para el seguimiento de la dirección de la fila. Creo que todas las filas deben actualizarse al menos cada 64 ms según JEDEC (512 por 8 ms según la hoja de datos de Seimens, es decir, actualización estándar del ciclo / 15.6us), por lo que esto debería funcionar bien y si me atoro, simplemente publicaré otra pregunta. Estoy más interesado en leer y escribir de manera simple, correcta y determinar qué debo esperar en cuanto a velocidad.
Primero describiré rápidamente cómo creo que funciona y las posibles soluciones que he encontrado hasta ahora.
Básicamente, divide una dirección de 20 bits por la mitad, utilizando una mitad para la columna y la otra para la fila. Estroboscópico la dirección de la fila, luego la dirección de la columna, si / W es ALTO cuando / CAS baja, entonces es una lectura, de lo contrario es una escritura. Si se trata de una escritura, los datos ya deben estar en el bus de datos en ese punto. Después de un período de tiempo, si es una lectura, entonces los datos están disponibles o si es una escritura, es seguro que los datos se han escrito. Luego, / RAS y / CAS deben volverse ALTOS nuevamente en el período de "precarga" contraintuitivo. Esto completa el ciclo.
Entonces, básicamente es una transición a través de varios estados con demoras específicas no uniformes entre cada transición. Lo he enumerado como una "tabla" indexada por la duración de cada fase de la transacción en orden:
- t (ASR) = 0ns
- /ERUPCIÓN
- / CAS: H
- A0-9: RA
- / W: H
- t (RAH) = 10ns
- / RAS: L
- / CAS: H
- A0-9: RA
- / W: H
- t (ASC) = 0ns
- / RAS: L
- / CAS: H
- 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 (datos disponibles)
- t (RP) = 40ns
- /ERUPCIÓN
- / CAS: L
- A0-9: X
- / W: X
- t (CP) = 10ns
- /ERUPCIÓN
- / CAS: H
- A0-9: X
- / W: X
Los tiempos a los que me refiero están en el siguiente diagrama.
(CA = dirección de columna, RA = dirección de fila, X = no me importa)
Incluso si no es exactamente eso, es algo así y creo que el mismo tipo de solución funcionará. Así que hasta ahora he tenido un par de ideas, pero creo que solo la última tiene potencial y estoy buscando mejores ideas. Estoy ignorando la actualización / verificación rápida de página y paridad / generación aquí.
La solución más simple es usar un contador y una ROM donde la salida del contador es la entrada de la dirección ROM y cada byte tiene la salida de estado apropiada para el período de tiempo al que corresponde la dirección. Esto no funcionará porque las ROM son lentas. Incluso una SRAM precargada parece que sería demasiado lenta para que valga la pena.
La segunda idea era usar un GAL16V8 o algo así, pero creo que no los entiendo lo suficientemente bien, los programadores son muy caros y el software de programación es de código cerrado y solo Windows hasta donde yo sé.
Mi última idea es la única que creo que podría funcionar. La familia lógica 74ACT tiene retrasos de propagación bajos y acepta frecuencias de reloj altas. Estoy pensando que leer y escribir podría hacerse con un registro de desplazamiento CD74ACT164E y SN74ACT573N .
Básicamente, cada estado único tiene su propio enganche programado estáticamente usando rieles 5V y GND. Cada salida del registro de desplazamiento va a un pin de pestillo / OE. Si entiendo bien las hojas de datos, el retraso entre cada estado solo podría ser 1 / SCLK, pero eso es mucho mejor que una solución PROM o 74HC.
Entonces, ¿es probable que el último enfoque funcione? ¿Existe una forma más rápida, más pequeña o generalmente mejor de hacer esto? Creo que vi que la PC / XT de IBM usaba 7400 chips para algo relacionado con la DRAM, pero solo vi fotos en la placa superior, así que no estoy seguro de cómo funcionó.
PD: Me gustaría que esto sea factible en DIP y no "engañar" con un FPGA o uC moderno.
pps Tal vez sea mejor usar el retraso de puerta directamente con el mismo enfoque de bloqueo. Me doy cuenta de que tanto el registro de desplazamiento como los métodos de retardo directo de puerta / propagación variarán con la temperatura, pero acepto esto.
Para cualquiera que encuentre esto en el futuro, esta discusión entre Bil Herd y André Fachat cubre varios de los diseños mencionados en este hilo y discute otros problemas, incluidas las pruebas de DRAM.
Respuestas:
Hay esquemas completos para IBM PC / XT en el manual de referencia técnica de IBM Personal Computer XT (Apéndice D), que puede encontrar en línea.
El problema aquí es que, dada una línea estroboscópica que se activa al leer o escribir en la memoria, desea generar RAS, CAS y una línea de control (llamada MUX) para el multiplexor de direcciones. Por simplicidad, supondré de manera poco realista que el estroboscopio, RAS y CAS están todos activos.
Al observar el esquema y los esquemas de PC / XT de algunas otras computadoras en este momento, veo tres estrategias básicas, que son aproximadamente las siguientes:
Use la luz estroboscópica para RAS. Use una línea de retraso (una parte cuya salida es una versión de su entrada con retraso de tiempo) en RAS para generar MUX, y use otra línea de retraso para generar una versión aún posterior de RAS, que se usa para CAS. Esta estrategia es utilizada por la PC / XT y el TRS-80 Modelo II.
Un ejemplo (moderno) de la línea de retardo es el Maxim DS1100.
Use la luz estroboscópica para RAS y retrasarla para MUX y CAS, pero haga esto utilizando un registro de desplazamiento de alta velocidad en lugar de una línea de demora. Esta estrategia es utilizada por el TRS-80 Modelo I y el Apple II.
Use circuitos integrados personalizados. Esta es la estrategia del Commodore 64.
fuente
Su pregunta es tan complicada que ni siquiera estoy seguro de cuál es su problema real, ¡pero lo intentaré!
El diseño DRAM basado en 6502 "más limpio" que pude encontrar es del Commodore PET 2001-N . Tiene un 6502 funcionando a 1 MHz, pero la lógica DRAM está sincronizada a 16 MHz, lo que probablemente genere todos los tiempos.
No he analizado los detalles, pero la acción principal parece suceder con un contador 74191 de 4 bits conectado a un registro de desplazamiento 74164. Esto genera 8 líneas separadas que van a un 74157 MUX que está controlado por la línea R / W. La salida del MUX entra en un flip-flop 7474 y una lógica discreta para generar las señales RAS / CAS finales. Aquí hay un extracto que enlaza a la página relevante en el esquema de referencia.
La actualización se maneja con un contador separado, y cada línea de dirección se conecta a un multiplexor que selecciona la dirección "real" o la dirección de actualización.
Partes de esta lógica también parecen generar tiempos para el subsistema de video. Estoy seguro de que puede simplificarse para sus necesidades particulares, pero creo que algo similar puede ser útil: un contador de alta frecuencia, registro de desplazamiento y multiplexores.
fuente
Si bien entiendo completamente el espíritu de su proyecto y su deseo de usar partes no elegantes, definitivamente seguiría el camino de la FPGA si fuera usted .
Muchas rasones:
fuente