30 / 37 · Conceito
Ready/valid e um buffer elástico de uma posição
Projete a condição de transferência e a entrada e saída simultâneas para que um caminho de dados que pode parar não perca nem duplique elementos.
As aulas podem ser lidas gratuitamente. Inscreva-se para salvar o progresso.
A transferência ocorre quando valid e ready valem 1 na mesma borda
O transmissor ativa valid ao apresentar um dado válido, e o receptor ativa ready quando pode aceitá-lo. A transferência é determinada pela amostragem conjunta dos dois sinais na borda de clock.
Enquanto valid=1 e ready=0, o transmissor deve manter tanto valid quanto os dados. Esperar ready subir para só então apresentar valid pode causar um impasse, dependendo das regras do receptor. Aqui se supõe que todos os sinais pertencem ao mesmo domínio de clock. Ready/validHandshake Contrato que confirma uma transferência quando valid do transmissor e ready do receptor valem 1 na mesma borda. Inclui as regras para manter os dados durante a espera., por si só, não resolve um cruzamento de domínios de clock.
Transferir uma única vez o dado que ficou esperando
As colunas seguintes representam, em ordem, os ciclos de amostragem 0 a 5. Leia cada sinal como seu valor imediatamente antes da borda de subidaBorda de subida Instante em que o clock passa de 0 para 1. É diferente do nível alto, que abrange todo o intervalo com CLK=1. Saiba mais correspondente. Nos ciclos 1 e 2, A espera com valid=1 e ready=0; os dados e valid devem ser mantidos. A é aceito na borda 3, e B na borda 4. O alinhamento de clock e sinais é um esquema do contrato; não modela os tempos de setupSetup Tempo mínimo durante o qual a entrada deve permanecer estável antes da borda de captura. Se for violado, o valor armazenado não é garantido. Saiba mais e hold.
Ver os dados da forma de onda
| Sinal | Forma de onda | Valores do barramento |
|---|---|---|
| clk | p..... | |
| valid | 01...0 | |
| ready | 10.1.. | |
| transfer | 0..1.0 | |
| data | x3..4x | A → B |
Manter valid em 1 por vários ciclos não limita a operação a uma única transferência. Cada borda em que ready também vale 1 produz uma transferência distinta.
Construir um buffer para um elemento
Há espaço para receber um novo dado se o buffer estiver vazio ou se puder entregar seu dado atual nesta borda.
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
endmoduleSe o buffer vazio aceitar uma entrada, out_valid e out_data serão atualizados após a borda. Não existe bypass combinacional, portanto o novo valor não é contado como transferência de saída nessa mesma borda. Durante reset, não se contam transferências, e out_data não tem significado quando out_valid=0. Por isso não é obrigatório reiniciarReset Controle que retorna o estado a um valor inicial especificado. É preciso definir se é síncrono ou assíncrono e sua prioridade em relação a outros controles. Saiba mais o próprio registradorRegistrador Circuito que armazena vários bits de estado. Os registradores síncronos deste curso capturam a entrada especificada na borda de clock. Saiba mais de dados.
Substituir o elemento mesmo com o buffer cheio
| Estado imediatamente antes da borda | out_ready | in_valid | Ação na borda |
|---|---|---|---|
| Vazio | 0 ou 1 | 1 | Armazena a entrada e coloca valid em 1 |
| Cheio | 0 | 0 ou 1 | Mantém o dado atual e valid |
| Cheio | 1 | 0 | Entrega a saída e fica vazio |
| Cheio | 1 | 1 | Entrega a saída anterior e armazena a nova entrada simultaneamente |
A última linha permite processar um elemento por ciclo após o preenchimento inicial. Ter latência não obriga a reduzir pela metade a taxa de processamentoTaxa de processamento Quantidade de operações aceitas ou concluídas por unidade de tempo. Um pipeline pode aumentá-la sem reduzir a latência de uma operação individual. Saiba mais.
Modelo para verificar a ordem dos dados
Use como referência uma fila de comprimento máximo 1. Decida a transferência de saída e a aceitação de entrada usando os valores anteriores a cada borda. Se houver saída, compare-a com a cabeça e retire-a antes de inserir a entrada no final. Dequeue e enqueue podem ocorrer na mesma borda, portanto a ordem precisa ficar explícita.
Essa invariante vale dentro de um intervalo cujo registro de operações recomeça com o reset. Confira também se os dados permanecem estáveis durante uma parada, se a ordem é mantida e se nenhum elemento é entregue duas vezes. A invariante de contagem, sozinha, não demonstra que os valores estão corretos.
Encadear ready combinacionalmente por muitos buffers pode alongar o caminho temporal de retorno. Ao conectá-los, verifique também se não surgem laços combinacionais.
Leitura adicional: AMD UG934 — READY/VALID Handshake
Experimente
O buffer contém A e a entrada apresenta um novo dado B com in_valid=1. Na primeira borda out_ready=0 e na seguinte out_ready=1. O que acontece com A e B em cada borda e até quando o transmissor deve manter B?
Ler a explicação
Na primeira borda, in_ready=0: A é mantido e B não é aceito. O transmissor mantém B e in_valid=1. Na borda seguinte, in_ready=1: A é entregue e B é armazenado simultaneamente. Após essa borda, a saída do buffer contém B, mas B ainda não foi transferido. Sua transferência de saída ocorrerá em uma borda posterior na qual out_valid e out_ready forem ambos 1.