萌新的RISC-V学习之再看计算机组成与设计大收获总六
我们在进行设计的时候首先要明白一点 就是 确定我们的设计所需要的
指令的大小和 地址的大小 指令集是32位的 而 地址则一般更多的是64位 数据也是64位
PC与指令寄存器之间的关系
PC是用来保存当前指令的地址。假设地址是000000
然后所有的指令都是存在了指令存储器中 那就是为什么叫instruction memory PC
其实指令早就写好了 存在了指令寄存器中 PC只是一个地址的媒介告诉我们从指令寄存器的哪里开始取出这条指令 为什么下一条指令是PC+4 也就是说明因为 我们的指令是32位 4字节 加4 就是正好换成下一个指令
PC+1就是1字节 PC+2 就是2字节
寄存器堆由32个通用寄存器构成
我们对寄存器进行操作 指令的实现有多种多样的
R型指令 读取 一个数据需要一个指定的”寄存器号“
还需要一个从寄存器堆中读出的数据
写入 那就需要 寄存器堆能够接收一个指定的”寄存器号“
还需要一个准备写入的数据
其实寄存器堆也是一样的 ,数据存在了寄存器堆中,寄存器根据寄存器号 选择相应的数据
所以对此我们总共需要3个寄存器编号和一个数据(写入的数据) 还有2个输出数据
寄存器编号是5位的 ,还有一个写入数据是64位
数据输入和数据输出总线都是64位宽的
注: 寄存器在进行写操作的时候 ,必须明确使得写使能信号有效。
对于此处的ALU模块 是用来 读入2个64位宽的输入,产生一个64的输出 还有一个1位的输出指示其结果是否为0
上面是进行简单的R型指令 可以完成
下面所用的指令 ld sd
我们来看这句话的意思就是说我们在完成存取这两样指令的时候 ,他说存储指令 其实意思是存储数据的指令 ,载入指令 其实是载入数据的指令
我们来看这句话的意思他说 这类指令通过将基址寄存器x2 与指令中包含的12位有符号偏移量相加,得到存储器地址 ,对于存储指令 ,就是存储数据指令,就是从寄存器x1中读取出想要存储的指令。
这句话的意思就是对于 ld x1 (offset)x2 我们依据ld 的opcode hex 代码 先从ld读出整个指令所需要的x1 x2两个寄存器编号 我们从x2 这个编号内读出他所代表的数据 那是64位 然后将ld 的op码中含有的12位数扩展64位的数据 共同组成 datamemory 的64位地址 然后在这个地址下读出 数据 并写会编号为x1的寄存器中
data memory 的读写控制信号都是独立的,但是仅有一个会在上升或下降沿有效。
然后我们来分析 这个立即数扩展单元 我们会发现这个模块是32位输入 64位输出的 实际上 其实只用到了这32位指令中的12位字段符号
上面我们讲述完了R型指令 和 ld 等需要用到data memory 和 一个扩展
接下来 还有一种 beq 类型
对于分支指令检查是否成立,我们可以这么来看
我们使用单独的加法器 将PC地址(64位) 和符号扩展之后的左移一位的12位指令相加,得到分支目标地址 。
上面是整个电路的基本逻辑
其实我们发现我们还有一些control 和 ALU单元的没做完
其实对于ALU这种中控 我们能进行的操作只有 加减乘除
我们现在想要做的是将ALUop细化出来 做以区分
其实因为我做的只有8条指令 只要在register里面筛选出来 分别对应了什么 op 的值 丢给parameter 就行了
我们需要进行的操作分为四类 算术 载入 存储 条件分支
1.R型算术指令 add sub and or
二进制op操作数 实现的操作码是011 0011
2. I型载入数据指令 ld 000 0011
3.S型存储指令 sd类型 010 0011
3. SB类型的条件分支语句 110 0011
这里表明 其实除了PCSrc 不能直接表示 其他都可以由控制单元经过opcode 和func字段控制