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.
Las lecciones se pueden leer gratis. Inscríbete para guardar el progreso.
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.
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ón | Nombre | Comportamiento |
|---|---|---|
| 0x0 | CONFIG | Lectura/escritura con habilitación por byte |
| 0x4 | STATUS | Solo lectura; devuelve el valor al aceptar la solicitud |
| 0x8 | COMMAND | La lectura devuelve 0; escribir el bit 0 del byte 0 activa el pulso start |
| Otras | Sin definir | Respuesta de error, sin modificar el estado |
Aceptar cuando la posición de respuesta está vacía o se vacía en el flanco
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
endmoduleSi 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.
- CONFIG anterior: 11 | 22 | 33 | 44
- Datos de escritura: AA | BB | CC | DD
- strobe 0101: Conservar | Cambiar | Conservar | Cambiar
- 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
- Direcciones y permisos: compruebe errores y efectos sobre el estado con direcciones válidas, direcciones no alineadas, escrituras en STATUS y direcciones sin definir.
- Selección de datos: pruebe exhaustivamente las combinaciones de los cuatro bits de strobe y compruebe que los bytes deshabilitados se conservan.
- 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.