====== QtMips - simulátor architektury MIPS ====== [[https://github.com/cvut/QtMips|QtMips]] je simulátor a nástroj k vizualizaci zpracování instrukcí procesorem s architekturou [[https://en.wikipedia.org/wiki/MIPS_architecture|MIPS]]. Program umožňuje zvolit mezi více možnými způsoby zpracování instrukcí od jednoduché jednocyklové architektury až po plně zřetězené (pipeline) zpracování v pěti stupních. Přitom je možné volit mezi řešením hazardů formou pozastavení nebo, kde je to možné, formou přeposílání výsledků. Pro demonstraci datových hazardů je k dispozici je i konfigurace zřetězeného zpracování bez detekce a řešení hazardů. Program dále umožňuje konfigurovat vyrovnávací paměti (cache) jak pro čtení instrukcí tak pro čtení i zápis dat. Obsah a struktura vyrovnávacích pamětí je opět graficky znázorněna stejně jako jsou barevně zvýrazněné buňky paměti, jejich obsah se nachází v dané chvíli ve vyrovnávací paměti. Simulátor je výsledkem diplomového projektu Ing. Karla Kočího. V jeho diplomové práci [[https://dspace.cvut.cz/bitstream/handle/10467/76764/F3-DP-2018-Koci-Karel-diploma.pdf|Graphical CPU Simulator with Cache Visualization]] lze nalézt analýzu alternativních simulátorů architektury MIPS, popis objektového návrhu simulátoru a návod jak simulátor [[https://github.com/cvut/QtMips|QtMips]] používat. ===== Volba architektury MIPS ===== Jako základní modelová architektura byla pro předmět APO vybraná architektura [[https://en.wikipedia.org/wiki/MIPS_architecture|MIPS]]. Důvody k její volbě: * Jedná se o jednu z prvních architektur založených na koncepci RISC (ta nyní ve vnitřním zpracování instrukcí i původně jinak založených architektur převažuje) * V základní verzi je kódování základní (a přitom pro programování kompletní) sady instrukcí přímočaré * Přímo z kódu jednotlivá pole v instrukčním slovu řídí výběr registrů a operaci * V základní sadě jsou použité pouze tři formáty kódování instrukcí a instrukce mají pevnou délku 32-bitů * Architektura byla v určité době ve své 64-bitové podobě použitá ve stanicích SGI, které daly vznik dnešní akcelerované grafice a mnoha dalším stavebním prvkům * Architektura se stále vyvíjí a je používaná především ve vestavných zařízeních, do nedávna převažovala v domácích WiFi routerech a pravděpodobně byla architekturou s největším množstvím vyrobených čipů (dnes je to již spíš ARM) * Jedná se o architekturu, která je jako úvodní využitá v učebnicích, na kterých je předmět postavený ===== Alternativy ===== * Intel/AMD 64-bitové a 32-bitové procesory - kódování instrukcí není ortogonální, původně malý počet specializovaných registrů, později přes prefixy rozšíření na 16 registrů, komplikovaný a již opuštěný model segmentace paměti, interně jsou CISC instrukce překládané do RISC instrukční sady, ale ta není dokumentovaná * [[https://en.wikipedia.org/wiki/ARM_architecture|ARM]] 32-bitů (Cortex-A - aplikační, Cortex-M - MCU, Cortex-R - realtime) - složitější kódování instrukcí a vkládání přímých operandů, druhý operand je kombinovaný s logickými posuny, množství režimů auto-inkrementace/dekrementace a vedlejších efektů instrukcí, komplikovaný model zpracování výjimek. Alternativní sada kódování instrukcí do délek 16 a 32 bitů (Thumb), v pevném 32-bit kódování možnost veškeré instrukce podmínit stavem příznakového registru. Obecně tyto volby umožňují uložit program do menšího prostoru, ale činní architekturu nevhodnou pro základní výuku, kdy je ještě potřeba programovat v assembleru a i obecně komplikují současné zpracování více instrukcí naráz. * [[https://en.wikipedia.org/wiki/ARM_architecture#AArch64|ARM AArch 64]] - adresní režimy již jednodušší, příklon v mnoha směrech více k architektuře MIPS než původnímu ARM 32 například i zjednodušeným způsobem zpracování výjimek. Přesto se jedná o architekturu již komplikovanou. * [[https://riscv.org/|RISC-V]] - architektura plně otevřená s množstvím dostupných implementací v různých jazycích pro popis hardware. Velmi rychle se rozvíjející komunita a nasazení. Opět se jedná o architekturu s malým množstvím formátů instrukcí (stejně jako MIPS). Nevýhodou je pro počáteční názorné ukázky komplikovanější kódování přímých operandů. ====== Simulátor QtMips ====== K výuce se po dlouhou dobu používal simulátor dodávaný s učebnicemi Computer Organization and Design. Jeho architektura byla již nevyhovující, přitom aplikace byla implementovaná s využitím starého WIN 32 API. Méně problémů bylo s jejím provozem v emulaci než nativně na Windows. K aplikaci nebylo možné sehnat zdrojové kódy a problémy řešit. QtMips je výsledkem zadané diplomové práce. Jedná se již o třetí práci na toto téma a v tomto případě považujeme výsledek za zdařilý. Aby se práce soustředila na implementaci vlastního simulátoru, bylo rozhodnuté, že nebude obsahovat editor ani integrovaný překladač zdrojového kódu. K překladu se využívají plnohodnotné nástroje pro programování MISP a jiných procesorů od malých vestavných aplikací až po superpočítače - překladač [[https://gcc.gnu.org/|GCC]] a [[https://sourceware.org/binutils/docs/as/index.html|GNU assembler]] vzniklé v rámci projektu [[https://www.gnu.org/|GNU]]. Pro editaci zdrojových kódů lze využít odlehčený editor [[https://www.geany.org/|Geany]] nebo jiný editor. Pro překlad pak GNU překladač kompilující programy pro architekturu MIPS. V nejjednodušší variantě například voláním mips-elf-gcc -ggdb -nostartfiles -o program program.S z příkazové řádky, kdy je výsledkem překladu zdrojového souboru v assembleru (standardizovaně přípona velké S - ''.S'') přímo spustitelný program. Volba ''-ggdb'' určuje, že budou přidané ladící informace. Volba ''-nostartfiles'' pak určuje, že zdrojové kódy obsahují přímo vstupní bod programu. Pokud volba není zadaná, přidá se standardní inicializační část C knihovny - objektový soubor ''crt.o''. Protože se předpokládá jeho zavedení operačním systémem, je vlastní strojový kód v instrukcích cílového procesoru vložený do obálky ve formátu [[https://en.wikipedia.org/wiki/Executable_and_Linkable_Format|ELF]] (Executable and Linkable Format), která určuje adresy, na které bude kód zavedený a adresu od které se má spustit. Adresy, na které bude kód a příslušná data zavedená lze zobrazit příkazem objdump --headers program Proložený výpis zdrojového kódu a výsledku překladu lze pak získat objdump --source program tento postup je pak zajímavější při kompilaci kódu z vyššího programovacího jazyka, ale pro pochopení základů zůstaňme ještě u assembleru. Minimální zdrojový soubor může vypadat následovně .globl _start .set noat .set noreorder .ent _start _start: addi $1, $0, 0x1234 // prostor pto pokačování loop: break beq $0, $0, loop nop .end _start Volba ''.globl'' určuje, že návěští ''_start'' bude viditelné i vně kompilační jednotky/souboru. Volba ''.noat'' zakazuje assembleru vkládat sekvence využívající pomocný registr. Volba ''.noreorder'' zakazuje assembleru optimalizovat kód skokových instrukcí a automaticky využívat "delay slot". Volba ''.ent'' označuje, od kterého symbolu bude kód startovat. Identifikátory před dvojtečkou jsou návěští, symbolické označení adresy, na kterou se lze odkazovat z instrukcí. Dále následují instrukce pro vlastní procesor. V přiloženém příkladu se jedná pouze o jednu instrukci, přičtení přímého operandu 0x1234 hexadecimálně k registru 0 fixovanému na hodnotu nula a uložení výsledku do registru 1. Další návěští ''loop'' slouží k zastavení programu po jeho vykonání. Zastavení kontinuálního běhu simulátoru zajišťuje zakompilovaná instrukce ''break''. Tento strojový kód by se využil i při ladění na skutečném systému, kdy ladící program podle potřeby nahradí instrukce v programu kódem ''break'' na místo většinou určené podle čísla řádky zdrojového souboru a při jeho dosažení při normálním běhu procesoru dojde k výjimce, kterou obslouží ladící program. Následuje skoková instrukce, která zajistí i při pokusu o pokračování programu v simulátoru opětovné zastavení na instrukci ''break''. Nakonec pseudoinstrukce ''.end'' označuje konec kódu a opět určuje adresu od které se bude program spouštět. Podrobnější popis a formátů souborů a kompilace programů naleznete na stránce projektu QtMips. [[https://github.com/cvut/QtMips/blob/master/docs/exec-formats-and-tools.md|QtMips - spustitelné formáty a kompilátory]] ====== Odkazy na stažení simulátoru QtMips ====== Zdrojové kódy jsou spravované na platformě GitHub. Na této platformě je možné snadno vytvořit vlastní vývojovou větev (fork). Původní práce pana Kočího se nachází na adrese [[https://github.com/Cynerd/QtMips]], současná nejnovější větev na stránce [[https://github.com/cvut/QtMips]]. Zkompilované verze programu pro platformu GNU/Linux 64-bitů a Windows 32-bitů se nacházejí ve složce release projektu [[https://github.com/cvut/QtMips/releases]]. Zabalené archivy obsahují i potřebné knihovny. Vlastní grafická verze programu na Windows se nachází ve spustitelném programu ''qtmips_gui.exe''. Na platformě GNU/Linux je nutné buď nainstalovat potřebné knihovny (jedná se o [[https://doc.qt.io/|Qt5]]) v odpovídající verzi do systému nebo program spouštět skriptem ''qtmips.sh'' který nastaví cesty k lokálně distribuovaným knihovnám a spustí vlastní aplikaci ''bin/qtmips_gui''. Pro aktuální verze distribuce Ubuntu GNU/Linuxu jsou připravené zkompilované balíky na adrese [[https://launchpad.net/~ppisa/+archive/ubuntu/qtmips]]. Pro několik dalších distribucí jsou k dispozici balíky kompilované [[https://software.opensuse.org//download.html?project=home%3Appisa&package=qtmips|Suse Open Build Service]]. V laboratorní síti je aplikace nainstalovaná do systému a lze jí spouštět přímo z příkazové řádky příkazem ''qtmips_gui'' nebo z nabídky aplikací ve složce ''Development''. Instalace se nachází v adresáři ''/opt/qtmips'' a je jí možné dotud i zkopírovat na vlastní médium nebo do emailu. K dispozici je i experimentální verze emulátoru zkompilovaného jako WASM aplikace pro prohlížeče s podporou WebGL, WASM a Javascriptu [[http://cmp.felk.cvut.cz/~pisa/apo/qtmips/qtmips_gui.html]]. K překladu zdrojových kódů je pak potřeba překladač, který je popsaný na stránce [[..:mips-elf-gnu:start|Křížový překladač GNU pro architekturu MIPS-ELF]]. ====== Kompilace ze zdrojových kódů ====== Nejdříve je potřeba nainstalovat vývojové prostředí knihoven Qt5. Na distribucích Debian i Ubuntu se instalace vývojového prostředí docílí příkazy sudo apt-get install build-essential sudo apt-get install qtcreator sudo apt-get install qt5-default Vlastní aplikaci lze z vývojového repozitáře naklonovat příkazem git clone git://github.com/cvut/QtMips.git K vlastní kompilaci lze buď projekt otevřít v prostředí [[https://doc.qt.io/qtcreator/index.html|QtCreator]] nebo provést kompilaci z příkazové řádky mkdir QtMips-build cd QtMips-build qmake "CONFIG+=static" "CONFIG+=staticlib" -recursive ../QtMips/qtmips.pro make Pokud se na systému nachází jako počáteční vývojové prostředí ke Qt4 může být nutné použít plnou cestu programu ''qmake'' /usr/lib/x86_64-linux-gnu/qt5/bin/qmake "CONFIG+=static" "CONFIG+=staticlib" -recursive ../QtMips/qtmips.pro Více opět na stránkách projektu.