
12 个 Verilog 文件、11 条指令30 分钟跑通 tiny-gpu 极简 GPU 实现【免费下载链接】tiny-gpuA minimal GPU design in Verilog to learn how GPUs work from the ground up项目地址: https://gitcode.com/GitHub_Trending/ti/tiny-gpu一块完整显卡的硬件代码动辄百万行tiny-gpu 只用 12 个 Verilog 文件、11 条指令就做出一台真能算矩阵乘法的极简 GPU。读完 src 目录下的全部源码、再敲一条仿真命令你就能看到内核从启动、调度、译码到访存等待的完整生命周期。 十分钟读完极简 GPU 源码先读哪 5 个文件仓库里信息量最大的文件是下面这 5 个建议先扫一遍再深入src/gpu.sv顶层模块端口定义、核心数与线程数默认参数都在这里src/core.sv计算核心六步指令流水的状态机主体src/decoder.sv指令译码器把 16 位指令拆成各线程控制信号test/test_matmul.py矩阵乘法测试内核机器码与校验逻辑都内联在此README.mdISA 表格与架构说明相当于项目说明书跟一次矩阵加法GPU 内核的完整生命周期以仓库里的矩阵加法内核为例跟着数据从进内存到出结果走一遍。内核启动三次内存写入加一个 start 信号GPU 一次只执行一个内核。启动前测试脚本扮演驱动要做三件事把内核的 16 位指令流写入程序内存把矩阵 A、B 写入数据内存把线程总数写入设备控制寄存器 dcr。都就绪后拉起 start内核开始跑。数据内存是 256 行 × 8 位程序内存是 256 行 × 16 位两者物理分开。带宽也各自配置数据 4 通道程序 1 通道。这是为简化做的取舍。调度把线程按 4 个一组切块dispatcher 收到 start 后把线程总数按 4 个一组切成块依次交给空闲核心。默认 2 个核每个核一次只处理一个块做完才接下一个。全部块完成后 done 拉高内核结束。这种块串行、线程并行的策略牺牲了部分吞吐但硬件逻辑好推理适合学习。核心内的六步指令执行核心拿到块后状态机对每条指令循环六个步骤FETCH 从程序内存取指DECODE 把指令拆成控制信号遇 LDR/STR 时 REQUEST 发出访存请求WAIT 等响应EXECUTE 做 ALU 运算UPDATE 把结果写回寄存器与条件位。指令集一共 11 条NOP、BRnzp、CMP、ADD、SUB、MUL、DIV、LDR、STR、CONST、RET。每条固定 16 位寄存器用 4 位编号。R0–R12 是通用寄存器后 3 个只读寄存器存放 %blockIdx、%blockDim、%threadIdx这是 SIMD 的来源。整个内核长这样矩阵加法内核节选.threads 8 .data 0 1 2 3 4 5 6 7 ; 矩阵 A .data 0 1 2 3 4 5 6 7 ; 矩阵 B MUL R0, %blockIdx, %blockDim ADD R0, R0, %threadIdx ; i blockIdx*blockDim threadIdx CONST R1, #0 ; baseA CONST R2, #8 ; baseB CONST R3, #16 ; baseC ADD R4, R1, R0 LDR R4, R4 ; 取 A[i]8 个线程执行同一份指令流但各自的 %threadIdx 不同算出的地址就不同各取一个元素。这就是 SIMD 的实质硬件复制多份程序只有一份。线程内部同一条指令各算各的数据核心内部每个线程都有专属的 ALU、LSU、PC 和寄存器堆ALU 管算术LSU 管访存PC 管下一条指令地址寄存器堆放数据。PC 每条指令默认 1BRnzp 命中条件时跳到指定程序内存行循环和条件就是这么实现的。注意 tiny-gpu 假设块内所有线程每条指令执行后仍在同一 PC不处理独立分支仓库两个内核的分支也都写成了会汇合的形式。访存是最慢的一环请求经 LSU 到数据内存控制器按通道数节流响应回来线程才离开 WAIT。调度器要做的就是围绕这些异步等待安排执行。⚡ 复现极简 GPU 仿真环境、命令与日志解读环境准备iverilog、cocotb 与 sv2v仿真依赖三样工具Icarus Verilog 编译器 iverilog、cocotb 测试框架以及 sv2v。iverilog 原生不支持 .sv需要 sv2v 先把 SystemVerilog 转成 Verilog。brew install icarus-verilog pip3 install cocotb再从其 GitHub releases 页下载最新 sv2v 二进制解压后放入 PATH。然后克隆仓库git clone https://gitcode.com/GitHub_Trending/ti/tiny-gpu cd tiny-gpu mkdir build跑通矩阵加法测试make test_mataddMakefile 先用 sv2v 把 src 下 12 个文件逐个编译合并成 build/gpu.v再用 iverilog 编译最后跑 test/test_matadd.py 里的 cocotb 测试。顺利的话终端会输出日志测试以 8 个加法结果全部通过断言收尾。读懂执行轨迹日志运行完会在 test/logs 留下日志文件分三段初始数据内存快照、逐周期执行轨迹、最终数据内存快照。初始快照开头是矩阵 A 和 B最终快照 16–23 行是逐元素加法结果。trace 段逐周期记录每个核心中每个线程的状态当前 PC、指令、核心状态机、取指器状态、LSU 状态、16 个寄存器值。调试时挑一个线程的行逐行跟就能看清 PC 如何跳、寄存器如何变。 扩展入口想改 GPU 从哪些文件下手想调每核线程数或核心数量改 src/gpu.sv 里的 NUM_CORES、THREADS_PER_BLOCK 参数内核线程数需同步测试脚本效果是改变并行规模想新增一条指令在 src/decoder.sv 扩展译码再到 src/core.sv 对应状态机里补语义效果是指令集从 11 条变 12 条想提高访存带宽改 src/lsu.sv 的请求仲裁逻辑可以先尝试把相邻线程的相邻地址请求合并成一笔资源继续深入 GPU 架构的三个关键文件README.mdISA 表、架构说明与两个内核的汇编源码src/core.sv核心指令执行状态机全文值得逐行读test/test_matmul.py从机器码到结果断言完整演示一次仿真闭环跑仿真遇到问题或者对加缓存、流水线、warp 调度有想法欢迎到仓库 issue 区交流。【免费下载链接】tiny-gpuA minimal GPU design in Verilog to learn how GPUs work from the ground up项目地址: https://gitcode.com/GitHub_Trending/ti/tiny-gpu创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考