{"id":13607771,"url":"https://github.com/skyzh/mips-cpu","last_synced_at":"2026-03-03T01:35:58.025Z","repository":{"id":85472421,"uuid":"257911006","full_name":"skyzh/mips-cpu","owner":"skyzh","description":"💻 A 5-stage pipeline MIPS CPU implementation in Verilog.","archived":false,"fork":false,"pushed_at":"2020-07-05T10:27:47.000Z","size":38,"stargazers_count":28,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"multi-cycle","last_synced_at":"2025-01-08T18:30:08.639Z","etag":null,"topics":["computer-architecture","cpu","mips","verilog"],"latest_commit_sha":null,"homepage":"","language":"Verilog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skyzh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-04-22T13:33:28.000Z","updated_at":"2024-12-30T12:13:49.000Z","dependencies_parsed_at":"2023-03-13T05:26:06.306Z","dependency_job_id":null,"html_url":"https://github.com/skyzh/mips-cpu","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skyzh%2Fmips-cpu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skyzh%2Fmips-cpu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skyzh%2Fmips-cpu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skyzh%2Fmips-cpu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skyzh","download_url":"https://codeload.github.com/skyzh/mips-cpu/tar.gz/refs/heads/multi-cycle","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240794917,"owners_count":19858719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computer-architecture","cpu","mips","verilog"],"created_at":"2024-08-01T19:01:21.488Z","updated_at":"2026-03-03T01:35:57.986Z","avatar_url":"https://github.com/skyzh.png","language":"Verilog","funding_links":[],"categories":["资源清单"],"sub_categories":["CS2306 (原 CS145) - 计算机系统结构实验"],"readme":"# MIPS-CPU\n\nA MIPS CPU in Verilog.\n\nMaking a MIPS CPU is a non-trivial task. But with the help of mips-simulator,\nmy previous project on describing circuit logic in functional programming language,\nthis project can be done easily by directly translating Haskell into Verilog.\n\n\nAll CPU and CPU simulators I've made are listed below.\n\n|                                                                     | Technique                                      | Implementation |\n|---------------------------------------------------------------------|------------------------------------------------|----------------|\n| [RISC-V v1](https://github.com/skyzh/RISCV-Simulator/tree/pipeline) | 5-stage pipeline  simulator                 | C++            |\n| [RISC-V v2](https://github.com/skyzh/RISCV-Simulator)               | dynamic scheduling simulator \u003cbr\u003e Tomasulo + Speculation | C++            |\n| [MIPS](https://github.com/skyzh/mips-simulator)                     | 5-stage pipeline  simulator                             | Haskell        |\n| [MIPS](https://github.com/skyzh/mips-cpu)                           | 5-stage pipeline CPU         | Verilog        |\n\n\nVariable naming and wire naming are nearly identical in Haskell version and Verilog version.\nHere I compare some code snippets between Verilog and Haskell.\n\n## Circuit Logic in Haskell and Verilog\n\n**signals and circuit logic**\n\n```haskell\npc'' = \n    if take_branch then branch_pc \n    else next_pc\n```\n\n```verilog\nassign ex_pc = take_branch ? \n    branch_pc : next_pc;\n```\n\n**stage input**\n\n```haskell\n-- use stage reg data type\n\ndata ID_EX_Reg = ID_EX_Reg {\n    id_alu_op :: Word32,\n    id_alu_src1 :: Word32,\n    id_alu_src2 :: Word32,\n    id_opcode :: Word32,\n    id_pc :: Word32,\n    ...\n    }\n\nstageExecute :: ID_EX_Reg -\u003e (EX_MEM_Reg, (Bool, Word32))\n```\n\n```verilog\n// feed signals directly\n\nmodule Execute(\n    input [`OP] alu_op,\n    input [`WORD] alu_src1,\n    input [`WORD] alu_src2,\n    input [`OP] id_opcode,\n    input [`WORD] id_pc,\n    ...\n```\n\n**cycle on clock**\n\n```haskell\n-- return data from this cycle\n\ncpu_cycle :: Registers -\u003e Registers\n\nnext_regs = Registers   new_rf\n                        new_hi\n                        new_lo\n                        imem'\n                        new_dmem\n                        new_pc\n                        next_if_id_reg\n                        next_id_ex_reg\n                        next_ex_mem_reg\n                        next_mem_wb_reg\n```\n\n```verilog\n// events\n\nalways @ (negedge clk) begin\n    if (!out_id_stall) begin\n        stage_if_inst \u003c= out_if_inst;\n        stage_if_pc \u003c= out_if_pc;\n        stage_if_branch_taken \u003c= 0;\n        pc \u003c= out_if_next_pc;\n    end\nend\n```\n\n**stage with multiple outputs**\n\n```haskell\n-- use tuple\n\nout_id_stall   = snd stage_id_out\nstage_id_regs  = fst stage_id_out\n```\n\n```verilog\n// use signals directly\n\nInstDecode instDecode (\n    ... (stage regs)\n    .stall (out_id_stall),\n    ... (other modules)\n);\n```\n\n**decode helper**\n\n```haskell\n-- defined as functions\n\nextMode :: Word32 -\u003e Bool\nextMode 0x0C = False\nextMode 0x0D = False\nextMode 0x0E = False\nextMode 0x24 = False\nextMode 0x25 = False\nextMode _    = True\n```\n\n```verilog\nmodule ExtMode(\n    input [5:0] opcode,\n    output reg signExt);\n\n    always @ (opcode) begin\n        case (opcode)\n            6'h0c: signExt = 0;\n            6'h0d: signExt = 0;\n            6'h0e: signExt = 0;\n            6'h24: signExt = 0;\n            6'h25: signExt = 0;\n            default: signExt = 1;\n        endcase\n    end\nendmodule\n```\n\n## Relationship\n\n| Verilog      | Haskell                                                                   |\n|--------------|---------------------------------------------------------------------------|\n| ALU          | aluRead in ALU                                                            |\n| ALUOp        | mapALUOp + isArithmeticOp in ALU                                          |\n| BranchOp     | isBranchOp + branchRtVal = overrideRt in Branch                           |\n| BranchOut    | branchOut in Branch                                                       |\n| ExtMode      | extMode in ALU                                                            |\n| Forward      | Forward                                                                   |\n| IsShift      | isShift in ALU                                                            |\n| MemoryOp     | memoryMode + memoryLoad + memoryStore + isMemoryOp + memoryMode in Memory |\n| SignExt      | signExt in ALU                                                            |\n| ZeroExt      | zeroExt in ALU                                                            |\n| Execute      | StageExecute                                                              |\n| InstDecode   | InstDecode                                                                |\n| InstFetch    | InstFetch                                                                 |\n| Memory       | StageMem                                                                  |\n| WriteBack    | embedded in CPU                                                           |\n| CPU          | CPU                                                                       |\n| RegisterFile | RegisterFile                                                              |\n| DataMemory   | dmem in Registers                                                         |\n| InstMemory   | imem in Registers                                                         |\n| signals in CPU   | StageReg                                                                  |\n\nAll signals in stage registers and in stage modules are exactly the same, except that:\n\n* Stage with multiple outputs has multiple output signals in Verilog.\n* In Verilog, forward module logic is located in CPU.\n* In Verilog, memory is located, and operates in CPU. Memory stage sends signals out of the module.\n* In Verilog, write back is a standalone stage.\n\n## Project Report\n\n[Pipelined Processor (Chinese)](https://github.com/skyzh/mips-cpu/files/4628149/pipelined-processor.pdf)\n[Single-Cycle Processor (Chinese)](https://github.com/skyzh/mips-cpu/files/4628151/single-cycle-processor.pdf)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskyzh%2Fmips-cpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskyzh%2Fmips-cpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskyzh%2Fmips-cpu/lists"}