Triumph core的TOP记录链接:https://blog.csdn.net/qq_39815222/article/details/111386853
作为鄙人处理器设计生涯的开山之作,究竟是搞一款靓绝全世界,让某里、某为、某通等汗颜的爆款,还是码一个麻雀虽小五脏俱全,或者说是一个及其简陋的LOW款呢?
经过短暂的思考后,笔者毫不犹豫的选择了后者。
1. 版本记录
- V1.0版本:
1.0版本实现了CPU的从无到有的突破,仿真工具为vivado,仿真成功的测试用例为斐波拉切数列
- V1.1版本:
1.1版本实现了仿真工具从vivado到xcelium的移植,完善了目录结构,搭建了makefile运行脚本,使用gcc工具将测试文件编译成二进制文件,并搭建testbench完整的数据通路,测试用例依旧采用斐波拉切数列。
- V1.2版本:
1.2版本将实现所有的rv32I指令,同时优化硬件代码
- V1.3版本:
1.3版本实现控制状态寄存器和6条CSR指令
- V1.4版本:
1.4版本实现4条特权指令和4条伪指令
2. 设计部分
1 处理器架构
- 流水线结构
该版本主要实现的是一款四级流水线结构,分别未取指、译码、执行、写回四个阶段。
流水线详见文章:https://blog.csdn.net/qq_39815222/article/details/106969845
(一)取指
根据PC读出指令地址,根据地址从指令存储器中取出指令,并计算PC+4
(二)译码
- 作用
- 从指令中解析出指令类型信号和操作类型信号
- 根据指令类型信号,依次取出指令的相应位,并根据指令功能组合相关位,若beq指令的imm信号等
- 根据寄存器编号从寄存器文件中取值
- 编码特征
- 由于指令的类型较多,各种指令对应位的角色不一,因此可先取出opcode,根据opcode的值确定那种类型的指令
- 确定指令类型后,即可确定32bit指令各对应位的角色,可使用组合逻辑直接取出。
- 为尽量在一个周期内完成译码,1、2两部均可用组合逻辑电路实现,向寄存器文件取数时可使用时序电路
(三)执行
运算器对通用寄存器堆读出的操作数进行计算
(四)写回
将结果写回到通用寄存器堆
2 典型代码描述
- triumph_core
core的顶层模块
-
triumph_if_stage
取指模块
-
triumph_id_stage
译码模块,针对输入的指令提取对应的opcode、funt3、funct7,并针对这三个指令码确定指令的类型,需要进行的操作(ALU,FPU)
-
triumph_ex_stage
执行模块,所有指令的运算处理均由该模块进行。存储访问指令用ALU计算地址,算术逻辑指令用ALU执行运算,分支指令用ALU进行比较
-
triumph_wb_stage
写回模块,包括
3. 验证部分
1 验证环境
4. 工具链
5. FPGA仿真
1 仿真环境
本测试搭建了一个简单的SoC系统,包含triumph_core CPU核模块、sram_instr指令存储器模块、sram_data数据存储器模块、clk_gen时钟产生模块、1S定时器模块以及数码管显示模块。
- SoC_top
CPU核和相关外设的顶层模块
- triumph_core
设计详述篇中已阐述。
- sram_instr
指令存储器保存了CPU需要执行的指令数据,指令将在rst复位时写入到该模块中的寄存器中。该模块只可读。
- sram_data
数据存储器保存了CPU运行时产生的数据,该模块可读可写。
-
clk_gen
时钟分频模块,由于本设计中core的设计和一些外设驱动的设计时序要求不一,因此需要进行一部分异步时序的设计。
本模块将100Mhz时钟分频为50MHz和25MHz。
-
seg_screen
数码管驱动模块,四个7段数码管(加一个小数点)的驱动模块,
2 测试
- 测试代码:实现斐波拉挈数列
add x0,x0,x0
lw x4, 3(x0)
lw x5, 1(x0)
lw x6, 2(x0)
nop
nop
add x7,x5,x6
nop
nop
sw x6,1(x0)
sw x7,2(x0)
nop
nop
sub x4,x4,x1
nop
nop
bne x4,x0,-4
nop
nop
nop
bne x4,x7,-16
nop
- vivado仿真时序图
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/82483.html