{"id":23340277,"url":"https://github.com/liu42/processor","last_synced_at":"2026-02-27T15:13:52.188Z","repository":{"id":250975986,"uuid":"835823638","full_name":"LIU42/Processor","owner":"LIU42","description":"《计算机组成原理》课程设计，基于 MIPS 的流水线 CPU 系统设计。","archived":false,"fork":false,"pushed_at":"2024-12-17T04:08:30.000Z","size":100,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-13T17:17:40.741Z","etag":null,"topics":["architecture","computer-architecture","course-project","cpu","fpga","homework-project","mips","mips-architecture","mips-processor","pipeline","verilog"],"latest_commit_sha":null,"homepage":"","language":"Verilog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LIU42.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-30T15:45:34.000Z","updated_at":"2025-01-01T10:14:36.000Z","dependencies_parsed_at":"2024-11-23T18:36:04.297Z","dependency_job_id":null,"html_url":"https://github.com/LIU42/Processor","commit_stats":null,"previous_names":["liu42/pipeline","liu42/processor"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LIU42%2FProcessor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LIU42%2FProcessor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LIU42%2FProcessor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LIU42%2FProcessor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LIU42","download_url":"https://codeload.github.com/LIU42/Processor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247675618,"owners_count":20977376,"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":["architecture","computer-architecture","course-project","cpu","fpga","homework-project","mips","mips-architecture","mips-processor","pipeline","verilog"],"created_at":"2024-12-21T04:21:00.523Z","updated_at":"2025-11-05T21:03:40.045Z","avatar_url":"https://github.com/LIU42.png","language":"Verilog","readme":"# Processor 流水线处理器\n\n*\u003cu\u003ev1.1.0 新变化：修改所有控制信号为独热编码，同时优化源代码。\u003c/u\u003e*\n\n## 项目简介\n\n本项目为《计算机组成原理》课程设计，采用 Verilog 语言，实现了一个基于 MIPS 五级流水线的 CPU 架构，且具有数据旁路机制解决数据冲突，处理器总体结构框图如下：\n\n\u003cimg title=\"\" src=\"Processor.res/img/structure.jpg\" alt=\"\" style=\"zoom:67%;\"\u003e\n\n### 指令集\n\n本项目基于 MIPS 指令集，实现了 39 种不同的指令，指令的格式和编码与 MIPS 指令集保持一致。\n\n| 汇编指令             | 指令码                                     | 功能描述                                          |\n|:----------------:|:---------------------------------------:|:---------------------------------------------:|\n| add Rd, Rs, Rt   | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|100000       | RF[Rd] = RF[Rs] + RF[Rt]                      |\n| and Rd, Rs, Rt   | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|100100       | RF[Rd] = RF[Rs] \u0026 RF[Rt]                      |\n| jr Rs            | 000000\\|Rs\\|00000\\|00000\\|00000\\|001000 | PC = RF[Rs]                                   |\n| mfhi Rd          | 000000\\|00000\\|00000\\|Rd\\|00000\\|010000 | RF[Rd] = HI                                   |\n| mflo Rd          | 000000\\|00000\\|00000\\|Rd\\|00000\\|010010 | RF[Rd] = LO                                   |\n| mthi Rs          | 000000\\|Rs\\|00000\\|00000\\|00000\\|010001 | HI = RF[Rs]                                   |\n| mtlo Rs          | 000000\\|Rs\\|00000\\|00000\\|00000\\|010011 | LO = RF[Rs]                                   |\n| mult Rs, Rt      | 000000\\|Rs\\|Rt\\|00000\\|00000\\|011000    | HI \\| LO = RF[Rs] * RF[Rt]                    |\n| nor Rd, Rs, Rt   | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|100111       | RF[Rd] = ~(RF[Rs] \\| RF[Rt])                  |\n| or Rd, Rs, Rt    | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|100101       | RF[Rd] = RF[Rs] \\| RF[Rt]                     |\n| sll Rd, Rt, sa   | 000000\\|00000\\|Rt\\|Rd\\|sa\\|100111       | RF[Rd] = RF[Rt] \u003c\u003c sa                         |\n| sllv Rd, Rt, Rs  | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|000100       | RF[Rd] = RF[Rt] \u003c\u003c RF[Rs]                     |\n| slt Rd, Rs, Rt   | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|101010       | RF[Rd] = (RF[Rs] \u003c RF[Rt]) ? 1 : 0            |\n| sra Rd, Rt, sa   | 000000\\|00000\\|Rt\\|Rd\\|sa\\|000011       | RF[Rd] = RF[Rt] \u003e\u003e\u003e sa                        |\n| srav Rd, Rt, Rs  | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|000111       | RF[Rd] = RF[Rt] \u003e\u003e\u003e RF[Rs]                    |\n| srl Rd, Rt, sa   | 000000\\|00000\\|Rt\\|Rd\\|sa\\|000010       | RF[Rd] = RF[Rt] \u003e\u003e sa                         |\n| srlv Rd, Rt, Rs  | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|000110       | RF[Rd] = RF[Rt] \u003e\u003e RF[Rs]                     |\n| sub Rd, Rs, Rt   | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|100010       | RF[Rd] = RF[Rs] - RF[Rt]                      |\n| xor Rd, Rs, Rt   | 000000\\|Rs\\|Rt\\|Rd\\|00000\\|100110       | RF[Rd] = RF[Rs] ^ RF[Rt]                      |\n| addi Rt, Rs, imm | 001000\\|Rs\\|Rt\\|imm                     | RF[Rt] = RF[Rs] + imm                         |\n| andi Rt, Rs, imm | 001100\\|Rs\\|Rt\\|imm                     | RF[Rt] = RF[Rs] \u0026 imm                         |\n| beq Rs, Rt, imm  | 000100\\|Rs\\|Rt\\|imm                     | if RF[Rs] == RF[Rt]: PC = PC + imm \u003c\u003c 2       |\n| bgez Rs, imm     | 000001\\|Rs\\|00001\\|imm                  | if RF[Rs] \u003e= 0: PC = PC + imm \u003c\u003c 2            |\n| bgtz Rs, imm     | 000111\\|Rs\\|00000\\|imm                  | if RF[Rs] \u003e 0: PC = PC + imm \u003c\u003c 2             |\n| blez Rs, imm     | 000110\\|Rs\\|00000\\|imm                  | if RF[Rs] \u003c= 0: PC = PC + imm \u003c\u003c 2            |\n| bltz Rs, imm     | 000001\\|Rs\\|00000\\|imm                  | if RF[Rs] \u003c 0: PC = PC + imm \u003c\u003c 2             |\n| bne Rs, Rt, imm  | 000101\\|Rs\\|Rt\\|imm                     | if RF[Rs] != RF[Rt]: PC = PC + imm \u003c\u003c 2       |\n| lb Rt, imm(Rs)   | 100000\\|Rs\\|Rt\\|imm                     | RF[Rt] = MEM[RF[Rs] + imm]                    |\n| lh Rt, imm(Rs)   | 100001\\|Rs\\|Rt\\|imm                     | RF[Rt] = MEM[RF[Rs] + imm]                    |\n| lui Rt, imm      | 001111\\|Rs\\|Rt\\|imm                     | RF[Rt] = imm \u003c\u003c 16 \\| 0x0000                  |\n| lw Rt, imm(Rs)   | 100011\\|Rs\\|Rt\\|imm                     | RF[Rt] = MEM[RF[Rs] + imm]                    |\n| ori Rt, Rs, imm  | 001101\\|Rs\\|Rt\\|imm                     | RF[Rt] = RF[Rs] \\| imm                        |\n| sb Rt, imm(Rs)   | 101000\\|Rs\\|Rt\\|imm                     | MEM[RF[Rs] + imm] = RF[Rt]                    |\n| sh Rt, imm(Rs)   | 101001\\|Rs\\|Rt\\|imm                     | MEM[RF[Rs] + imm] = RF[Rt]                    |\n| slti Rt, Rs, imm | 001010\\|Rs\\|Rt\\|imm                     | RF[Rt] = (RF[Rs] \u003c imm) ? 1 : 0               |\n| sw Rt, imm(Rs)   | 101011\\|Rs\\|Rt\\|imm                     | MEM[RF[Rs] + imm] = RF[Rt]                    |\n| xori Rt, Rs, imm | 001110\\|Rs\\|Rt\\|imm                     | RF[Rt] = RF[Rs] ^ imm                         |\n| j imm            | 000010\\|imm                             | PC = PC[31:28] \\| imm \u003c\u003c 2                    |\n| jal imm          | 000011\\|imm                             | RF[$ra] = PC + 4;  PC = PC[31:28] \\| imm \u003c\u003c 2 |\n\n### 算术逻辑单元 ALU\n\nALU 模块由一个加法器、一个乘法器和一个移位器构成，实现 12 种不同的运算，控制信号采用独热编码。\n\n| 运算操作名称 | 控制信号编码 | 运算操作名称   | 控制信号编码 |\n|:------:|:------:|:--------:|:------:|\n| 加法     | [0]    | 按位或非     | [6]    |\n| 减法     | [1]    | 逻辑左移     | [7]    |\n| 小于条件设置 | [2]    | 逻辑右移     | [8]    |\n| 按位与    | [3]    | 算术右移     | [9]    |\n| 按位或    | [4]    | 立即数写入高半字 | [10]   |\n| 按位异或   | [5]    | 乘法       | [11]   |\n\n### 寄存器堆\n\n寄存器堆内部共有 32 个通用寄存器，其中零号寄存器的值被硬编码为零，用于提供常数零。寄存器堆模块共有两个读端口用于同时读取两个操作数、一个写端口用于数据的写回以及两个测试读端口用于展示程序运行状态。\n\n### 数据 RAM 存储器\n\n- 数据 RAM 存储器共有 4KB 的存储空间，且内存按字节编址。\n- 基于 Xilinx 提供的 RAM 双端口存储器 IP 核构建，由 4 个 1024 × 8bit 的 RAM 作位拓展组合而成。\n- 支持 8 位（字节）、16 位（半字）、32 位（字）数据的读写。\n- 不同位数数据读写的内存地址需要满足整数边界的要求。\n- 双端口分别用于正常数据读写和测试读数据。\n\n### 指令译码器\n\n指令译码器根据指令的格式进行匹配，生成所实现的所有指令的独热编码，组合得到 CPU 内部各个模块所需的控制信号。\n\n| 控制信号           | 描述                                                                                                  |\n|:--------------:|:--------------------------------------------------------------------------------------------------- |\n| jump_ctrl[8:0] | 9 种不同的分支跳转指令独热编码                                                                                    |\n| alu_ctrl[11:0] | ALU 模块控制信号                                                                                          |\n| alu_c1         | ALU 源操作数 1 控制信号：\u003cbr/\u003e取 0 表示来自 Rs 寄存器值\u003cbr/\u003e取 1 表示来自指令 sa 段的值                                         |\n| alu_c2         | ALU 源操作数 2 控制信号：\u003cbr/\u003e取 0 表示来自 Rt 寄存器值 \u003cbr/\u003e取 1 表示来自指令中的 16 位立即数                                     |\n| mem_ren[2:0]   | 数据 RAM 模块读使能信号独热编码：\u003cbr/\u003e[0] 表示读 8 位数据\u003cbr/\u003e[1] 表示读 16 位数据\u003cbr/\u003e[2] 表示读 32 位数据                         |\n| mem_wen[2:0]   | 数据 RAM 模块写使能信号独热编码：\u003cbr/\u003e[0] 表示写 8 位数据\u003cbr/\u003e[1] 表示写 16 位数据\u003cbr/\u003e[2] 表示写 32 位数据                         |\n| wb_en          | 写回使能信号：\u003cbr/\u003e取 0 表示不需要写回 \u003cbr/\u003e取 1 表示需要写回                                                             |\n| wb_addr[4:0]   | 写回的目的寄存器地址                                                                                          |\n| hi_ctrl[2:0]   | 专用寄存器 HI 控制信号独热编码：\u003cbr/\u003e[0] 表示需要读 HI 寄存器\u003cbr/\u003e[1] 表示需要向 HI 寄存器写入某个通用寄存器值\u003cbr/\u003e[2] 表示需要向 HI 寄存器写入乘法运算结果 |\n| lo_ctrl[2:0]   | 专用寄存器 LO 控制信号独热编码：\u003cbr/\u003e[0] 表示需要读 LO 寄存器\u003cbr/\u003e[1] 表示需要向 LO 寄存器写入某个通用寄存器值\u003cbr/\u003e[2] 表示需要向 LO 寄存器写入乘法运算结果 |\n\n### 数据冲突检测与数据旁路\n\n- CPU 内部维护一个队列用于记录前两条指令的写回寄存器地址。\n\n- 若源操作数寄存器地址位于队列种则存在数据冲突。\n\n- 根据寄存器地址在队列中的位置选择来自 ALU 或者 MEM 的旁路数据。\n\n- 读 RAM 指令的特殊性使得在其之后的指令若存在数据冲突需要插入空操作或进行指令调度，因为此类指令 ALU 计算的实际上是内存地址。\n\n## 使用说明\n\n本项目使用 Xilinx Vivado 2019.1 开发。\n\n- 本项目提供了 4 段测试程序，详见测试用例说明。\n\n- 可通过为 instrom 模块更换不同的 coe 文件更改当前 CPU 执行的程序，也可将自定义的测试程序写入新的 coe 文件加载到 instrom 模块中。\n\n- 根据需要修改 testbench.v 仿真文件，运行仿真后查看仿真波形图，也可综合实现后编程到 FPGA 板上，CPU 提供两个寄存器测试读端口和一个 RAM 测试读端口，可以利用它们检查程序在 CPU 内部的运行状态。\n\n### 测试用例说明\n\n测试程序 1 为指令功能测试，指令机器码与对应的汇编程序如下。\n\n```shell-session\n34010003  ori $1, $0, 3\n34020005  ori $2, $0, 5\n0C00001C  jal 28\n00000000  nop\n00200011  mthi $1\n00400013  mtlo $2\n00002010  mfhi $4\n00002812  mflo $5\nA0010000  sb $1, 0($0)\nA4020002  sh $2, 2($0)\nAC030004  sw $3, 4($0)\n80060000  lb $6, 0($0)\n84060002  lh $6, 2($0)\n8C060004  lw $6, 4($0)\n10220002  beq $1, $2, 2\n00000000  nop\n04210003  bgez $1, 3\n00000000  nop\n1C200007  bgtz $1, 7\n00000000  nop\n18200004  blez $1, 4\n00000000  nop\n0420FFFB  bltz $1, -5\n00000000  nop\n1422FFF9  bne $1, $2, -7\n00000000  nop\n08000064  j 100\n00000000  nop\n00221820  add $3, $1, $2\n20230001  addi $3, $1, 1\n00221824  and $3, $1, $2\n30230002  andi $3, $1, 2\n00221827  nor $3, $1, $2\n00221825  or $3, $1, $2\n00021867  sll $3, $2, 1\n00221804  sllv $3, $2, $1\n0022182A  slt $3, $1, $2\n28230002  slti $3, $1, 2\n00021843  sra $3, $2, 1\n00221807  srav $3, $2, $1\n00021882  srl $3, $2, 2\n00221806  srlv $3, $2, $1\n00221822  sub $3, $1, $2\n00221826  xor $3, $1, $2\n3823000C  xori $3, $1, 12\n00220018  mult $1, $2\n03E00008  jr $ra\n00000000  nop\n```\n\n测试程序 2 为阶乘求解，求解 5 的阶乘值，指令机器码与对应的汇编程序如下。\n\n```shell-session\n34010001  ori $1, $0, 1\n34020005  ori $2, $0, 5\n00220018  mult $1, $2\n00000812  mflo $1\n2042FFFF  addi $2, $2, -1\n1C40FFFC  bgtz $2, -4\n00000000  nop\n```\n\n测试程序 3 为斐波那契数列求解，求解斐波那契数列的前 10 项，指令机器码与对应的汇编程序如下。\n\n```shell-session\n34010001  ori $1, $0, 1\n34020000  ori $2, $0, 0\n3403000A  ori $3, $0, 10\n00222020  add $4, $1, $2\n00011025  or $2, $0, $1\n00040825  or $1, $0, $4\n2063FFFF  addi $3, $3, -1\n1C60FFFB  bgtz $3, -5\n00000000  nop\n```\n\n测试程序 4 为冒泡排序算法，实现 RAM 中长度为 5 的数组排序，指令机器码与对应的汇编程序如下。\n\n```shell-session\n340B0054  ori $11, $0, 84\n340C0007  ori $12, $0, 7\n340DFFF1  ori $13, $0, -15\n340E0015  ori $14, $0, 21\n340FFFFA  ori $15, $0, -6\nAC0B0000  sw $11, 0($0)\nAC0C0004  sw $12, 4($0)\nAC0D0008  sw $13, 8($0)\nAC0E000C  sw $14, 12($0)\nAC0F0010  sw $15, 16($0)\n34010000  ori $1, $0, 0\n34020010  ori $2, $0, 16\n34030000  ori $3, $0, 0\n00412022  sub $4, $2, $1\n8C650000  lw $5, 0($3)\n8C660004  lw $6, 4($3)\n00000000  nop\n00C5382A  slt $7, $6, $5\n10E00003  beq $7, $0, 3\n00000000  nop\nAC660000  sw $6, 0($3)\nAC650004  sw $5, 4($3)\n20630004  addi $3, $3, 4\n1464FFF6  bne $3, $4, -10\n00000000  nop\n20210004  addi $1, $1, 4\n1422FFF1  bne $1, $2, -15\n00000000  nop\n```\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliu42%2Fprocessor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliu42%2Fprocessor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliu42%2Fprocessor/lists"}