Altifigence Academy

62 / 63 · Concepto

Interfaz de registros e instante de los efectos de una operación

Especifique direcciones, escrituras por byte y paradas de respuesta para que cada solicitud produzca exactamente una modificación de estado.

Definir qué significa escribir un registro

Conocimientos previos: decodificadores de direccionesDecodificador Circuito que activa la línea de salida correspondiente a un código binario. Con enable, puede llevar todas las salidas a 0 cuando está deshabilitado. Más información, ready/validHandshake Contrato que confirma una transferencia cuando valid del emisor y ready del receptor valen 1 en el mismo flanco. Incluye las reglas para conservar los datos durante la espera. Más información, enable y prioridad de actualización del estado.

Al conectar registrosRegistro Circuito que almacena varios bits de estado. Los registros síncronos de este curso capturan la entrada especificada en el flanco de reloj. Más información de configuración a un controlador externo, no basta con comprobar la dirección. Hay que definir cuándo se acepta una solicitud, qué permanece estable mientras la respuesta espera y qué ocurre al escribir en una dirección de solo lectura. Aquí usamos una interfaz sencilla de una solicitud y una respuesta, con un único reloj.

accept=req_valid∧req_ready\mathrm{accept}=\mathrm{req\_valid}\land\mathrm{req\_ready}

Las direcciones siguientes son direcciones de byte, con alineación a 32 bits. Cada solicitud genera exactamente una respuesta, de éxito o de error.

DirecciónNombreComportamiento
0x0CONFIGLectura/escritura con habilitación por byte
0x4STATUSSolo lectura; devuelve el valor al aceptar la solicitud
0x8COMMANDLa lectura devuelve 0; escribir el bit 0 del byte 0 activa el pulso start
OtrasSin definirRespuesta de error, sin modificar el estado

Aceptar cuando la posición de respuesta está vacía o se vacía en el flanco

SystemVerilog
module register_interface (
    input  logic        clk, rst,
    input  logic        req_valid, req_write,
    output logic        req_ready,
    input  logic [3:0]  req_addr,
    input  logic [31:0] req_wdata,
    input  logic [3:0]  req_wstrb,
    output logic        rsp_valid,
    input  logic        rsp_ready,
    output logic [31:0] rsp_rdata,
    output logic        rsp_error,
    input  logic [31:0] status_value,
    output logic [31:0] config_value,
    output logic        start_pulse
);
    assign req_ready = !rsp_valid || rsp_ready;
    always_ff @(posedge clk) begin
        if (rst) begin
            rsp_valid    <= 1'b0;
            config_value <= 32'd0;
            start_pulse  <= 1'b0;
        end else begin
            start_pulse <= 1'b0;
            if (req_ready) begin
                rsp_valid <= req_valid;
                if (req_valid) begin
                    rsp_rdata <= 32'd0;
                    rsp_error <= 1'b0;
                    case (req_addr)
                        4'h0: begin
                            if (req_write) begin
                                for (int i=0; i<4; i++)
                                    if (req_wstrb[i])
                                        config_value[8*i +: 8]
                                            <= req_wdata[8*i +: 8];
                            end else rsp_rdata <= config_value;
                        end
                        4'h4: begin
                            if (req_write) rsp_error <= 1'b1;
                            else rsp_rdata <= status_value;
                        end
                        4'h8: begin
                            if (req_write)
                                start_pulse <= req_wstrb[0] && req_wdata[0];
                        end
                        default: rsp_error <= 1'b1;
                    endcase
                end
            end
        end
    end
endmodule

Si la respuesta está bloqueada, req_ready=0: no vuelven a ejecutarse la escritura de configuración ni el pulso de comando. Los efectos de una solicitud aceptada pueden haberse producido aunque su respuesta siga esperando. Reenviar incondicionalmente una solicitud al observar una respuesta tardía puede ejecutar el comando dos veces.

Calcular el efecto de la habilitación por byte

Con CONFIG en 32'h11223344, una escritura de req_wdata=32'hAABBCCDD y req_wstrb=4'b0101 modifica solo los bytes 0 y 2. El resultado es 32'h11BB33DD. Compruebe por separado la alineación de direcciones, la posición de los bits y el orden de bytes en memoria. Una escritura con wstrb=0000 genera una respuesta de éxito y conserva el valor.

Desde el MSBMSB Bit de mayor peso. Su índice depende del sentido de declaración del vector; no debe suponerse que siempre tiene el número más alto. Más información, los bytes aparecen en orden 3, 2, 1, 0. El strobe 0101 selecciona byte2 y byte0, por lo que solo se escriben BB y DD. Cada bit de strobe habilita la escritura de un byte completo, no de un único bit de datos.

Modificar solo los bytes seleccionados por byte strobe
  1. CONFIG anterior: 11 | 22 | 33 | 44
  2. Datos de escritura: AA | BB | CC | DD
  3. strobe 0101: Conservar | Cambiar | Conservar | Cambiar
  4. CONFIG nuevo: 11 | BB | 33 | DD

¿A qué instante corresponde el estado leído?

La respuesta de una lectura de STATUS guarda status_value al aceptar la solicitud. Si el estado real cambia mientras la respuesta está detenida, rsp_rdata permanece estable. Con rsp_valid=1 y rsp_ready=0, conectar directamente un estado combinacional a la respuesta permitiría que cambiara su contenido y violaría el protocolo.

Si req_valid y req_ready valen ambos 1 en dos flancos consecutivos, hay dos solicitudes distintas. Tras la aceptación, el emisor debe bajar valid o presentar la siguiente solicitud. No puede mantener indefinidamente la misma solicitud esperando que se procese una sola vez.

Tres ejes de verificación

  1. Direcciones y permisos: compruebe errores y efectos sobre el estado con direcciones válidas, direcciones no alineadas, escrituras en STATUS y direcciones sin definir.
  2. Selección de datos: pruebe exhaustivamente las combinaciones de los cuatro bits de strobe y compruebe que los bytes deshabilitados se conservan.
  3. Control del flujo: bloquee respuestas durante varios ciclos y compruebe que la respuesta y el estado se mantienen; haga coincidir el consumo de una respuesta con la aceptación de la siguiente solicitud y verifique el número de transacciones.

Inténtalo tú

Tras aceptar una escritura en COMMAND con req_wstrb[0]=1 y req_wdata[0]=1, rsp_ready permanece en 0 durante tres ciclos. ¿Debe repetirse start_pulse durante esos tres ciclos? ¿Puede una escritura en STATUS modificar config_value?

Leer la explicación

start_pulse vale 1 durante un solo ciclo inmediatamente después de aceptar la solicitud y después vuelve a 0. La parada de la respuesta no vuelve a ejecutar el comando. Una escritura en STATUS genera una respuesta de error y no modifica otros estados, incluido config_value. Emisor y receptor también deben acordar la política de reintentos antes de completar una respuesta.

Tu elección se aplica a este navegador. Puedes cambiarla en el pie de página.