Altifigence Academy

62 / 63 · Konzept

Registerschnittstelle und Zeitpunkt von Nebenwirkungen

Adressen, Byte-Schreiben und Antwortstopps spezifizieren, sodass eine Annahme genau eine Änderung auslöst.

Was „in ein Register schreiben“ bedeutet

Voraussetzungen: AdressdecoderDecoder Aktiviert die einem Binärcode zugeordnete Ausgangsleitung. Mit enable können im deaktivierten Zustand alle Ausgänge 0 sein. Mehr erfahren, ready/validHandshake Transfervertrag: valid des Senders und ready des Empfängers sind an derselben Flanke 1. Dazu gehören Regeln zum Halten wartender Daten. Mehr erfahren und Aktualisierungsprioritäten.

Für extern gesteuerte KonfigurationsregisterRegister Speichert einen Zustand aus mehreren Bits. Die synchronen Register dieses Kurses übernehmen festgelegte Eingaben an Taktflanken. Mehr erfahren genügt eine richtige Adresse nicht. Annahmezeit, Halten bei blockierter Antwort und Schreiben auf Nur-Lese-Adressen müssen feststehen. Wir nutzen eine einfache Anforderungs-/Antwortschnittstelle im selben Takt.

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

Adressen sind Byteadressen mit 32-Bit-Ausrichtung. Jede Anforderung erzeugt genau eine Erfolgs- oder Fehlerantwort.

AdresseNameVerhalten
0x0CONFIGLesen/Schreiben mit Byte-Strobe
0x4STATUSNur lesen; Wert bei Annahme
0x8COMMANDLesen ergibt 0; Schreiben von Bit 0 in Byte 0 erzeugt start
AndereUndefiniertFehlerantwort, keine Zustandsänderung

Annehmen, wenn der Antwortplatz leer ist oder frei wird

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

Bei blockierter Antwort ist req_ready=0; CONFIG-Schreiben und COMMAND-Puls werden nicht wiederholt. Die Nebenwirkung kann bereits erfolgt sein, während nur die Antwort wartet. Unbedingtes Wiederholen wegen Verzögerung kann Befehle doppelt ausführen.

Byte-Strobes auswerten

Bei CONFIG=32'h11223344, req_wdata=32'hAABBCCDD, req_wstrb=4'b0101 ändern sich nur Bytes 0 und 2: 32'h11BB33DD. Prüfen Sie Ausrichtung, Bitpositionen und Speicher-Byteordnung getrennt. Schreiben mit wstrb=0000 antwortet erfolgreich ohne Wertänderung.

Vom MSBMSB Bit mit dem höchsten Stellenwert. Sein Index hängt von der Deklarationsrichtung ab und ist nicht grundsätzlich der größte Index. Mehr erfahren aus folgen byte3,2,1,0. Strobe 0101 wählt byte2 und byte0, also nur BB und DD. Ein Strobe-Bit ist eine Byte-Schreibfreigabe, keine Einzelbitfreigabe.

Nur die durch Byte-Strobes ausgewählten Bytes ändern
  1. Bisheriges CONFIG: 11 | 22 | 33 | 44
  2. Schreibdaten: AA | BB | CC | DD
  3. strobe 0101: Halten | Ersetzen | Halten | Ersetzen
  4. Neues CONFIG: 11 | BB | 33 | DD

Welcher Zeitpunkt des Status zählt?

STATUS speichert status_value bei Anforderungsannahme. Ändert sich der reale Status während einer blockierten Antwort, muss rsp_rdata trotzdem halten. Den kombinatorischen Status bei rsp_valid=1, rsp_ready=0 direkt anzuschließen verletzt das Protokoll.

Sind req_valid und req_ready an zwei aufeinanderfolgenden Flanken 1, sind dies zwei verschiedene Anforderungen. Nach Annahme muss der Sender valid absenken oder zur nächsten Anforderung wechseln. Dieselbe dauerhaft angelegte Anforderung wird nicht automatisch nur einmal ausgeführt.

Drei Prüfdimensionen

  1. Adresse/Rechte: gültige und nicht ausgerichtete Adressen, STATUS-Schreiben und undefinierte Adressen auf Fehler und Nebenwirkungen prüfen.
  2. Datenauswahl: alle Kombinationen der vier Strobe-Bits und Erhalt inaktiver Bytes prüfen.
  3. Flusssteuerung: Antwort über mehrere Zyklen blockieren und Stabilität prüfen; auch bei gleichzeitiger Antwortannahme und neuer Anforderung müssen Transaktionszahlen stimmen.

Selbst ausprobieren

COMMAND mit req_wstrb[0]=1, req_wdata[0]=1 wurde angenommen; rsp_ready bleibt drei Zyklen 0. Muss start_pulse wiederholt werden? Darf ein STATUS-Schreiben config_value ändern?

Erklärung lesen

start_pulse ist nur einen Zyklus nach Annahme 1, danach 0. Eine blockierte Antwort wiederholt keinen Befehl. STATUS-Schreiben erzeugt einen Fehler und verändert weder config_value noch anderen Zustand. Wiederholungsregeln vor abgeschlossener Antwort müssen beide Seiten vereinbaren.

Deine Auswahl gilt für diesen Browser. Du kannst sie jederzeit in der Fußzeile ändern.