- π Overview
- π Get Started
- πΎ Memory units and register description
- π» ISA specifications
- 𧱠Design
- β¨ Contributors
- π License
- It is required to design, implement and test a Harvard (separate memories for data and instructions), RISC-like, five-stages pipeline processor, with the specifications as described in the following sections
- Project Description
- Built using:
- Clone the repository
git clone https://github.com/AdhamAliAbdelAal/Pipelined-Processor
- Put your test cases in "code.asm"
cd './Assembler/code.asm'
- Run
python ./Assembler/assembler.py
- Main file is
cd './Codes/Processor.v'
- There are more test cases in folder
cd './Assembler/TestCases'
- In this project, we apply a Harvard architecture with two memory units; Instructionsβ memory and Data memory.
- The processor in this project has a RISC-like instruction set architecture. There are eight 2-bytes general purpose registers[ R0 to R7]. These registers are separate from the program counter and the stack pointer registers.
- The program counter (PC) spans the instructions memory address space that has a total size of 2 Megabytes. Each memory address has a 16-bit width (i.e., is word addressable). The instructions memory starts with the interrupts area (the very first address space from [0 down to 2^5 -1]), followed by the instructions area (starting from [2^5 and down to 2^20]) as shown in Figure.1. By default, the PC is initialized with a value of (2 5 ) where the program code starts.
- The other memory unit is the data memory, which has a total size of 4 Kilobytes for its own, 16-bit in width (i.e., is word addressable). The processor can access both memory units at the same time without having a memory access hazard.
- The data memory starts with the data area (the very first address space and down), followed by the stack area (starting from [2^11 β 1 and up]) as shown in Figure.1. By default, the stack pointer (SP) pointer points to the top of the stack (the next free address available in the stack), and is initialized by a value of (2^11 -1).
- When an interrupt occurs, the processor finishes the currently fetched instructions (instructions that have already entered the pipeline), save the processor state (Flags), then the address of the next instruction (in PC) is saved on top of the stack, and PC is loaded from address 0 of the memory where the interrupt code resides.
- For simplicity reasons, we will have only one interrupt program, the one which starts at the top of the instructionβs memory, but be aware of possible nested interrupts i.e., an interrupt might be raised while executing an interrupt, and your processor should handle all of them successfully.
- To return from an interrupt, an RTI instruction loads the PC from the top of stack, restores the processor state (Flags), and the flow of the program resumes from the instruction that was supposed to be fetched in-order before handling the interrupted instruction. Take care of corner cases like Branching
-
Register
- R[0:7]<15:0> : Eight 16-bit general purpose registers
- PC<31:0> : 32-bit program counter
- SP<31:0> : 32-bit stack pointer
- CCR<3:0> : condition code register that can be divided to
- Z<0>:=CCR<0> : zero flag, change after arithmetic, logical, or shift operations
- N<0>:=CCR<1> : negative flag, change after arithmetic, logical, or shift operations
- C<0>:=CCR<2> : carry flag, change after arithmetic or shift operations.
-
Input-Output
- IN.PORT<15:0> : 16-bit data input port
- OUT.PORT<15:0> : 16-bit data output port
- INTR.IN<0> : a single, non-maskable interrupt
- RESET.IN<0> : reset signal
-
Other registers to hold the operands and opcodes of the instructions
- Rsrc : 1st operand register
- Rdst : 2nd operand register and result register field
- Imm : Immediate Value
- Instructions (some instructions will occupy more than one memory location)
- NOT value stored in register Rdst
- R[ Rdst ] β 1βs Complement(R[ Rdst ])
- If (1βs Complement(R[ Rdst ]) = 0): Z β1; else: Z β0
- If (1βs Complement(R[ Rdst ]) < 0): N β1; else: N β0
- Increment value stored in Rdst
- R[ Rdst ] βR[ Rdst ] + 1
- If ((R[ Rdst ] + 1) = 0): Z β1; else: Z β0
- If ((R[ Rdst ] + 1) < 0): N β1; else: N β0
- Decrement value stored in Rdst
- R[ Rdst ] βR[ Rdst ] β 1
- If ((R[ Rdst ] - 1) = 0): Z β1; else: Z β0
- If ((R[ Rdst ] - 1) < 0): N β1; else: N β0
- Add the values stored in registers Rsrc, Rdst and store the result in Rdst
- If the result =0 then Z β1; else: Z β0;
- If the result less than 0 then N β1; else: N β0
- Subtract the values stored in registers Rsrc, Rdst and store the result in Rdst
- If the result =0 then Z β1; else: Z β0;
- If the result less than 0 then N β1; else: N β0
- AND the values stored in registers Rsrc, Rdst and store the result in Rdst
- If the result =0 then Z β1; else: Z β0;
- If the result less than 0 then N β1; else: N β0
- OR the values stored in registers Rsrc, Rdst and store the result in Rdst
- If the result =0 then Z β1; else: Z β0;
- If the result less than 0 then N β1; else: N β0 ;
- Jump if zero
- If (Z=1): PC βR[ Rdst ]; (Z=0)
- Jump if negative
- If (N=1): PC βR[ Rdst ]; (N=0)
- Jump if negative
- If (C=1): PC βR[ Rdst ]; (C=0)
- Jump
- PC βR[ Rdst ]
Mnemonic | Function |
---|---|
π One Operand | |
πΆ NOP | PC β PC + 1 |
π· SETC | C β 1 |
πΆ CLRC | C β 0 |
π· NOT Rdst |
|
πΆ INC Rdst |
|
π· DEC Rdst |
|
πΆ OUT Rdst | OUT.PORT β R[ Rdst ] |
π· IN Rdst | R[ Rdst ] βIN.PORT |
βοΈ Two Operand | |
π· MOV Rsrc, Rdst | Move value from register Rsrc to register Rdst |
πΆ ADD Rsrc, Rdst |
|
π· SUB Rsrc, Rdst |
|
πΆ AND Rsrc, Rdst |
|
π· OR Rsrc, Rdst |
|
πΆ SHL Rsrc, Imm |
Shift left Rsrc by #Imm bits and store result in same register Donβt forget to update carry |
π· SHL Rsrc, Imm |
Shift right Rsrc by #Imm bits and store result in same register Donβt forget to update carry |
πΎ Memory Operations | |
πΆ PUSH Rdst | X[SP--] β R[ Rdst ] |
π· POP Rdst | R[ Rdst ] β X[++SP] |
πΆ LDM Rdst, Imm | Load immediate value (15 bit) to register Rdst R[ Rdst ] β Imm<15:0> |
π· LDD Rsrc, Rdst | Load value from memory address Rdst to register Rdst R[ Rdst ] β M[Rsrc]; |
πΆ STD Rsrc, Rdst | Store value in register Rsrc to memory location Rdst M[Rdst] βR[Rsrc]; |
π¦ Branch and Change of Control Operations | |
π· JZ Rdst |
|
πΆ JN Rdst |
|
π· JC Rdst |
|
πΆ JMP Rdst |
|
π· CALL Rdst | (X[SP] β PC + 1; sp-2; PC β R[ Rdst ]) |
πΆ RET | sp+2, PC βX[SP] |
π· RTI | sp+2; PC β X[SP]; Flags restored |
π» Input Signals | |
πΆ Reset | PC β2 5h //memory location of the first instruction |
π· Interrupt | X[Sp]βPC; sp-2;PC β 0; Flags preserved |
- You can view Design
- OP Code
- Output Signals from Control Unit
khaled Farahat |
Adham Ali |
Mohamed Walid |
Eslam Ashraf |
Note: This software is licensed under MIT License, See License for more information Β©Adham Ali.