本项目实现了一个基于RISC指令集的向量处理器,专门用于矩阵乘法运算。支持2x2、4x4、8x8矩阵乘法仿真验证。
Simple-Vector-Processor/
├── README.md # 项目说明文档
├── Makefile # 编译构建文件(集成所有构建功能)
├── vector_engine.v # 顶层向量处理器模块
├── Decoder.v # 指令解码器
├── ICM.v # 指令缓存模块
├── Imm_Gen.v # 立即数生成器
├── MAC.v # 乘累加器
├── PC.v # 程序计数器
├── Scalar_DCM.v # 标量数据缓存
├── Scalar_RegFile.v # 标量寄存器文件
├── Vector_DCM.v # 向量数据缓存
├── Vector_RegFile.v # 向量寄存器文件
├── matrix_2x2_tb.v # 2x2矩阵乘法测试台
├── matrix_4x4_tb.v # 4x4矩阵乘法测试台
├── matrix_8x8_tb.v # 8x8矩阵乘法测试台
├── script/
│ └── matrix_parser.py # 矩阵数据生成脚本
└── data/
├── test_2x2_instruction_memory.txt # 2x2指令数据(由parser生成)
├── test_2x2_scalar_data_memory.txt # 2x2标量数据(由parser生成)
├── test_2x2_vector_data_memory.txt # 2x2向量数据(由parser生成)
├── test_4x4_instruction_memory.txt # 4x4指令数据(由parser生成)
├── test_4x4_scalar_data_memory.txt # 4x4标量数据(由parser生成)
├── test_4x4_vector_data_memory.txt # 4x4向量数据(由parser生成)
├── test_8x8_instruction_memory.txt # 8x8指令数据(由parser生成)
├── test_8x8_scalar_data_memory.txt # 8x8标量数据(由parser生成)
└── test_8x8_vector_data_memory.txt # 8x8向量数据(由parser生成)
- Icarus Verilog (iverilog): 用于Verilog仿真
- Python 3: 用于数据生成脚本
- Make: 用于构建管理
- Bash/Zsh: 用于执行脚本
sudo apt update
sudo apt install iverilog python3 gtkwave makesudo pacman -S iverilog python3 gtkwave make# 生成2x2矩阵测试数据
python3 script/matrix_parser.py --test-2x2
# 生成4x4矩阵测试数据
python3 script/matrix_parser.py --test-4x4
# 生成8x8矩阵测试数据
python3 script/matrix_parser.py --test-8x8
# 一次性生成所有测试数据
python3 script/matrix_parser.py --test-2x2
python3 script/matrix_parser.py --test-4x4
python3 script/matrix_parser.py --test-8x8# 完整的2x2矩阵乘法测试(自动生成数据、编译、仿真)
make matrix_2x2
# 完整的4x4矩阵乘法测试
make matrix_4x4
# 完整的8x8矩阵乘法测试
make matrix_8x8
# 查看所有可用命令
make help# 生成所有测试数据
make gen_data
# 单独编译某个测试
make build_2x2
make build_4x4
make build_8x8
# 单独运行仿真
make run_2x2
make run_4x4
make run_8x8
# 查看波形文件
make wave
# 清理生成文件
make cleanmake matrix_2x2 # 完整的2x2矩阵乘法测试流程
make matrix_4x4 # 完整的4x4矩阵乘法测试流程
make matrix_8x8 # 完整的8x8矩阵乘法测试流程
make custom_matrix # 自定义矩阵测试(需要指定INPUT参数)
make help # 显示详细的帮助信息# 编译命令
make build_2x2 # 只编译2x2测试
make build_4x4 # 只编译4x4测试
make build_8x8 # 只编译8x8测试
make build_custom # 编译自定义矩阵测试
# 运行命令
make run_2x2 # 只运行2x2仿真
make run_4x4 # 只运行4x4仿真
make run_8x8 # 只运行8x8仿真
make run_custom # 运行自定义矩阵仿真
# 数据准备命令
make setup_custom_data INPUT=文件名 # 准备自定义矩阵数据make gen_data # 生成所有测试数据
make wave # 查看波形文件(自动选择最新的)
make clean # 清理构建文件
make check # 语法检查
make stats # 显示设计统计信息
make info # 显示设计信息除了预定义的2x2、4x4、8x8测试,系统还支持从文件读取自定义矩阵进行测试。
创建一个文本文件,包含两个矩阵,格式如下:
MATRIX_A: [[矩阵A的数据]]
MATRIX_B: [[矩阵B的数据]]
example_matrix.txt (2x2矩阵):
MATRIX_A: [[1, 2], [3, 4]]
MATRIX_B: [[5, 6], [7, 8]]
期望结果: [[19, 22], [43, 50]]
example_3x3_matrix.txt (3x3矩阵):
MATRIX_A: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
MATRIX_B: [[2, 0, 1], [0, 3, 0], [1, 0, 2]]
期望结果: [[5, 6, 7], [14, 15, 16], [23, 24, 25]]
# 使用预定义的示例文件
make custom_matrix INPUT=example_matrix.txt
# 使用自己创建的文件
make custom_matrix INPUT=my_matrices.txt# 第一步:准备数据
make setup_custom_data INPUT=example_matrix.txt
# 第二步:编译
make build_custom
# 第三步:运行仿真
make run_custom
# 查看波形
make wave# 基本用法
python3 script/matrix_parser.py --input-file example_matrix.txt
# 指定输出前缀
python3 script/matrix_parser.py --input-file example_matrix.txt --output-prefix my_test
# 查看parser的所有选项
python3 script/matrix_parser.py --help- 数据格式: 矩阵必须使用JSON格式,注意逗号和括号
- 数据类型: 矩阵元素必须是整数(支持负数)
- 矩阵尺寸: 支持最大8x8矩阵,矩阵维度必须满足乘法要求(A的列数 = B的行数)
- 文件编码: 建议使用UTF-8编码
- 错误处理: 如果文件格式错误,系统会提供详细的错误信息
script/matrix_parser.py 支持多种输入方式:
# 测试模式(预定义矩阵)
python3 script/matrix_parser.py --test-2x2
python3 script/matrix_parser.py --test-3x3
python3 script/matrix_parser.py --test-4x4
python3 script/matrix_parser.py --test-8x8
# 文件输入模式
python3 script/matrix_parser.py --input-file my_matrices.txt
# 命令行矩阵输入模式
python3 script/matrix_parser.py --matrix-a '[[1,2],[3,4]]' --matrix-b '[[5,6],[7,8]]'
# 指定输出文件前缀
python3 script/matrix_parser.py --input-file my_matrices.txt --output-prefix custom_testmake clean # 清理构建文件 make check # 语法检查 make stats # 显示设计统计信息 make info # 显示设计信息
### 数据生成脚本使用
`script/matrix_parser.py`是核心数据生成脚本,可以通过Makefile调用:
```bash
# 使用Makefile生成数据(推荐)
make gen_data # 生成所有尺寸的测试数据
# 或直接使用脚本
python3 script/matrix_parser.py --test-2x2 # 生成2x2矩阵测试数据
python3 script/matrix_parser.py --test-4x4 # 生成4x4矩阵测试数据
python3 script/matrix_parser.py --test-8x8 # 生成8x8矩阵测试数据
- 指令内存文件 (
test_NxN_instruction_memory.txt): 包含矩阵乘法的向量指令序列 - 标量数据内存文件 (
test_NxN_scalar_data_memory.txt): 包含标量寄存器的初始值和常数 - 向量数据内存文件 (
test_NxN_vector_data_memory.txt): 包含矩阵A和B的向量化数据
- 矩阵A:
[[1,2],[3,4]] - 矩阵B:
[[1,0],[0,1]](单位矩阵) - 预期结果:
[[1,2],[3,4]](等于矩阵A)
- 矩阵A:
[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] - 矩阵B:
[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]](单位矩阵) - 预期结果: 等于矩阵A
- 矩阵A: 1到64的连续整数填充
- 矩阵B: 8x8单位矩阵
- 预期结果: 等于矩阵A
仿真完成后,程序会自动验证结果并输出:
PASSED: 计算结果正确FAILED: 计算结果有误
仿真日志会显示:
- 矩阵乘法的输入矩阵
- 期望的结果矩阵
- 实际计算的结果矩阵
- 每个元素的比较结果
# 1. 预定义矩阵测试(推荐)
make matrix_2x2 # 自动处理数据准备、编译、仿真
# 2. 自定义矩阵测试
make custom_matrix INPUT=example_matrix.txt # 一键式自定义矩阵测试
# 3. 手动分步流程
make gen_data # 生成预定义测试数据
make build_2x2 # 编译2x2测试
make run_2x2 # 运行2x2仿真
make wave # 查看波形
# 4. 自定义矩阵分步流程
make setup_custom_data INPUT=my_matrix.txt # 准备自定义数据
make build_custom # 编译自定义测试
make run_custom # 运行自定义仿真
# 5. 批量测试所有尺寸
make matrix_2x2 && make matrix_4x4 && make matrix_8x8
# 6. 清理和重新开始
make clean # 清理文件
make matrix_4x4 # 重新测试- 向量寄存器: 16个128位向量寄存器,每个可存储8个16位元素
- 标量寄存器: 16个16位标量寄存器
- 向量配置寄存器(R15): 控制向量操作的配置参数
VLEN[15:13]: 向量长度-1 (0=1元素, 1=2元素, ..., 7=8元素)VSTR[12:10]: 向量步长-1 (0=步长1, 1=步长2, ..., 7=步长8)VSHIFT[9:8]: 用于截断,便于计算定点数VMSK[7:0]: 向量掩码 (8位,每位对应一个向量元素)
- Vector Chaining: 向量链式处理,支持连续向量操作之间的直接数据传递
- 指令集: 支持向量加载、存储、乘累加等操作
- 存储器: 指令缓存、标量数据缓存、向量数据缓存
Vector Chaining是现代向量处理器的重要特性,允许一个向量功能单元的输出立即作为另一个向量功能单元的输入,最小化连续操作之间的延迟。
- 自动检测: 硬件自动检测连续向量操作之间的寄存器依赖关系
- 前向数据路径: 当检测到依赖时,直接使用前一条指令的计算结果,跳过寄存器写入/读取
- 无延迟传输: 消除连续向量操作之间的pipeline bubble
在矩阵乘法中的典型Vector Chaining序列:
VLOAD v1, [addr] # 加载矩阵行
VMAC v15, r2, v1 # 立即使用v1进行乘累加 ← Vector Chaining
VMAC v15, r3, v1 # 再次使用v1 ← Vector Chaining
VSTORE [addr], v15 # 立即使用v15的结果 ← Vector Chaining
Vector Chaining显著提高了向量操作的吞吐量,特别是在密集的矩阵运算中,可以减少多达50%的寄存器访问延迟。
采用行向量×列向量的方式实现矩阵乘法:
- 配置R15寄存器设置向量长度、步长和掩码
- 逐行加载矩阵A的行向量
- 逐列加载矩阵B的列向量
- 使用向量乘累加指令计算点积(支持向量掩码)
- 将结果存储到向量寄存器
- 最终结果写回存储器
- 向量长度控制: 支持1-8个元素的向量操作
- 向量步长: 支持非连续内存访问模式
- 向量掩码: 选择性启用/禁用特定向量元素
- Stripmining支持: 当VLEN超过最大长度时自动分块处理
支持的主要指令:
VLOAD: 向量加载指令(支持步长访问)VSTORE: 向量存储指令(支持步长访问)VMAC: 向量乘累加指令(支持向量掩码)LOAD/STORE: 标量加载存储指令MOV: 立即数移动指令(用于配置R15)NOP: 空操作指令
# 配置向量长度=4, 步长=1, 掩码=0xFF
MOV R15, 0x6FFC, 0 # VLEN=3(4元素), VSTR=0(步长1), VMSK=0xFF
# 配置向量长度=2, 步长=2, 掩码=0x0F
MOV R15, 0x43C0, 0 # VLEN=1(2元素), VSTR=1(步长2), VMSK=0x0FA: Vector Chaining功能在所有矩阵乘法测试中自动启用。可以通过以下方式验证:
观察VCD波形:
make matrix_2x2
make wave
# 在波形中查看vector_chaining_enable信号A:
- 创建包含矩阵的文本文件:
MATRIX_A: [[1, 2], [3, 4]] MATRIX_B: [[5, 6], [7, 8]] - 运行测试:
make custom_matrix INPUT=your_file.txt - 或分步操作:
make setup_custom_data INPUT=your_file.txt make build_custom make run_custom
A:
- 必须包含
MATRIX_A:和MATRIX_B:标记 - 矩阵使用JSON格式:
[[1, 2], [3, 4]] - 矩阵元素必须是整数
- 支持最大8x8矩阵
- 矩阵维度必须满足乘法要求(A的列数 = B的行数)
A: 请确保已安装iverilog。在Ubuntu/Debian上运行:sudo apt install iverilog
A: 确保使用Python 3,数据生成可以通过Makefile自动处理:make gen_data
A:
make matrix_2x2 # 运行仿真,自动生成VCD文件
make wave # 自动打开最新的波形文件
# 或手动打开: gtkwave matrix_2x2_tb.vcdA: 使用 make help 查看完整的命令列表和使用说明
A:
- 生成的测试数据在
data/目录下 - 当前使用的数据文件是根目录下的符号链接(
instruction_memory.txt等) - 每次运行不同尺寸的测试时,链接会自动更新指向对应的数据文件
创建包含矩阵的文本文件:
MATRIX_A: [[your_matrix_a]]
MATRIX_B: [[your_matrix_b]]
然后运行:make custom_matrix INPUT=your_file.txt
python3 script/matrix_parser.py --matrix-a '[[1,2],[3,4]]' --matrix-b '[[5,6],[7,8]]'如需修改预定义的测试矩阵,可以编辑script/matrix_parser.py中的矩阵定义:
# 在对应的测试函数中修改matrix_a和matrix_b
matrix_a = [[your_values]]
matrix_b = [[your_values]]- 可以调整时钟频率(修改测试台中的时钟周期)
- 优化指令序列(减少NOP指令)
- 改进向量寄存器的数据布局