type
status
date
slug
summary
tags
category
icon
password
断断续续把一生一芯推进到了实现单周期,吸取上次没有进行记录,导致停止一段时间工作后,再回来忘记了哪里有 Bug,被迫重新开始的教训,这次把实现的模块,接口都进行记录,以供之后参考。

架构设计

为了方便后续划分流水,按照经典的五级流水线对单周期处理器进行模块划分。分别是取指、译码、执行、访存、写回五个单元。除此之外还有一个寄存器组。总体架构及布线如图所示:
notion image

模块设计

本节介绍各个模块的功能和输入输出端口设计。

寄存器组

寄存器组由 32 个 64 位寄存器构成,提供两个异步读端口和一个同步写端口。可以在一个周期读取两个操作数并进行一次写回操作。表中的“寄存器 1/2 读地址”和“寄存器 1/2 读数据”是指操作数 1 和操作数 2 对寄存器的要求,而不是寄存器编号。
端口名
位宽
input/output
含义
clk
1
input
工作时钟
rst
1
input
复位信号
raddr1
5
input
寄存器 1 读地址
raddr2
5
input
寄存器 1 读地址
wen
1
input
寄存器写使能
waddr
5
input
寄存器写地址
wdata
64
input
寄存器写数据
rdata1
64
output
寄存器 1 读数据
rdata2
64
output
寄存器 2 读数据
单击展开查看实现代码

取指

取指单元的主要工作是从存储中读取指令。取指单元由 PC(程序计数器) 和 IR(指令寄存器)组成

PC - 程序计数器

PC 是一个寄存器,负责指示程序的运行位置,输出当前指令存放的地址,复位值为 0x80000000。PC 值会被送入存储器。
端口名
位宽
input/output
含义
clk
1
input
工作时钟
rst
1
input
复位信号
pc_d
64
input
上周期 PC 地址
jump_flag
1
input
跳转控制信号
jump_addr
64
input
跳转地址
pc
64
output
当前 PC 地址
单击展开查看实现代码

IR - 指令寄存器

IR 是一个寄存器,接收存储器的输出,并从存储器中取出当前 PC 对应的指令输出,屏蔽掉多余的高字节的信息并输出指令。
端口名
位宽
input/output
含义
clk
1
input
工作时钟
rst
1
input
复位信号
pc
64
input
当前 PC 地址
inst
64
output
指令
单击展开查看实现代码

译码

译码单元接收前级取指模块的输出,进行译码,生成各个部件的控制信号和传向后级的源操作数。译码单元是一个组合逻辑单元。
端口名
位宽
input/output
含义
inst
64
input
指令
pc
64
input
PC 地址
rdata1
64
input
寄存器 1 读数据
rdata2
64
input
寄存器 1 读数据
raddr1
5
output
寄存器 1 读地址
raddr2
5
output
寄存器 2 读地址
waddr
5
output
寄存器写地址
wen
1
output
寄存器写使能
jr_flag
1
output
JALR 指令信号
j_flag
1
output
J 型指令信号
br_flag
1
output
分支指令信号
mem_flag
1
output
访存信号
mem_mask
2
output
访存掩码
mem_wdata
64
output
访存写数据
imm_ex
64
output
符号位拓展的立即数
src1
64
output
源操作数 1
src2
64
output
源操作数 2
alu_op
14
output
alu 执行的操作类型
bsrc1
64
output
分支指令源操作数 1
bsrc2
64
output
分支指令源操作数 2
branch_op
14
output
alu 执行的操作类型
  1. alu_op 是一个 19 位的独热码,为执行单元的 alu 指示操作类型,编码如下,其中 rv64 是标志指令是否为 rv64 指令: {rv64, add, sub, slt, sltu, and, or, xor, sll, srl, sra, mul, mulh, mulhsu, mulhu, div, divu, rem, remu}
  1. branch_op 与 alu_op 类似,是一个 6 位的独热码,为分支控制单元指示操作类型,编码如下: {beq, bge, bgeu, blt, bltu, bne}
  1. mem_mask 为访存写入时的掩码,宽度为 3 位,最高位指示访存类型。
      • mem_mask[3]: 0, load; 1, store;
      • mem_mask[2]: 0, 无符号拓展; 1, 符号拓展;
      • mem_mask[1:0]: 00, 写入一字节; 01, 写入两字节; 10, 写入四字节; 11, 写入八字节。
单击展开查看实现代码

执行

执行单元有一个 alu(算术逻辑单元)和一个分支控制单元构成,主要负责接收源操作数并进行操作类型判断,得出结果后将执行结果送入后级,是组合逻辑单元

alu

alu 主要负责处理逻辑和算术运算。
端口名
位宽
input/output
含义
alu_op
14
input
alu 执行的操作类型
src1
64
input
源操作数 1
src2
64
input
源操作数 2
alu_result
64
output
alu 计算结果
单击展开查看实现代码

分支控制

分支控制单元为一个 32 位的比较器,给出分支控制信号
端口名
位宽
input/output
含义
branch_op
14
input
分支操作类型
src1
64
input
源操作数 1
src2
64
input
源操作数 2
branch_flag
1
output
比较器计算结果
单击展开查看实现代码

访存

访存单元也设计成一个寄存器,接收 alu 的输出和译码产生的 mem_flag 信号,执行 load/store 指令
端口名
位宽
input/output
含义
mem_flag
4
input
alu 执行的操作类型
mem_addr
64
input
访存地址
mem_wdata
64
input
store 指令数据
mem_rdata
64
output
load 指令数据
单击展开查看实现代码
chipsalliance sv-tests 初探RISC-V Spike 代码分析
Loading...