¿Cuál es el mecanismo subyacente detrás de los registros RO o WO y WR?

En los sistemas integrados, tiene registros de solo lectura y solo escritura. ¿Cómo se distinguen los dos tipos en la netlist producida?

¿Cómo se construye un flop en el que solo puedes escribir y no leer?

Respuestas (3)

Se trata de cómo se conectan los registros al bus:

if wb_cyc = '1' and wb_stb = '1' then         -- accessing the register

    if wb_we = '1' then                       -- writing to the register?
        my_reg <= wb_dat_i;                   -- update register contents

    else                                      -- reading from the register
        wb_dat_o <= my_reg;                   -- return register contents
    end if;
end if;

Si omite la parte del hardware que puede leer el registro, entonces su registro es de solo escritura. De manera similar, si omite la parte del hardware que puede escribir en el registro, entonces es de solo lectura.

A veces tiene sentido tener solo una "dirección" de flujo de datos. Piense en una ruta de datos DAC o ADC.

Además, a veces tiene sentido que la misma dirección devuelva algo diferente a los datos que ha escrito en ella. Piense en los microcontroladores más comunes; sus periféricos tienden a tener una sola dirección que es un "comando" para escritura y un "estado" para lectura.

Otro ejemplo serían las banderas de interrupción: lee el registro de interrupción para ver qué periférico interrumpió el programa, luego escribe un '1' en el mismo bit para borrar la bandera de interrupción. Una forma de darse cuenta de eso es la siguiente:

wb_dat_o <= (others => '0');
if wb_cyc = '1' and wb_stb = '1' then             -- register access
    if wb_we = '1' then                           -- writing to the register?
        clear_int <= wb_dat_i(0);
    else                                          -- reading from the register?
        clear_int <= '0';
        wb_dat_o <= running & int_enabled & int_active;
    end if;
end if;

Aquí puede ver que estoy configurando un indicador para lo que sea que esté en la posición de bit 0 en el caso de escritura (y no me importa cualquier otra cosa que hayan escrito), mientras que en el caso de lectura estoy construyendo un estado palabra compuesta de bits individuales que el periférico está manejando.

aparte: también mantengo explícitamente clear_inten cero en el caso de lectura. Es solo una buena práctica de codificación asegurarse de que todas las señales estén asignadas en todas las rutas de código en HDL. En el mejor de los casos, no hacerlo genera un código descuidado. En el peor de los casos, puede inferir pestillos. Tenga en cuenta que hago algo similar wb_dat_oincluso antes de ingresar al caso de acceso al registro.

Tenga en cuenta que estos son solo ejemplos para ilustrar el punto, y que un programa bien escrito se describirá con más cuidado y detalle. También tenga en cuenta que son las 8 am aquí y aún no he tomado mi café. :-)

Supongo que está hablando de registrarse en alguna parte periférica, ya sea parte del chip del procesador o conectado a él de alguna manera.

En un registro de solo lectura, los datos se originan en algún proceso externo (desde el punto de vista del procesador) y hardware asociado, como la recepción de datos en serie por un UART. Por lo tanto, ese hardware se conecta a la entrada del FF y sus salidas se conectan (por ejemplo) al bus del procesador.

Para un registro de solo escritura, la situación es la inversa, el procesador se conecta (directa o indirectamente) a las entradas de FF y las salidas de FF se conectan a algún circuito externo. Un ejemplo es un convertidor de digital a analógico.

Gracias, ¿qué pasa con los registros WR?
Un registro WO simple (donde el hardware que no es CPU no cambiará el contenido) puede, por supuesto, extenderse para que sea legible, como un servicio para el software (para que no tenga que recordar lo que se colocó allí cuando quiera aplicar un cambio incrementado). Otro tipo de registro RW es uno que puede ser cambiado tanto por el software como por el hardware, piense en un contador/temporizador en marcha.

Una cosa que le sugiero que intente hacer, aunque lamentablemente muchos diseños no lo hacen de manera consistente, es dividir los registros de escritura en categorías de "bloqueo" y "acción", con la expectativa de que una lectura de un registro de bloqueo siempre devolverá el valor escrito, mientras que una lectura de la dirección de un registro de acción debe considerarse como la lectura de un registro independiente de solo lectura.

Por ejemplo, suponga que su sistema tiene ocho pestillos que detectan eventos externos. Si esos latches se encuentran en un registro de 8 bits que la CPU puede leer o escribir directamente, o que se puede configurar de forma asíncrona externamente, entonces si el código de usuario observa que los bits 0 y 2 están configurados (lo que significa que el registro lee 0x05) y quiere para borrar el bit 0 mientras se deja el bit 2 establecido, tratar de escribir 0x04 en el registro del mismo modo que algún evento haría que otro bit se estableciera tendría el desafortunado efecto de borrar el pestillo asociado con ese otro evento, lo que provocaría que se pierda . Si uno tuviera una dirección de "lectura" que informa el estado de los pestillos, una dirección de "escribir ceros" que permite borrar los bits seleccionados, y posiblemente una dirección de "escribir unos" que permite configurar los bits seleccionados, entonces estos problemas no ocurriría.

Para las cosas que se supone que controla la CPU (en lugar de simplemente tomar nota, como fue el caso de las banderas de interrupción), pero donde la capacidad de la CPU para controlarlas puede estar limitada por factores externos, uno debe separar lo que el La CPU está solicitando lo que puede hacer. Por ejemplo, si se supone que una salida de control de motor se apaga de forma asíncrona mediante una entrada externa de "apagado de motor", esa entrada no debería simplemente borrar el bloqueo de salida de "control de motor" que configuró la CPU. En su lugar, la CPU debe tener un pestillo que diga si quiere que el motor esté encendido, y ese pestillo no debe cambiarse por factores externos. Un segundo pestillo activado externamente debería indicar si ha llegado una señal de apagado del motor; la salida del motor debe activarse solo cuando la solicitud de la CPU dice "ir"

Diseñar hardware para separar lo que la computadora está pidiendo en comparación con lo que el hardware externo puede hacer actualmente no debería ser difícil, y mantener esas cosas separadas como una cuestión de principio ayudará a evitar errores que pueden ocurrir cuando la CPU, en el proceso de tratar de escribir una cosa, accidentalmente escribe otra cosa.