Altifigence Academy

30 / 37 · Concepto

Ready/valid y un búfer elástico de una posición

Diseñe la condición de transferencia y la entrada y salida simultáneas para que una ruta de datos que puede detenerse no pierda ni duplique elementos.

La transferencia ocurre cuando valid y ready valen 1 en el mismo flanco

El emisor activa valid al presentar un dato válido y el receptor activa ready cuando puede aceptarlo. La transferencia se determina muestreando ambas señales en el flanco de reloj.

transferk=validk∧readyk\mathrm{transfer}_k=\mathrm{valid}_k\land\mathrm{ready}_k

Mientras valid=1 y ready=0, el emisor debe mantener tanto valid como los datos. Esperar a que ready se active para empezar a presentar valid puede causar un bloqueo mutuo, según las reglas del receptor. Aquí se supone que todas las señales pertenecen al mismo dominio de reloj. 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. por sí solo no resuelve un cruce de dominios de reloj.

Transferir una sola vez el dato que ha esperado

Las columnas siguientes representan, en orden, los ciclos de muestreo 0 a 5. Lea cada señal como su valor justo antes del flanco de subidaFlanco ascendente Instante en que el reloj pasa de 0 a 1. Se distingue del nivel alto, que abarca todo el intervalo con CLK=1. Más información correspondiente. Durante los ciclos 1 y 2, A espera con valid=1 y ready=0; deben conservarse los datos y valid. A se acepta en el flanco 3 y B en el flanco 4. La alineación del reloj y las señales es un esquema del contrato; no modela los tiempos de setupSetup Tiempo mínimo durante el cual la entrada debe permanecer estable antes del flanco de captura. Si se incumple, el valor almacenado no está garantizado. Más información y hold.

Ready/valid · Espera y transferencias consecutivas
Ver los datos de la forma de onda
Datos de la forma de onda: cada carácter es un intervalo; un punto conserva el estado anterior; p representa un ciclo de reloj.
SeñalForma de ondaValores del bus
clkp.....
valid01...0
ready10.1..
transfer0..1.0
datax3..4xA → B

Mantener valid en 1 durante varios ciclos no limita la operación a una sola transferencia. Cada flanco en el que ready también vale 1 produce una transferencia distinta.

Construir un búfer para un elemento

Hay espacio para recibir un nuevo dato si el búfer está vacío o si puede entregar su dato actual en este flanco.

in_ready=¬out_valid∨out_ready\mathrm{in\_ready}=\neg\mathrm{out\_valid}\lor\mathrm{out\_ready}
SystemVerilog
module elastic_buffer (
    input  logic       clk,
    input  logic       rst,
    input  logic       in_valid,
    output logic       in_ready,
    input  logic [7:0] in_data,
    output logic       out_valid,
    input  logic       out_ready,
    output logic [7:0] out_data
);
    assign in_ready = !out_valid || out_ready;

    always_ff @(posedge clk) begin
        if (rst) begin
            out_valid <= 1'b0;
        end else if (in_ready) begin
            out_valid <= in_valid;
            if (in_valid) out_data <= in_data;
        end
    end
endmodule

Si el búfer vacío acepta una entrada, out_valid y out_data se actualizan después del flanco. No existe un bypass combinacional, por lo que el nuevo valor no se cuenta como una transferencia de salida en ese mismo flanco. Durante reset no se cuentan transferencias, y out_data carece de significado cuando out_valid=0. Por eso no es imprescindible reiniciarReset Control que devuelve el estado a un valor inicial especificado. Deben definirse su carácter síncrono o asíncrono y su prioridad frente a otros controles. Más información el propio registroRegistro 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 datos.

Reemplazar el elemento incluso con el búfer lleno

Estado justo antes del flancoout_readyin_validAcción en el flanco
Vacío0 o 11Almacena la entrada y pone valid en 1
Lleno00 o 1Conserva el dato actual y valid
Lleno10Entrega la salida y queda vacío
Lleno11Entrega la salida anterior y almacena la nueva entrada simultáneamente

La última fila permite procesar un elemento por ciclo después del llenado inicial. Tener latencia no obliga a reducir a la mitad la tasa de procesamientoTasa de procesamiento Número de operaciones aceptadas o completadas por unidad de tiempo. Un pipeline puede aumentarla sin reducir la latencia de una operación individual. Más información.

Modelo para verificar el orden de los datos

Use como referencia una cola de longitud máxima 1. Decida la transferencia de salida y la aceptación de entrada con los valores anteriores a cada flanco. Si hay salida, compárela con la cabecera y retírela antes de añadir la entrada al final. Dequeue y enqueue pueden ocurrir en el mismo flanco, así que su orden debe quedar explícito.

0≤Naccepted−Ndelivered≤10\le N_{\mathrm{accepted}}-N_{\mathrm{delivered}}\le1

Esta invariante vale dentro de un intervalo cuyo registro de operaciones comienza de nuevo con el reset. Compruebe además que los datos permanecen estables durante una parada, que se conserva su orden y que ningún elemento se entrega dos veces. La invariante de recuento no demuestra por sí sola que los valores sean correctos.

Encadenar combinacionalmente ready a través de muchos búferes puede alargar la ruta temporal de retorno. Al conectarlos, compruebe también que no aparezcan bucles combinacionales.

Lectura adicional: AMD UG934 — READY/VALID Handshake

Inténtalo tú

El búfer contiene A y la entrada presenta un nuevo dato B con in_valid=1. En el primer flanco out_ready=0 y en el siguiente out_ready=1. ¿Qué ocurre con A y B en cada flanco y hasta cuándo debe conservar B el emisor?

Leer la explicación

En el primer flanco, in_ready=0: A se conserva y B no se acepta. El emisor mantiene B e in_valid=1. En el siguiente flanco, in_ready=1: se entrega A y se almacena B simultáneamente. Después de ese flanco, la salida del búfer contiene B, pero B todavía no se ha transferido. Su transferencia de salida ocurrirá en un flanco posterior en el que out_valid y out_ready valgan ambos 1.

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