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.
Les leçons sont gratuites. Inscrivez-vous pour enregistrer vos progrès.
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.
Les adresses sont en octets et alignées sur 32 bits. Chaque requête produit exactement une réponse, succès ou erreur.
| Adresse | Nom | Comportement |
|---|---|---|
| 0x0 | CONFIG | Lecture/écriture avec byte strobe |
| 0x4 | STATUS | Lecture seule, valeur à l'acceptation |
| 0x8 | COMMAND | Lecture=0 ; écrire bit 0 de l'octet 0 déclenche start |
| Autre | Non définie | Erreur, aucun changement d'état |
Accepter si la réponse est vide ou se libère
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
endmoduleSi 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.
- Ancien CONFIG: 11 | 22 | 33 | 44
- Données à écrire: AA | BB | CC | DD
- Strobe 0101: Garder | Changer | Garder | Changer
- 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
- Adresses et permissions : adresses valides, désalignées, écriture STATUS et adresses absentes ; vérifier erreurs et effets.
- Sélection de données : tester les seize combinaisons des quatre strobes et préserver les octets inactifs.
- 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.