Condivisione della tecnologia

Principi di base del NEMU DiffTest

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina


Questo articolo appartiene a"Tutorial della serie di test differenziali del set di istruzioni RISC-V (DiffTest)"1, benvenuto per controllare altri articoli.

1 Breve descrizione del principio DiffTest

L'idea centrale di DiffTest: per due implementazioni basate sulla stessa specifica, dato lo stesso input definito, il loro comportamento dovrebbe essere coerente.
Tornando alla progettazione del processore, per le due implementazioni secondo il manuale riscv, dato lo stesso programma corretto, i loro cambiamenti di stato (registri, memoria) dovrebbero essere coerenti per le due implementazioni:

  • Uno di questi è la nostra CPU;
  • In alternativa, scegli un simulatore come implementazione di riferimento.
    Inserisci qui la descrizione dell'immagine
    Ogni volta che entrambe le parti terminano l'esecuzione di un'istruzione, controllano lo stato dei rispettivi registri e della memoria. Se scoprono che lo stato è incoerente, segnalano immediatamente un errore e interrompono l'esecuzione del programma client (equivalente a dare un giudizio di asserzione). ogni istruzione).
  • DiffTest = metodo di verifica comportamentale a livello di comando online
    • Online = Verifica durante l'esecuzione del programma
    • Livello di istruzione = ogni istruzione eseguita viene verificata
  • Può convertire qualsiasi programma in test a livello di istruzione e affermarne lo stato
    • Supporta programmi che non finiranno, come il sistema operativo
  • Non è necessario conoscere in anticipo l'esito della procedura
    • Perché stiamo confrontando il comportamento dell'esecuzione delle istruzioni, non la semantica del programma

I maggiori usi di DiffTest sono:Quando si verificano bug di decodifica o di esecuzione dopo aver eseguito centinaia o migliaia di istruzioni, come possiamo trovare rapidamente la prima istruzione di errore? Questa è una difficoltà di livello infernale?

In questo articolo, scegliamo quanto segue come esempio per illustrare:

  • QEMU come oggetto di riferimento (REF)
  • NEMU come soggetto di prova (DUT)

Naturalmente, se è necessario testare l'hardware del processore, è possibile utilizzare il processore anche come DUT.

2 DiffTest supportato da NEMU

make menuconfig
  • 1

Accedere a Test e debug -> Abilita test differenziali -> Progetto di riferimento, come segue:

Inserisci qui la descrizione dell'immagine
Quando NEMU viene utilizzato per il DUT, è possibile scegliere 5 modalità simulatore come simulatore di riferimento REF.

  • QEMU, modalità libreria dinamica, il codice si trova in NEMU/tools/qemu-dl-diff/
  • QEMU, modalità Socket, il codice si trova in NEMU/tools/qemu-socket-diff/
  • KVM, il codice si trova in NEMU/tools/kvm-diff/
  • NON TI PIACE
  • ARPIONE

Per questi ultimi tre l'autore non ha svolto alcuna ricerca specifica, quindi questo articolo non li presenterà.

3 QEMU crea REF (modalità libreria dinamica)

Puoi cambiare NEMU/tools/qemu-dl-diff/, compilato nella libreria dinamica riscv64-qemu-so.
La relazione tra NEMU, librerie dinamiche e QEMU:
Inserisci qui la descrizione dell'immagine

  • Libreria dinamica: riscv64-qemu-so, che esporta la serie difftest_xx di interfacce di funzioni.
  • QEMU: nel file eseguibile qemu-system-riscv64, sono presenti le interfacce delle funzioni delle serie cpu_xx, gdb_xx e qemu_xx.
  • NEMU: il programma riscv64-nemu-interpreter chiama la libreria dinamica, che poi chiama QEMU.

processo specifico:

  • Il programma eseguibile NEMU riscv64-nemu-interpreter carica riscv64-qemu-so chiamando la funzione dlopen e analizza i simboli di funzione della serie difftest_xx per le chiamate successive.
  • Quindi, NEMU chiama la funzione difftest_init per inizializzare.
  • Nella funzione difftest_init, la funzione dlopen verrà richiamata nuovamente per caricare il file eseguibile qemu-system-riscv64 e analizzare le serie di simboli di funzione cpu_xx, gdb_xx e qemu_xx. Questi simboli di funzione sono in realtà il codice di implementazione sottostante della serie di funzioni difftest_xx .
  • Dal file qemu-system-riscv64, la funzione analizzata è la funzione principale, quindi la funzione difftest_init la chiamerà per avviare il programma qemu.
  • Quindi, se tutto è normale, puoi chiamare la funzione qemu per confrontare i risultati dell'istruzione.

4 QEMU per REF (modalità presa)

Puoi cambiare NEMU/tools/differenza-socket-qemu/, compilato nella libreria dinamica riscv64-qemu-so.
La relazione tra NEMU, librerie dinamiche e QEMU:
Inserisci qui la descrizione dell'immagine

  • Libreria dinamica: riscv64-qemu-so, che esporta la serie difftest_xx di interfacce di funzioni.
  • QEMU: il file eseguibile qemu-system-riscv64 ha le interfacce delle funzioni delle serie cpu_xx e gdb_xx.
  • NEMU: il programma riscv64-nemu-interpreter chiama la libreria dinamica. La libreria dinamica invia un pacchetto di comandi attraverso il socket QEMU riceve il pacchetto e lo analizza e decide quale funzione chiamare per l'esecuzione in base al comando specifico.

processo specifico:

  • Il programma eseguibile NEMU riscv64-nemu-interpreter carica riscv64-qemu-so chiamando la funzione dlopen e analizza i simboli di funzione della serie difftest_xx per le chiamate successive.
  • Quindi, NEMU chiama la funzione difftest_init per inizializzare.
  • Nella funzione difftest_init, un processo figlio eseguirà il fork() e avvierà QEMU chiamando la funzione execlp mentre il processo genitore continua l'esecuzione, si connette a QEMU tramite il socket e chiama la funzione init_isa per inizializzare.
  • Quindi, se tutto è normale, puoi confrontare i risultati del comando tramite il socket.

Documentazione di riferimento: