Interactive MIPS processor simulation and visualisation.
MIPS visualiser is project aimed at showcasing underlying principles of every CPU using MIPS architecture as an example.
When using MIPS simulator, these are the steps you could follow:
-
Modify registers (optional).
-
Modify RAM memory (optional).
-
Load the instruction.
-
Execute instruction either as a whole or step by step.
-
You can manipulate individual registers.
- Note that some of them aren't editable such as $ir, $target and $zero.
-
By default, all values are set to 0. Not all instructions require registers to be edited.
-
Hover over register's alias to display its purpose and current value in binary.
- When you modify values, you write them in decimal.
-
When referencing registers you can use numbers or aliases (e.g. $0 and $zero are pointing to same register).
-
You can set values for specific memory locations (addresses).
-
You do not have to set memory values for every instruction, it is optional.
-
By default, when you load an instruction, it is written at address that $pc register points to.
-
Instructions are specified using MIPS assembly language.
-
Supported instructions:
- add
- addi
- sub
- slt
- beq
- bne
- lw
- sw
-
Instructions modify registers and memory in real time, so be sure to check out changed values after execution.
Once you set up instruction, registers and memory, it's time for execution.
You can:
-
Execute instruction clock by clock.
-
Execute all clocks in a sequence.
Animation speeds can also be altered, which will reflect to both methods of execution.
Once instruction execution begins, you can inspect different parts of the CPU while it's executing.
Provided CPU schema is interactive, hover over any of the focused elements to get details regarding it.
I have included only a subset of MIPS ISA which, in my opinion, is sufficient for demonstrating principles.
However, I have made it quite easy to implement new instructions which would fit right into the existing architecture.
Instructions are defined in a single configuration file Specification.ts
const Specification = {
...,
instructions: [
{
alias: 'add',
opcode: '000000',
funct: '100000',
type: 'R',
clocks: [
'clock_1',
'clock_2',
'custom_clock',
]
}
],
...,
}
As you can see, among other things, instructions define clocks they use.
Some clocks are same for every instruction.
-
Precisely, clock 1 and 2 are common for every instruction.
-
Rest of the clocks vary from instruction to instruction.
Clocks are defined both as separate classes and in config file:
class CustomClock implements Clock
{
public id (): string
{
return 'custom_clock'; // id referenced by instruction
}
public execute (cpu: CPU): void
{
// Manipulate the CPU.
}
}
And in Specification.ts
file:
const Specification = {
...,
clocks: [
{
id: 'custom_clock',
focus: ['el1', 'el2', ...],
tooltips: [
{
...
}
]
}
],
...
};
As you can see there are few different steps:
-
Defining class that implement interface
Clock
.-
Define the clock id, used to reference the clock inside an instruction.
-
Implement the clock logic.
-
Add clock to
ClockFactory.fromId(id: string): Clock
method.
-
-
Define clock in
Specification.ts
. Clock is defined by:-
id: same id you put in Clock implementation.
-
focus: List of HTML entities to be focused when this clock is active.
-
tooltips: Array of objects defining tooltips.
-
Tooltips are blocks of information visible on element hover.
You can define tooltips that are shown only when certain clock is active, or ones that are not tied to any particular clock (global).
Tooltip is defined by:
-
ids: List of HTML entities which will trigger this tooltip.
-
additional: List of HTML entities to be focused when this tooltip becomes active.
-
title: String representing tooltip title.
-
description: HTML representing tooltip description.
-
value: Function that takes the cpu instance and returns a value of particular component.
- This is mostly used when tooltip is related to a Clock. This function allows us to extract values from CPU in runtime.
const tooltip = {
ids: ['el1', 'el2', ...],
additional: ['el3', 'el4'],
title: 'Tooltip title',
description: '<div>Tooltip HTML body.</div>',
value: (cpu: CPU) => {
return cpu.register('$3').value;
}
};
Global tooltips are defined Specitifcation.ts
file:
const Specification = {
...,
global_tooltips: [
...
],
...,
};
Clock specific tooltips are define inside configuration object of a specific clock.
1.) Angular 8.
2.) Jasmine + Karma.
3.) Tailwind CSS.
4.) Docker/Travis/GitHub Pages.
docker exec -it mips-visualiser ng test --watch=false
docker exec -it mips-visualiser bash
- Clone this repository wherever you see fit.
- From terminal, navigate to cloned repository.
- Run
docker-compose build
. - Run
docker-compose up
. - From host machine:
docker exec -it mips-visualiser bash
. - Run
npm i
. - Run
ng serve --host 0.0.0.0
. - Navigate to http://localhost:4200.
- Upon next container initialization, command number 7. will be automatically run.