
不到 1300 行 Verilog 代码跑起来的极简 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-gputiny-gpu 是一个极简 GPU 实现12 个 Verilog 文件、约 1300 行代码却真能执行矩阵乘法和矩阵加法内核。它把渲染、光栅化这些图形功能全部砍掉只留下指令集、多线程执行和内存访问这几块承重墙专门用来回答一个问题——GPU 架构到底是怎么转起来的。这篇文章不讲概念带你先把这个 GPU 仿真跑起来再顺着执行轨迹把它的内部一层层拆开。五分钟跑起来极简 GPU 仿真整个仿真链路只需要三样东西iverilog一个开源的 Verilog 编译器、cocotb用 Python 写的硬件测试框架、sv2v把 SystemVerilog 转成 Verilog 的转换器因为 iverilog 不直接吃.sv文件。按顺序装好它们再建一个构建目录# 安装 Verilog 编译器与 cocotb 仿真框架 brew install icarus-verilog pip3 install cocotb # 从 sv2v 官方 releases 下载预编译二进制并放入 PATH然后 mkdir build装完就开工。仓库用 Makefile 把转换源码 → 编译 → 仿真整条链串好了跑矩阵加法和矩阵乘法各只需一条命令# 矩阵加法内核8 个线程并行做 8 次元素相加 make test_matadd # 矩阵乘法内核4 个线程各算 2x2 矩阵的一个元素 make test_matmul跑完后去test/logs目录找日志文件里面按顺序记着初始数据内存、逐周期执行轨迹、最终数据内存。开头能看到输入的两个矩阵结尾就是算出来的结果矩阵。一次完整的 Verilog GPU 仿真到这一步就算成了。看执行轨迹亲眼看见 4 个线程并行计算先打开矩阵乘法的日志。这个 2x2 矩阵乘法内核一共发射 4 个线程每个线程负责结果矩阵里的一个格子线程自己用编号算出我负责第几行第几列然后沿着那个方向做点积最后把结果写回全局内存。轨迹日志的每一行就是一个时钟周期你能同时看到 4 个线程各自的当前指令、程序计数器 PC 和寄存器取值。这正是 SIMD 执行在硬件上的样子同一条指令作用在各自的数据上。区别来自每个线程寄存器堆里几个只读寄存器——%blockIdx、%blockDim、%threadIdx内核靠它们算出各自负责的地址。这种结构就是两级并行模型线程是最小执行单位若干线程打包成一个块BlockGPU 里的调度单元按块为单位分发工作。tiny-gpu 的取舍很明确——每个核心一次只处理一个块跑完才接下一个新块。这牺牲了一些吞吐量换来的是控制逻辑极其简单每一行轨迹你都能看懂。16 位指令到计算结果极简 ISA 与六阶段流水线打开黑盒先看指令集。tiny-gpu 一共只有 11 条指令每条固定 16 位按用途分四类每类一句话就能说清内存读写LDR/STR负责从全局内存搬数据进寄存器、再把寄存器写回去矩阵元素的每一次访问都走这里算术运算ADD、SUB、MUL、DIV由 ALU算术逻辑单元执行矩阵乘法的乘和加全靠它们比较与跳转CMP比较两个寄存器并把结果状态存起来BRnzp据此决定是否跳回别的行——矩阵乘法里k N的循环就是这么实现的立即数CONST把一个常量直接塞进寄存器不用碰内存。寄存器用 4 位编号总共 16 个前 13 个随便读写最后 3 个是只读的线程身份寄存器SIMD 的各自为政就靠它们。一条指令进来后走的是一条六站装配线FETCH取指按 PC 从程序内存取走 16 位指令DECODE译码解析出操作码和操作数变成控制信号REQUEST请求如果是内存指令向内存控制器发请求WAIT等待等外部内存应答——只有内存指令真的会停在这其他指令快速通过EXECUTE执行ALU 完成运算UPDATE更新结果写回寄存器堆。六站串行、一条指令走完再走下一条是刻意设计的先看清每一步在干什么后面谈流水优化才有对比。计算核心里有什么ALU、调度器与参数化线程数把视角拉到整机。一次内核启动的流程是内核代码装进程序内存数据装进数据内存设备控制寄存器里写入线程总数然后拉高 start 信号。之后由分发器把线程组织成块、派发给空闲的核心全部完成后回报 done。整台 GPU 由这几块组成设备控制寄存器存这次要发多少线程、分发器、可配置数量的计算核心默认 2 个、数据/程序内存各自的内存控制器负责按带宽节流请求并转交响应以及一个规划中的缓存。内存本身很小8 位地址意味着 256 行数据位宽 8 位、程序位宽 16 位。每个核心内部再往下拆取指器和译码器是全线程共享的一套而每个线程独享一个 ALU、一个 LSU负责内存请求的收发、一个寄存器堆和一个 PC。关键设计在于线程数是参数THREADS_PER_BLOCK默认 4——改一个参数就换一种核心规格而不是重新画电路这让同一个设计可以拿来对比不同并行度。核心里只有一个调度器它按块串行地驱动所有线程同步步进。这就是前文说的取舍牺牲部分吞吐量换硬件极简恰好是学 GPU 架构教程式理解的最好切面。从能跑到更快极简 GPU 的六条改造清单读到这里你已经知道它缺什么了。生产级 GPU 的优化大致落在这六个方向每一条都是这个项目留出的练手空间性能侧多级缓存把单层缓存扩成 L1/L2 层次让高频数据离计算单元更近内存合并把相邻线程的连续地址请求合成一笔事务省掉重复寻址开销指令流水不等上一条完全跑完就放行下一条掩盖内存等待的空转。功能侧分支发散允许同一批线程跳到不同 PC放弃每条指令后必然汇合的假设共享内存给块内线程开一片公共存储交换中间结果不再绕道全局内存图形功能加一点基本的光栅化或纹理硬件让这台极简 GPU 也碰一碰图形负载。资源速查从 README 到调度器、译码器入口完整文档README.md架构、ISA、内核汇编与仿真说明最全的一手资料计算核心顶层src/core.sv看共享/独享资源如何接线矩阵乘法测试脚本test/test_matmul.py对照日志验证输出矩阵内核程序镜像gds/两个内核编译后的二进制都在这里想改调度策略入口在 src/scheduler.sv块级批处理逻辑就在这个文件里想加新指令从 src/decoder.sv 的译码控制信号入手。建议的动手路线先跑通仿真再改一个参数比如线程数重跑一次对比轨迹最后挑上面清单里的一条实现掉——这台不到 1300 行的极简 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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考