Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/skyzh/mips-cpu
💻 A 5-stage pipeline MIPS CPU implementation in Verilog.
https://github.com/skyzh/mips-cpu
computer-architecture cpu mips verilog
Last synced: 22 days ago
JSON representation
💻 A 5-stage pipeline MIPS CPU implementation in Verilog.
- Host: GitHub
- URL: https://github.com/skyzh/mips-cpu
- Owner: skyzh
- License: mit
- Created: 2020-04-22T13:33:28.000Z (almost 5 years ago)
- Default Branch: multi-cycle
- Last Pushed: 2020-07-05T10:27:47.000Z (over 4 years ago)
- Last Synced: 2024-11-11T02:41:56.146Z (3 months ago)
- Topics: computer-architecture, cpu, mips, verilog
- Language: Verilog
- Homepage:
- Size: 37.1 KB
- Stars: 28
- Watchers: 2
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-cs - @skyzh, 2020 Spring
README
# MIPS-CPU
A MIPS CPU in Verilog.
Making a MIPS CPU is a non-trivial task. But with the help of mips-simulator,
my previous project on describing circuit logic in functional programming language,
this project can be done easily by directly translating Haskell into Verilog.All CPU and CPU simulators I've made are listed below.
| | Technique | Implementation |
|---------------------------------------------------------------------|------------------------------------------------|----------------|
| [RISC-V v1](https://github.com/skyzh/RISCV-Simulator/tree/pipeline) | 5-stage pipeline simulator | C++ |
| [RISC-V v2](https://github.com/skyzh/RISCV-Simulator) | dynamic scheduling simulator
Tomasulo + Speculation | C++ |
| [MIPS](https://github.com/skyzh/mips-simulator) | 5-stage pipeline simulator | Haskell |
| [MIPS](https://github.com/skyzh/mips-cpu) | 5-stage pipeline CPU | Verilog |Variable naming and wire naming are nearly identical in Haskell version and Verilog version.
Here I compare some code snippets between Verilog and Haskell.## Circuit Logic in Haskell and Verilog
**signals and circuit logic**
```haskell
pc'' =
if take_branch then branch_pc
else next_pc
``````verilog
assign ex_pc = take_branch ?
branch_pc : next_pc;
```**stage input**
```haskell
-- use stage reg data typedata ID_EX_Reg = ID_EX_Reg {
id_alu_op :: Word32,
id_alu_src1 :: Word32,
id_alu_src2 :: Word32,
id_opcode :: Word32,
id_pc :: Word32,
...
}stageExecute :: ID_EX_Reg -> (EX_MEM_Reg, (Bool, Word32))
``````verilog
// feed signals directlymodule Execute(
input [`OP] alu_op,
input [`WORD] alu_src1,
input [`WORD] alu_src2,
input [`OP] id_opcode,
input [`WORD] id_pc,
...
```**cycle on clock**
```haskell
-- return data from this cyclecpu_cycle :: Registers -> Registers
next_regs = Registers new_rf
new_hi
new_lo
imem'
new_dmem
new_pc
next_if_id_reg
next_id_ex_reg
next_ex_mem_reg
next_mem_wb_reg
``````verilog
// eventsalways @ (negedge clk) begin
if (!out_id_stall) begin
stage_if_inst <= out_if_inst;
stage_if_pc <= out_if_pc;
stage_if_branch_taken <= 0;
pc <= out_if_next_pc;
end
end
```**stage with multiple outputs**
```haskell
-- use tupleout_id_stall = snd stage_id_out
stage_id_regs = fst stage_id_out
``````verilog
// use signals directlyInstDecode instDecode (
... (stage regs)
.stall (out_id_stall),
... (other modules)
);
```**decode helper**
```haskell
-- defined as functionsextMode :: Word32 -> Bool
extMode 0x0C = False
extMode 0x0D = False
extMode 0x0E = False
extMode 0x24 = False
extMode 0x25 = False
extMode _ = True
``````verilog
module ExtMode(
input [5:0] opcode,
output reg signExt);always @ (opcode) begin
case (opcode)
6'h0c: signExt = 0;
6'h0d: signExt = 0;
6'h0e: signExt = 0;
6'h24: signExt = 0;
6'h25: signExt = 0;
default: signExt = 1;
endcase
end
endmodule
```## Relationship
| Verilog | Haskell |
|--------------|---------------------------------------------------------------------------|
| ALU | aluRead in ALU |
| ALUOp | mapALUOp + isArithmeticOp in ALU |
| BranchOp | isBranchOp + branchRtVal = overrideRt in Branch |
| BranchOut | branchOut in Branch |
| ExtMode | extMode in ALU |
| Forward | Forward |
| IsShift | isShift in ALU |
| MemoryOp | memoryMode + memoryLoad + memoryStore + isMemoryOp + memoryMode in Memory |
| SignExt | signExt in ALU |
| ZeroExt | zeroExt in ALU |
| Execute | StageExecute |
| InstDecode | InstDecode |
| InstFetch | InstFetch |
| Memory | StageMem |
| WriteBack | embedded in CPU |
| CPU | CPU |
| RegisterFile | RegisterFile |
| DataMemory | dmem in Registers |
| InstMemory | imem in Registers |
| signals in CPU | StageReg |All signals in stage registers and in stage modules are exactly the same, except that:
* Stage with multiple outputs has multiple output signals in Verilog.
* In Verilog, forward module logic is located in CPU.
* In Verilog, memory is located, and operates in CPU. Memory stage sends signals out of the module.
* In Verilog, write back is a standalone stage.## Project Report
[Pipelined Processor (Chinese)](https://github.com/skyzh/mips-cpu/files/4628149/pipelined-processor.pdf)
[Single-Cycle Processor (Chinese)](https://github.com/skyzh/mips-cpu/files/4628151/single-cycle-processor.pdf)