- Notifications
You must be signed in to change notification settings - Fork4
💻 A 5-stage pipeline MIPS CPU implementation in Verilog.
License
skyzh/mips-cpu
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
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 | 5-stage pipeline simulator | C++ |
RISC-V v2 | dynamic scheduling simulator Tomasulo + Speculation | C++ |
MIPS | 5-stage pipeline simulator | Haskell |
MIPS | 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.
signals and circuit logic
pc''=if take_branchthen branch_pcelse next_pc
assign ex_pc= take_branch ? branch_pc : next_pc;
stage input
-- use stage reg data typedataID_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))
// feed signals directlymoduleExecute(input [`OP] alu_op,input [`WORD] alu_src1,input [`WORD] alu_src2,input [`OP] id_opcode,input [`WORD] id_pc, ...
cycle on clock
-- return data from this cyclecpu_cycle::Registers->Registersnext_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
// eventsalways @ (negedge clk)beginif (!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;endend
stage with multiple outputs
-- use tupleout_id_stall=snd stage_id_outstage_id_regs=fst stage_id_out
// use signals directlyInstDecode instDecode ( ... (stage regs) .stall (out_id_stall), ... (other modules));
decode helper
-- defined as functionsextMode::Word32->BoolextMode0x0C=FalseextMode0x0D=FalseextMode0x0E=FalseextMode0x24=FalseextMode0x25=FalseextMode _=True
moduleExtMode(input [5:0] opcode,outputreg signExt);always @ (opcode)begincase (opcode)6'h0c: signExt=0;6'h0d: signExt=0;6'h0e: signExt=0;6'h24: signExt=0;6'h25: signExt=0;default: signExt=1;endcaseendendmodule
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.
Pipelined Processor (Chinese)Single-Cycle Processor (Chinese)