62 / 63 · Conceito
Interface de registradores e instante dos efeitos de uma operação
Especifique endereços, escritas por byte e paradas de resposta para que cada solicitação produza exatamente uma alteração de estado.
As aulas podem ser lidas gratuitamente. Inscreva-se para salvar o progresso.
Definir o que significa escrever em um registrador
Conhecimentos prévios: decodificadores de endereçosDecodificador Circuito que ativa a linha de saída correspondente a um código binário. Com enable, pode colocar todas as saídas em 0 quando está desabilitado. Saiba mais, 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. Saiba mais, enable e prioridade de atualização do estado.
Ao conectar registradoresRegistrador 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 configuração a um controlador externo, não basta conferir o endereço. É necessário definir quando uma solicitação é aceita, o que permanece estável enquanto a resposta espera e o que acontece ao escrever em um endereço somente de leitura. Aqui usamos uma interface simples de uma solicitação e uma resposta, com um único clock.
Os endereços seguintes são endereços de byte, com alinhamento de 32 bits. Cada solicitação gera exatamente uma resposta, de sucesso ou de erro.
| Endereço | Nome | Comportamento |
|---|---|---|
| 0x0 | CONFIG | Leitura/escrita com habilitação por byte |
| 0x4 | STATUS | Somente leitura; retorna o valor na aceitação da solicitação |
| 0x8 | COMMAND | A leitura retorna 0; escrever o bit 0 do byte 0 ativa o pulso start |
| Outros | Não definido | Resposta de erro, sem alteração de estado |
Aceitar quando a posição de resposta está vazia ou fica vazia na borda
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
endmoduleSe a resposta estiver bloqueada, req_ready=0: a escrita de configuração e o pulso de comando não são executados novamente. Os efeitos de uma solicitação aceita podem já ter ocorrido enquanto sua resposta ainda espera. Reenviar incondicionalmente uma solicitação ao observar uma resposta atrasada pode executar o comando duas vezes.
Calcular o efeito da habilitação por byte
Com CONFIG em 32'h11223344, uma escrita de req_wdata=32'hAABBCCDD e req_wstrb=4'b0101 altera somente os bytes 0 e 2. O resultado é 32'h11BB33DD. Verifique separadamente o alinhamento dos endereços, a posição dos bits e a ordem de bytes na memória. Uma escrita com wstrb=0000 gera uma resposta de sucesso e mantém o valor.
A partir do MSBMSB Bit de maior peso. Seu índice depende do sentido de declaração do vetor; não se deve supor que sempre tenha o maior número. Saiba mais, os bytes aparecem na ordem 3, 2, 1, 0. O strobe 0101 seleciona byte2 e byte0, portanto apenas BB e DD são escritos. Cada bit de strobe habilita a escrita de um byte inteiro, não de um único bit de dados.
- CONFIG anterior: 11 | 22 | 33 | 44
- Dados de escrita: AA | BB | CC | DD
- strobe 0101: Manter | Trocar | Manter | Trocar
- CONFIG novo: 11 | BB | 33 | DD
A que instante corresponde o estado lido?
A resposta de uma leitura de STATUS armazena status_value ao aceitar a solicitação. Se o estado real mudar enquanto a resposta estiver parada, rsp_rdata permanece estável. Com rsp_valid=1 e rsp_ready=0, conectar diretamente um estado combinacional à resposta permitiria que seu conteúdo mudasse, violando o protocolo.
Se req_valid e req_ready forem ambos 1 em duas bordas consecutivas, existem duas solicitações distintas. Após a aceitação, o transmissor deve baixar valid ou apresentar a próxima solicitação. Não pode manter indefinidamente a mesma solicitação esperando que ela seja processada uma única vez.
Três eixos de verificação
- Endereços e permissões: confira erros e efeitos sobre o estado com endereços válidos, endereços desalinhados, escritas em STATUS e endereços não definidos.
- Seleção de dados: teste exaustivamente as combinações dos quatro bits de strobe e confira se os bytes desabilitados são preservados.
- Controle de fluxo: bloqueie respostas por vários ciclos e confira se a resposta e o estado são mantidos; faça o consumo de uma resposta coincidir com a aceitação da solicitação seguinte e verifique a quantidade de transações.
Experimente
Após aceitar uma escrita em COMMAND com req_wstrb[0]=1 e req_wdata[0]=1, rsp_ready permanece em 0 por três ciclos. start_pulse deve se repetir durante esses três ciclos? Uma escrita em STATUS pode alterar config_value?
Ler a explicação
start_pulse vale 1 por apenas um ciclo imediatamente após a aceitação da solicitação e depois volta a 0. A parada da resposta não executa novamente o comando. Uma escrita em STATUS gera uma resposta de erro e não modifica outros estados, incluindo config_value. Transmissor e receptor também devem concordar sobre a política de repetição antes de concluir uma resposta.