Skip to content

🧠 Pipelined Processor is to design, implement and test a Harvard (separate memories for data and instructions), RISC-like, five-stages pipeline processor.

License

Notifications You must be signed in to change notification settings

EslamAsHhraf/Pipelined-Processor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧠 Pipelined Processor

logo

”Take Rest, Let Our Processor Handle your Tasks. πŸš€β€œ


πŸ“ Table of Contents


πŸ“™ Overview

  • 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:
    1. Verilog
    2. Python

πŸš€ Get Started

  1. Clone the repository
    git clone https://github.com/AdhamAliAbdelAal/Pipelined-Processor
  2. Put your test cases in "code.asm"
     cd './Assembler/code.asm'
  3. Run
    python ./Assembler/assembler.py
  4. Main file is
     cd './Codes/Processor.v'
  5. There are more test cases in folder
     cd './Assembler/TestCases'

πŸ€– Memory units and registers description

  • 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

πŸ–₯️ ISA specifications

  • 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)

  • Mnemonic Function
    πŸ‘† One Operand
    πŸ”Ά NOP PC ← PC + 1
    πŸ”· SETC C ← 1
    πŸ”Ά CLRC C ← 0
    πŸ”· NOT Rdst
    • 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

    πŸ”Ά INC Rdst
    • 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
    πŸ”· DEC Rdst
    • 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
    πŸ”Ά 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
    • 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
    πŸ”· SUB Rsrc, Rdst
    • 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 Rsrc, Rdst
    • 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 Rsrc, Rdst
    • 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 ;
    πŸ”Ά 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
    • Jump if zero
    • If (Z=1): PC ←R[ Rdst ]; (Z=0)
    πŸ”Ά JN Rdst
    • Jump if negative
    • If (N=1): PC ←R[ Rdst ]; (N=0)
    πŸ”· JC Rdst
    • Jump if negative
    • If (C=1): PC ←R[ Rdst ]; (C=0)
    πŸ”Ά JMP Rdst
    • Jump
    • PC ←R[ 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

🧱 Design


πŸ‘‘ Contributors


khaled Farahat


Adham Ali


Mohamed Walid


Eslam Ashraf

πŸ”’ License

Note: This software is licensed under MIT License, See License for more information Β©Adham Ali.