====== 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.