# Computer Architecture Lab/Winter2006/LechnerWalterStadlerTrinkl/Workplace
## RISE
### Design decisions

We have choose to do a RISC processor featuring a typical load/store architecture. The only powerful instructions are the load (LD) and store instructions (ST) where we focused on a single-cycle implementation. Some parts of the instructions has been inspired by the ARM architecture which has similar load/store operations. All operations can be conditional. We have chosen to use only general purpose registers where we have given the register R13 to R15 special meanings. Please not that all registers share the same location with the exception of the register R15'.
| User Mode | User Mode | Interrupt Mode | Interrupt Mode |
| R0 | 16 Bit Zero Register | R0 | 16 Bit Zero Register |
| R1 | 16 Bit General Purpose Register | R1 | 16 Bit General Purpose Register |
| R2 | 16 Bit General Purpose Register | R2 | 16 Bit General Purpose Register |
| R3 | 16 Bit General Purpose Register | R3 | 16 Bit General Purpose Register |
| R4 | 16 Bit General Purpose Register | R4 | 16 Bit General Purpose Register |
| R5 | 16 Bit General Purpose Register | R5 | 16 Bit General Purpose Register |
| R6 | 16 Bit General Purpose Register | R6 | 16 Bit General Purpose Register |
| R7 | 16 Bit General Purpose Register | R7 | 16 Bit General Purpose Register |
| R8 | 16 Bit General Purpose Register | R8 | 16 Bit General Purpose Register |
| R9 | 16 Bit General Purpose Register | R9 | 16 Bit General Purpose Register |
| R10 | 16 Bit General Purpose Register | R10 | 16 Bit General Purpose Register |
| R11 | 16 Bit General Purpose Register | R11 | 16 Bit General Purpose Register |
| R12 | 16 Bit General Purpose Register | R12 | 16 Bit General Purpose Register |
| R13 | 16 Bit Link Register (Special - See Notes) | R13 | 16 Bit Link Register (Special - See Notes) |
| R14 | 16 Bit Program Counter (Special - See Notes) | R14 | 16 Bit Program Counter (Special - See Notes) |
| R15 | Status Register | R15 | Status Register |
| | | R15' | Backup Status Register |
Register file of RISE processor
Notes: The Link Register R13 is updated with the value of the program counter PC + 2 if the Jump Subroutine instruction is executed. This effectively places the return address in the link register. Notes SR: The Status Register is special because is contains a lot of flags. The lower byte is used to store conditionals and the high byte is used for interrupt handling (Not implemented):
| Bit15 | Bit14:12 | Bit11:8 | Bit 7:4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
| Disable Interrupts | Interrupt Priority Mask | - | - | Overflow | Negative | Carry | Zero |
Status Register

### Pipeline stages

* Instruction fetch: Fetches instructions from program memory.
* Instruction decode and Register fetch
* Execution
* Memory Access
* Write back
Instruction decode and Argument fetch stages could probably be combined in one single stage.

### Interrupt Handling (Feature)

The processor supports eight external interrupt sources INT0 to INT7. If an external interrupt pin is high the value of the interrupt source is compared with the priority level in the status register. If it is greater than or equal to the level and the global Disable Interrupt bit in the status registers is cleared an interrupt is generated.
Interrupt are only handled at the end of the currently executing instruction. If an interrupt is handled the return address is placed in the link register (LR) and the current value of the status register (SR) is copied into the backup status register (R15'). In the next step the processor loads the address stored at 0x0000 + 2*IRQ_NR into its program counter. In addition the interrupt disable flag in the status register (Bit 15) is set which disables any further interrupts.

### Instruction set
#### The conditional flags

Almost all instructions support the usage of conditonals. Conditionals specify if the instruction should be executed depending on the current value of the status registers. The following conditionals are supported:
* 000b: Uncoditional:
* 001b: NZ ( Not Equal != 0 )
* 010b: Z ( Equal = 0)
* 011b: C ( Carry )
* 100b: N ( Negative < 0)
* 101b: O ( Overflow )
* 110b: Z, N (Zero or Negative)

#### Open Questions

These Questions are open and must be worked out:
* What about interrupt support in the feature. If an interrupt occurs it must be possible to save the processor status register and the other registers on something like a stack without corrupting the other registers.

#### Load Instructions
##### Load Immediate

The load immediate instruction loads a 8-Bit constant into the destination register. Depending upon the value of lhb (Load High Byte) the value is either stored in the high or low byte of the register. If the low byte is accessed the high byte is set to zero. Otherwise loading of small constants, which is very frequent, couldn't be done in one instruction. If the high byte is written the low byte remains unchanged.
| Bit 15:13 | Bit 12 | Bit 11:8 | Bit 7:0 |
| 100 (Opcode) | lhb (Load High Byte) | rX (Destination Register) | imm8 (Immediate 8-Bit value) |
Format of Load Immediate instruction
Semantics: If lhb(Load High Byte) is zero the value is stored in the low byte of rX. If lhb is set the value is stored in the high byte of rX. This functions does not affect the status register. For example to load ANY 16-Bit constant the following assembler code is sufficient:
Syntax: ld rX, #IMM8 to load an 8-Bit immediate into rX. ldhb rX, #IMM8 to load an 8-Bit immediate into the high byte of rX.

##### Load Indirect with Displacement

The Load Indirect with Displacement instruction, abbr. ld rX, rZ[rY] adds the value of rZ to the value of the register rY. The resulting address is then used to fetch the operand from memory with the result beeing stored in rX.
| Bit 15:13 | Bit 12:10 | Bit 9:8 | Bit 7:4 | Bit 3:0 |
| 101 (Opcode) | cond (Conditional flags) | rZ (See Notes) | rX (Destination register) | rY (Base Address Register) |
Format of Load Indirect with Displacement
Notes: Only the lower 2bits of rZ are encoded in the instruction. On instruction decode the value is constructed by using the value rZ prefixed by 00b. That is valid registers value for rZ are r0:r3 = 00XX. Semantics: The value of rZ is added to the value of rY. The resulting address is then used to fetch an operand from memory and the result is stored in rX. Depending upon cond the function is either conditional or not. Syntax: ld{COND} rX, rZ[rY]

##### Load Indirect with Displacement and Mode Switch

The Load Indirect with Displacement and Mode Switch instruction works equally to the Load Indirect with Displacement instruction. But additionally this instruction copies the backup SR (R15') into the real SR. This is needed i.e. when leaving an interrupt service routine.
| Bit 15:13 | Bit 12:10 | Bit 9:8 | Bit 7:4 | Bit 3:0 |
| 110 (Opcode) | cond (Conditional flags) | rZ (See Notes) | rX (Destination register) | rY (Base Address Register) |
Format of Load Indirect with Displacement and Mode Switch
Syntax: ldm{COND} rX, rZ[rY]

##### Load Indirect {with Mode Switch}

This Load Indirect function, abbr. ld{m} rX, [rY] is implemented by the Load Indirect with Displacement function by using r0 as displacement register. This functionallity is implemented into the assembler which generates a instruction for ld{m} rX, r0[rY].

##### Load Register Register

The Load Register with Register instruction, abbr. ld rX, rY stores the value of rY in rX.
| Bit 15:11 | Bit 10:8 | Bit 7:4 | Bit 3:0 |
| 00001 (Opcode) | cond (Conditional flags) | rX (Destination register) | rY (Source register) |
Format of Load Register with Register
Semantics: The value of rY is copied into rX. Depending upon cond the instruction is either conditional or not. Syntax: ld{COND} rX, rY Note: Please note that the instruction format is the same as for the general instructions but because it is a load instruction is has been placed here.

#### Store instructions
##### Store Indirect

This Store Indirect function, abbr. st rX, [rY] is implemented by the Store Indirect with Displacement function by using r0 as displacement register. This functionallity is implemented into the assembler which generates a instruction for st rX, r0[rY].

##### Store Indirect with Displacement

The Store Indirect with Displacement instruction, abbr. st rX, rZ[rY] adds the value of rZ to the value of the register rZ. The resulting address is then used to store the value of rX.
| Bit 15:13 | Bit 12:10 | Bit 9:8 | Bit 7:4 | Bit 3:0 |
| 111 (Opcode) | cond (Conditional flags) | rZ (See Notes) | rX (Source register) | rY (Base Address Register) |
Format of Store Indirect with Displacement
Notes: Only the lower 2bits of rZ are encoded in the instruction. On instruction decode the value is constructed by using the value rZ prefixed by 10b. That is valid registers value for rZ are r11:r8 = 10XX. Semantics: The value of rZ is added to the value of rY. The resulting address is then used to store the value of rX to. Depending upon cond the function is either conditional or not. Syntax: st{COND} rX, rZ[rY]

#### Other instructions

All other instructions are of the format shown below.
| Bit 15:11 | Bit 10:8 | Bit 7:4 | Bit 3:0 |
| 0xxxx (Opcode) | cond (Conditional flags) | rX (Destination register) | rY (Source register) |
General instruction for Register-Register Operation
or
| Bit 15:11 | Bit 10:8 | Bit 7:4 | Bit 3:0 |
| 0xxxx (Opcode) | cond (Conditional flags) | rX (Destination register) | imm4 (4 Bit Immediate) |
General instruction for Register-Immediate Operation

##### Arithmetic

All arithmetic instructions work on 16-bit signed values.
| Assembler Syntax | Opcode | Description |
| ADD{COND} rX, rY | 00010 | Add value of rY to rX, and store result in rX. |
| ADD{{COND} rX, #imm4 | 00011 | Add unsigned 4-Bit value to rX. |
| SUB{COND} rX, rY | 00100 | Substract value of rY from rX and store result in rX. |
| SUB{COND} rX, #imm4 | 00101 | Substract unsigned 4-Bit value from in rX. |
| NEG{COND} rX, rY | 00110 | Build two's complement of rY and store result in rX. |
| ARS{COND} rX, rY | 00111 | Arithmetically shift right by value of rY. |
| ALS{COND} rX, rY | 01000 | Arithmetically shift left by value of rY. |
Arithmetic Instructions
Notes: Arithmetic left shift instruction seems to be redundant since the produced result doesn't differ from a logical left shift. Though we think a arithmetic left shift make sense because a logical left shift wouldn't update the overflow bit in the status register.

##### Logical

| Assembler Syntax | Opcode | Description |
| AND{COND} rX, rY | 01001 | Logically and value of rY with rX and store result in rX. |
| NOT{COND} rX, rY | 01010 | Negate the value of rY and store result in rX. |
| EOR{COND} rX, rY | 01011 | Logically exclusive or of rY with rX and store result in rX. |
| LS{COND} rX, rY | 01100 | Shift value of rX left by rY bits. |
| RS{COND} rX, rY | 01101 | Shift value of rX right by rY bits. |
Logical Instructions

##### Program Control

| Assembler Syntax | Opcode | Description |
| JMP{COND} [rX] | 01110 | Jump to subroutine starting at the address provided in register rX. Return address is stored in link register. |
Subroutine instructions

##### Other

| Assembler Syntax | Opcode | Description |
| TST{COND} rX | 01111 | Test value of register rX. |
| NOP | 00000 | Nop instruction |
Other Instructions

## Tool Chain

We have ported the GNU binutils which include assembler, linker and other tools for our processor. You can get download our patch from here (patch-rise-1.5.gz). In addition some assembler source are available my here.

### Installing the port (Users)

Download binutils 2.17 and unpack it into a directory. Switch to this directory and apply our patch and build the toolchain.

### Installing the port (Developers)

The port uses CGEN as a framework for building the assembler, disassembler. Non CGEN specific parts include BFD/ELF support and Autoconf/Automake stuff but changeing them is rarely necessary. First download cgen and unpack it into a directory. Then copy the subdirectory 'cgen' into the binutils directory. Finally configure must be called with --enable-cgen-main to support updating the processor description.
Now build the toolchain to test if everything worked out okay.

### Adding new opcodes

In this example we are going to add a new opcode for loading an immediate value into a register to the processor. Open the file 'cpu/rise.cpu' in an editor and add the following piece of code at the end:
The second line is the assembler syntax and the third list is the actual encoding of the instruction. cond1, $dr, %dr2 and $sr are defined as operands in rise.cpu. OPC_3 is defined as an enum type. If you have finished updating the CPU file change to the opcode directory and call 'make stamp-rise'. This calls CGEN and rebuilds the input source files for the GNU assembler.
Now switch to the top-level directory and rebuild the tools. You can test the new tools without installing them by calling 'gas/as-new' and 'binutils/objdump'.

### Common problems

* Changes in the BFD (e.g. archures.c) subdirectory require calling 'make headers' within this directory.
* If you get an error like .././opcodes/cgen.sh: line 96: guile: command not found during make stamp-rise you have to install guile.

### Using it

You can test the port with the following assembler source code.
The source file must then be compiled by the assembler rise-as and liked with rise-ld to resolve the symbols. This is done with the following steps:
The result can then be disassembling again by calling rise-objdump.
Another demo program for testing the compiler:

### Port Details

The following files have been modified for this port to work:

#### BFD specific parts

A BFD ELF backend is required for storing object files on the disc. In additions it handles all the low levels stuff like relocations, ...
* bfd/aclocal.m4, bfd/configure, bfd/doc/Makefile.in, bfd/Makefile.in, bfd/po/Makefile.in, bfd/config.h, bfd/targmatch.h, bfd/elf32-target.h: Autogenerated
* bfd/configure.in: Add support for or --target=rise.
* bfd/config.bfd: Add target vector
* bfd/cpu-rise.c: CPU architecture and name
* bfd/elf32-rise.c: ELF specific stuff for the architecture.
* bfd/targets.c: Architecture vector.
* bfd/Makefile.am: Add sources and dependencies for compilation.
* bfd/reloc.c: Add support for relocations (Used by high/low bytes of 16-bit addresses).
* bfd/archures.c: Architecture declaration
* bfd/bfd.h bfd/bfd-in2.h bfd/bfd-in3.h bfd/bfdver.h: autogenerated by calling make headers in BFD.
* include/elf/common.h
* include/elf/rise.h

#### CGEN/CPU specific parts

This defines the types of instructions and how they are encoded.
* opcodes/aclocal.m4, opcodes/configure, opcodes/configure.in, opcodes/Makefile.in, opcodes/po/Makefile.in: Autogenerated
* opcodes/Makefile.am: Add support for our target.
* opcodes/disassemble.c: Call disassemble function for our target.
* cpu/rise.cpu: CPU description - Most important file. Add new instructions here.
* cpu/rise.opc: Special handling/parsing for opcodes.
* include/dis-asm.h: Prototype for disassemble function.
* opcodes/rise-asm.c opcodes/rise-desc.c opcodes/rise-desc.h opcodes/rise-dis.c opcodes/rise-ibld.c opcodes/rise-opc.c opcodes/rise-opc.h opcodes/rise-opinst.c: Auto generated by CGEN from rise.cpu and rise.opc for our CPU.

#### GNU assembler specific parts

* gas/aclocal.m4, gas/configure: Autogenerated
* gas/configure.in: Add support for or --target=rise.
* gas/configure.tgt: Add the cpu and the generic target. Define the endianness and the BFD format.
* gas/Makefile.am: Add sources.
* gas/config/tc-rise.c: Special assembler handling for our target and CGEN setup.
* gas/config/tc-rise.h: Defines for our target.

#### GNU ld

* ld/aclocal.m4, ld/Makefile.in
* ld/configure.tgt
* ld/Makefile.am
* ld/emulparams/riseelf.sh: Generates a linker script for our target.

#### Other parts

* binutils/readelf.c: Support for disassembling ELF objects for our target.
* bootstrap.sh
* config.sub, configure