Altifigence Academy

62 / 63 · Concept

Interface de registres et instant des effets de bord

Spécifier adresse, écriture par octets et attente de réponse pour qu'une requête produise un seul effet.

Définir « écrire dans un registre »

Prérequis : décodeur d'adresseDécodeur Circuit activant la ligne correspondant à un code binaire. Avec enable, toutes les sorties peuvent être mises à 0 lorsqu'il est désactivé. En savoir plus, ready/validHandshake Contrat validant le transfert lorsque valid de l'émetteur et ready du récepteur valent 1 au même front. Il définit aussi la conservation des données en attente. En savoir plus, enable et priorité de mise à jour.

Relier des registresRegistre Circuit stockant plusieurs bits d'état. Les registres synchrones du cours capturent leur entrée définie sur un front d'horloge. En savoir plus de configuration à un contrôleur externe exige plus qu'une adresse correcte : définissez acceptation, stabilité d'une réponse bloquée et écriture à une adresse en lecture seule. Nous utilisons une interface simple requête/réponse unique sur la même horloge.

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

Les adresses sont en octets et alignées sur 32 bits. Chaque requête produit exactement une réponse, succès ou erreur.

AdresseNomComportement
0x0CONFIGLecture/écriture avec byte strobe
0x4STATUSLecture seule, valeur à l'acceptation
0x8COMMANDLecture=0 ; écrire bit 0 de l'octet 0 déclenche start
AutreNon définieErreur, aucun changement d'état

Accepter si la réponse est vide ou se libère

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

Si la réponse est bloquée, req_ready=0 : écriture config et impulsion command ne se répètent pas. L'effet d'une requête acceptée peut déjà être produit tandis que sa réponse attend. Réémettre systématiquement après une latence de réponse peut donc dupliquer la commande.

Calculer l'effet des byte strobes

Avec CONFIG=32'h11223344, écrire req_wdata=32'hAABBCCDD et req_wstrb=4'b0101 change seulement les octets 0 et 2 : 32'h11BB33DD. Vérifiez séparément alignement, positions et ordre des octets mémoire. Une écriture wstrb=0000 réussit sans changer la valeur.

Du MSBMSB Bit de poids le plus fort. Son indice dépend du sens de déclaration du vecteur ; ce n'est pas nécessairement l'indice numérique le plus grand. En savoir plus vers le bas, les octets sont 3,2,1,0. 0101 sélectionne 2 et 0 : seuls BB et DD sont écrits. Chaque strobe autorise un octet, pas un bit.

Modifier uniquement les octets choisis par le byte strobe
  1. Ancien CONFIG: 11 | 22 | 33 | 44
  2. Données à écrire: AA | BB | CC | DD
  3. Strobe 0101: Garder | Changer | Garder | Changer
  4. Nouveau CONFIG: 11 | BB | 33 | DD

De quel instant provient STATUS ?

La réponse STATUS stocke status_value à l'acceptation. Si le statut réel change pendant l'attente, rsp_rdata reste constant. Brancher directement le statut combinatoire sur une réponse rsp_valid=1,rsp_ready=0 violerait le protocole en changeant son contenu.

Si req_valid=req_ready=1 sur deux fronts consécutifs, ce sont deux requêtes distinctes. Après acceptation, l'émetteur doit baisser valid ou passer à la suivante ; maintenir la même requête ne garantit pas une seule exécution.

Trois axes de vérification

  1. Adresses et permissions : adresses valides, désalignées, écriture STATUS et adresses absentes ; vérifier erreurs et effets.
  2. Sélection de données : tester les seize combinaisons des quatre strobes et préserver les octets inactifs.
  3. Flux : bloquer plusieurs cycles sans changement indu de réponse/état ; vérifier les comptes lors de consommation et acceptation simultanées.

Essayez vous-même

Une écriture COMMAND avec req_wstrb[0]=1 et req_wdata[0]=1 est acceptée, puis rsp_ready=0 pendant trois cycles. start_pulse doit-il se répéter ? Une écriture STATUS peut-elle changer config_value ?

Lire l’explication

start_pulse vaut 1 pendant un seul cycle après acceptation, puis 0. Bloquer la réponse ne relance pas la commande. Écrire STATUS produit une erreur sans changer config_value ni les autres états. Les deux côtés doivent aussi convenir d'une politique de nouvelle tentative avant achèvement de réponse.

Votre choix s’applique à ce navigateur. Modifiez-le à tout moment en bas de page.