利用SystemVerilog语言编写FPGA 实现picoMIPS并且能够进行仿射变换的计算
-
使用的软件及版本
- quartus II 13.1
- modelsim SE 10.4
- vscode
-
使用的语言
- systemVerilog
-
PC(Program Counter) : 程序计数器
- PC的主要功能是取memory中的数据。
- 输入: 时钟clk, 复位reset, 是否对输出加1(向下一个指令移动)PCincr
- 输出: PCout
- 实现文件: pc.sv
-
Prog( Program memory): 程序内存,存放指令
- 输入: address
- 输出: 指令
- 实现文件: prog.sv
-
Decoder: 解码器 : 用于解析指令给ALU使用
- 所需5个指令 所以需要3bits的操作数
- load : 加载数据到寄存器
- add : 加寄存器中的两个数字
- addI : 加立即数
- MULI : 乘立即数
- NOP : 什么也不干
- 输入: operation_code
- 输出: ALUFunc(add,mul),imm(ALU是否读取立即数),write(是否写入寄存器)
- 实现文件: decoder.sv
- 所需5个指令 所以需要3bits的操作数
-
Regs: 寄存器 : 主要功能是存储中间数据
- 输入:
- 两个输入地址
- 一个write写入标识
- 一个wdata写入数据
- 输出: 两个输出数据
- 实现文件: regs.sv
- 输入:
-
ALU: 逻辑计算单元
- ALU函数一共有三个
- ADD: 加法 10
- MUL: 乘法 11
- Always B : 永远输出B 00
- 输入: 有符号的a,b输入,ALUFunc
- 输出: result
- 实现文件: alu.sv
- ALU函数一共有三个
// 指令LOAD测试
10000100000000001 // LOAD %1 %0 1 加载数字1到1号寄存器
10001000000000010 // LOAD %2 &0 2 加载数字2到2号寄存器
// 测试加法
01001000100000000 // ADD %2 %1 %2 = %2+%1 加法 将2号和1号加起来给2号
// 测试加立即数
11001000000000011 //ADDI %2 %0 3 此时%2应该是6
00000000000000000 // NOP 清空
// 指令LOAD测试
00000000000000000 // NOP 清空
10000100000000001 // LOAD %1 %0 1 加载数字1到1号寄存器
00000000000000000 // NOP 清空
10001000000000010 // LOAD %2 &0 2 加载数字2到2号寄存器
// 测试加法
01001000100000000 // ADD %2 %1 %2 = %2+%1 加法 将2号和1号加起来给2号
// 测试加立即数
11001000000000011 //ADDI %2 %0 3 此时%2应该是6
// 测试乘法
11101000001100000 // MULI %2 %0 0.75 得出的结果应该是 4.5 00000100 只取整数部分
// 测试版本 只用于检测程序是否有效
// | x2 | | x1 |
// | y2 | = A * | y1 | + B
//
// A = | 0.75 0.5 | B = | 20 |
// | -0.5 0.75| | -20 | A与B是系数 是固定的,执行特定的仿射变换
//
// 指令LOAD测试
00000000000000000 // NOP 清空
10000100000000001 // LOAD %1 %0 0 加载sw到1号寄存器
00000000000000000 // NOP 清空
10001000000000010 // LOAD %2 &0 2 加载sw到2号寄存器
11101100101100000 //19960//MULI %3, %1, 0.75; // %3 = X1*0.75
11110001001000000 //1A240//MULI %4, %2, 0.5; // %4 = Y1*0.5
01001110000000000 //05C00//ADD %3, %4; //%3 = %3+%4
11110100111000000 //19AC0//MULI %5, %1, -0.5; //%5 = X1*(-0.5)
11111001001100000 //1B260//MULI %6, %2, 0.75; //%6 = Y1*0.75
01010111000000000 //06E00//ADD %5, %6; //%5 = %5+%6 目前为止%3 存 0.75 * x1 + 0.5*y1 %5 存 -0.5 * x1 + 0.75 * y1
11001101100010100 //15B14//ADDI %3, %3, 20; //%3 = %3+20 + 系数 B
11010110111101100 //16DEC//ADDI %5, %5, -20; //%5 = %5-20 + 系数 B
00000000000000000
- 去掉零号机寄存器减少操作 去掉后寄存器的数量并没有变化,大概是本来就没有用到被优化了吧
- 去掉加或者乘imm 直接去掉sv文件里面的ADDI与MULI指令, 毕竟这种写指令的方式浪费指令增加了ADDI与MULI 同时还增加了代码行数