Altifigence Academy

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.

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.

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

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çoNomeComportamento
0x0CONFIGLeitura/escrita com habilitação por byte
0x4STATUSSomente leitura; retorna o valor na aceitação da solicitação
0x8COMMANDA leitura retorna 0; escrever o bit 0 do byte 0 ativa o pulso start
OutrosNão definidoResposta de erro, sem alteração de estado

Aceitar quando a posição de resposta está vazia ou fica vazia na borda

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

Se 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.

Alterar somente os bytes selecionados por byte strobe
  1. CONFIG anterior: 11 | 22 | 33 | 44
  2. Dados de escrita: AA | BB | CC | DD
  3. strobe 0101: Manter | Trocar | Manter | Trocar
  4. 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

  1. 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.
  2. Seleção de dados: teste exaustivamente as combinações dos quatro bits de strobe e confira se os bytes desabilitados são preservados.
  3. 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.

Sua escolha vale neste navegador. Altere-a a qualquer momento no rodapé.