User Tools

Site Tools


tutoriale:debug-ise

= Debugging folosind Xilinx ISE = * Tutorialul își propune depanarea unui modul folosind uneltele de debugging puse la dispoziție de simulatorul integrat în Xilinx ISE. Scopul modului este să implementeze un sumator cu propagare a transportului (ripple carry). O implementare Verilog a acestuia, care conține 2 greșeli, este prezentată în figura următoare. {{ :tutoriale:debug-ise:00.jpg?direct&400 |}} * Modulul de test folosit pentru simulare este următorul. {{ :tutoriale:debug-ise:01.jpg?direct&400 |}} * Simularea inițială a modului poate fi observată în figura următoare. Se observă că semnalul //sum// conține valori nedefinite (//X//) pe toată durata de simulare a modulului. {{ :tutoriale:debug-ise:02.jpg?direct&400 |}} * Pentru a ne ușura analiza semnalelor vom schimba modul în care aceastea sunt afișate. Apăsând click-dreapta pe un semnal vom alege ca acesta să fie afișat ca un număr în baza 10, fără semn. {{ :tutoriale:debug-ise:03.jpg?direct&400 |}} * După ce schimbăm toate semnalele, diagrama va arăta în felul următor. {{ :tutoriale:debug-ise:04.jpg?direct&400 |}} * Putem expanda un semnal pe mai multi biți pentru a inspecta toți biții acestuia. {{ :tutoriale:debug-ise:05.jpg?direct&400 |}} * Se poate observa că doar bitul 7 din ''//sum//'' este nedefinit. {{ :tutoriale:debug-ise:06.jpg?direct&400 |}} * Putem vedea variabilele interne unui modul dacă selectăm selectăm instanța acestuia din lista de instanțe. În cadrul ierarhiei, modulul nostru se află imediat sub modulul ''//test_adder//'', iar instanța acestuia se numește ''//uut//'' (//unit under test//). {{ :tutoriale:debug-ise:07.jpg?direct&400 |}} * Putem deschide codul sursă al unei instanțe în simulator făcând dublu-click pe aceasta. {{ :tutoriale:debug-ise:08.jpg?direct&400 |}} * În cadrul editorului de cod putem activa un breakpoint la linia curentă folosind tasta ''//F9//'' sau făcând click pe porțiunea gri din dreapta numărului liniei. {{ :tutoriale:debug-ise:09.jpg?direct&400 |}} * În continuare vom activa 2 breakpoint-uri, la liniile 35 și 37, pentru a putea inspecta starea variabilelor în fiecare iterație și la sfârșitul ciclului. {{ :tutoriale:debug-ise:10.jpg?direct&400 |}} * Repornim simularea folosind butonul //Restart//. {{ :tutoriale:debug-ise:11.jpg?direct&400 |}} * Se poate observa că la începutul simulării toate variabilele modulului ''//uut//'' sunt nedefinite(''x'' inseamna nedefinit), lucru normal deoarece simularea nu a început încă . {{ :tutoriale:debug-ise:12.jpg?direct&400 |}} * Folosim butonul ''//Run All//'' pentru a porni simularea. {{ :tutoriale:debug-ise:13.jpg?direct&400 |}} * Simularea se va opri la orice breakpoint întâlnit. În cazul nostrul, primul breakpoint întâlnit este cel de la linia 35, iar simularea se va opri **înainte** de a executa instrucțiunea de la linia 35. În acest moment al simulării putem vedea că ambele intrări ale modului au valoarea 0, contorul ciclului are valoarea 0 (ne aflăm în prima iterație), iar ieșirile sunt încă nedefinite, deoarece încă nu le-am atribuit nici o valoare. {{ :tutoriale:debug-ise:14.jpg?direct&400 |}} * Vom rula simularea în continuare folosind butonul ''//Run All//''. Simularea se va opri din nou la breakpoint-ul de la linia 35, însa în momentul acesta ne aflăm în a doua iterație a ciclului. Putem vedea lucrul acesta inspectând valoarea contorului, care este 1 (prima valoare a contorului a fost 0). În această iterație vedem că primul bit al lui ''//sum//'' a fost setat la valoarea 0. {{ :tutoriale:debug-ise:15.jpg?direct&400 |}} * Rulăm în continuare simularea, folosind butonul ''//Run All//'', până când execuția ciclului se termină și ajungem la breakpoint-ul de la linia 37. În acest moment, pentru o implementare corectă, suma celor două intrări ar trebui să fie calculată complet. Observăm însă că cel mai semnificativ bit al lui //sum// a rămas nedefinit. Înseamnă că ciclul nostru s-a terminat prea repede. Inspectând condiția de oprire, vedem că ieșirea din ciclu se face când ''//i//'' devine 7. Iterația corespunzătoare lui ''//i == 7//'' nu se execută, ceea ce explică de ce bitul 7 din ''//sum//'' este nedefinit. {{ :tutoriale:debug-ise:16.jpg?direct&400 |}} * Modificăm codul corectând cu condiția corectă: ''//i < **8**//''. {{ :tutoriale:debug-ise:17.jpg?direct&400 |}} * După ce am modificat codul modulului este necesar să recompilăm simularea pentru a vedeam efectele schimbării. Folosim butonul ''//Re-launch//'' pentru a recompila și rerula simularea. {{ :tutoriale:debug-ise:18.jpg?direct&400 |}} * __Eliminăm breakpoint-urile făcând click pe ele sau folosind tasta //F9// pentru a putea rula ușor simularea până la capăt cu butonul ''//Run All//''__. La o primă vedere, din fereastra de variabile, rezultatul pare a fi corect, semnalele nedefinite au dispărut, iar suma pare a fi calculată corect. {{ :tutoriale:debug-ise:19.jpg?direct&400 |}} * Inspectarea digramei de semnale, însă, arată că suma dintre 10 și 40 este 39. {{ :tutoriale:debug-ise:20.jpg?direct&400 |}} * Adăugăm din nou breakpoint-urile anterioare și reluăm simularea de la început cu butonul ''//Restart//''. {{ :tutoriale:debug-ise:21.jpg?direct&400 |}} * Rulăm simularea până ajungem în prima iterație a celei de-a doua pereche de numere adunate. Recunoaștem această stare după valorile ''//00101000//'' și'' //00001010//'' prezente la intrarile ''//a//'' și ''//b//'' și valoarea 0 a controului ''//i//''. Valoarea sumei, ''//00000000//'', este rămasă de la adunarea anterioară. {{ :tutoriale:debug-ise:22.jpg?direct&400 |}} * În a doua iterație vedem că suma calculată în prima iterație pentru cel mai puțin semnificativ bit al lui ''//sum//'' este **1**. Din datele de intrare: ''//a[0] == 0//'', ''//b[0] == 0//'' și ''//c_in == 0//'' am deduce că această sumă ar trebui să fie 0. Inspectând expresia pentru calcul sumei, observăm că rezultatul pentru toți biții lui //sum// se calculează cu ''//b[**1**]//''. {{ :tutoriale:debug-ise:23.jpg?direct&400 |}} * Modificăm codul, corectând cu expresia corectă a sumei în funcție de //b[**i**]//. {{ :tutoriale:debug-ise:24.jpg?direct&400 |}} * Dezactivăm breakpoint-urile, recompilăm simularea și inspectăm din nou diagrama de semnale. Cu modificările făcute, circuitul pare să funcționeze corect (cel puțin pentru cele 4 cazuri testate). {{ :tutoriale:debug-ise:25.jpg?direct&400 |}} * În continuare, pentru a ne asigura de funcționarea corectă a modului, acesta trebuie testat folosind mai multe combinații pentru variabilele de intrare (în special cazuri limită). La descoperirea unei erori în output, vom relua procesul de debugging, pentru a găsi și corecta bug-ul.

tutoriale/debug-ise.txt · Last modified: 01.10.2017 (external edit)