C15 is a 32-bit, 100 MHz softcore microprocessor synthesized using an FPGA. The processor contains three registers, all 32 bits wide: register A, register B, and register R, which are used for arithmetic operations. There are four flags: zero, greater than, less than, and out of time (indicating the exhaustion of the execution time).
Press "Run" to assemble/compile, upload, and execute the machine code. You can program the processor by either using C15 assembly or the C programming language.
To use the C compiler, click on the button and add .c to end of your filename.
The compiler has support for struct, array and 32-bit primitive data types: uint, int, and float.
There is currently no support for recursion due to the limited stack space in the processor.
There are a few intrinsics provided:
To use the assembler, click on the button and add .asm to end of your filename. Additionally, you can view the disassembly of C files by clicking on the View Disassembly button.
Instructions are 32-bits in size, except for STORE and STOREPUSH, which are 64-bits in size. Opcodes are 8-bits in size. Arguments/operands are 12-bits in size, except for the immediate values of STORE and STOREPUSH.
Halts the execution of the processor.
Saves the value in register R to the given address.
Saves the value in register A to the given address.
Saves the value in register B to the given address.
Pushes the value in register R to the top of the general-purpose stack.
Saves the value in register R to register A.
Saves the value in register R to register B.
Writes the given immediate value to the address.
The given immediate value is 32-bits in size.Pushes the given immediate value to the top of the general-purpose stack.
The given immediate value is 32-bits in size.Writes the given immediate value to the given address.
Loads the value located at the given address into register A.
Loads the value located at the given address into register B.
Loads the value located at the given address into register A and loads the given immediate value into register B.
Pops the value at the top of the general-purpose stack and saves it into register A.
Pops the value at the top of the general-purpose stack and saves it into register B.
Pops the value at the top of the general-purpose stack and saves it into register R.
Loads the given immediate value into register A.
Loads the given immediate value into register B.
Pushes the given immediate value to the top of the general-purpose stack.
Pushes the value at the given address to the top of the general-purpose stack.
Pops the value from the top of the general-purpose stack and saves it at the given address.
Pops the value from the top of the general-purpose stack and discards it.
Swaps the values of register A and B.
Sets the on-board 8-bit LEDs to represent the value in register A.
Generates a 32-bit random number and places the random number into register A.
Places the number of clock cycles since execution began into register R.
Performs no operation.
Pushes the next address after the current address to the call stack and jumps to the given address.
Pushes the next address after the current address to the call stack and jumps to the address located at the given address.
Pops the address at top of the call stack and jumps to it.
Jumps to the given address (sets the program counter to the given address).
Jumps to the given address if the value in register R is non-zero.
Jumps to the given address if the value in register R is zero.
Jumps to the given address if the zero flag is set to 1.
Jumps to the given address if the zero flag is set to 0.
Jumps to the given address if the less than flag is set to 1.
Jumps to the given address if the greater than flag is set to 0.
Jumps to the given address if the greater than flag is set to 1.
Jumps to the given address if the less than flag is set to 0.
Copies the value from the source address to the destination address.
Copies the value from the source address to the destination address defined in register R.
Pops the source address from the top of the stack and copies the value from the source address to the destination address defined in register R.
Copies the value located at the source address defined in register R to the destination address.
Pushes the value located at the source address defined in register R to the top stack.
If the value in register A and register B are non-zero, then 1 is saved into register R, otherwise 0 is saved into register R.
If the value in register A or register B (or both) are non-zero, then 1 is saved into register R, otherwise 0 is saved into register R.
Performs bitwise NOT on the value in register A and saves the result into register R. (~A)
Performs bitwise AND on the values in register A and register B and saves the result into register R. (A & B)
Performs bitwise OR on the values in register A and register B and saves the result into register R. (A | B)
Performs bitwise XOR on the values in register A and register B and saves the result into register R. (A ^ B)
Left shifts the value in register A by the value in register B and saves the result into register R. (A << B)
Right shifts the value in register A by the value in register B and saves the result into register R. (A >> B)
Converts a single-precision floating-point in register A to an integer and places the result in register R. (int)A
Converts an integer in register A to a single-precision floating-point and places the result in register R. (float)A
Increments the value of register A and saves the result back into register A. (A++)
Decrements the value of register A and saves the result back into register A. (A--)
Sums the values in register A and B and saves the result in register R. (A + B)
For unsigned/signed addition, the zero flag will be set to 1 if the result is zero (which may occur because of an arithmetic overflow).Subtracts the values in register A and B and saves the result in register R. (A - B)
For unsigned/signed substraction, the zero flag will be set to 1 if the result is zero (which may occur because of an arithmetic underflow).Multiplies the values in register A and B and saves the result in register R. (A × B)
For unsigned/signed multiplication, the zero flag will be set to 1 if the result is zero.Divides the values in register A and B and saves the quotient in register R. (A ÷ B)
For unsigned/signed division, the zero flag will be set to 1 if the result is zero.Divides the values in register A and B and saves the remainder in register R. (A % B)
Compares the values in registers A and B and sets the following flags:
Compares the values in register A and B and places a 1 if A < B, otherwise 0 in register R.
Compares the values in register A and B and places a 1 if A > B, otherwise 0 in register R.
Compares the values in register A and B and places a 1 if A <= B, otherwise 0 in register R.
Compares the values in register A and B and places a 1 if A >= B, otherwise 0 in register R.
Compares the values in register A and B and places a 1 if A == B, otherwise 0 in register R.
Compares the values in register A and B and places a 1 if A != B, otherwise 0 in register R.
Places a 1 in register R if the value in register A is zero.
Places a 0 in register R if the value in register A is non-zero.
Sums the given immediate values A and B and saves the result in register R. (A + B)
Sums the value located at the given address with the immediate value and saves the result in register R. (A + B)
Substracts the given immediate values and saves the result in register R. (A - B)
Substracts the value located at the given address with the given immediate value and saves the result in register R. (A - B)