设计草稿
已有指令扩展
采用分布式译码,根据需求扩展ALU的OP和ext的OP即可。
乘法模块设计
考虑其为运算模块,故将其放置于E级
输入 | 输出 |
---|---|
a | busy |
b | out |
reset | |
clk | |
start | |
issigned | |
ismul | |
mula | |
smul | |
data |
- a、b为操作数
- reset复位
- clk时钟信号
- start启动运算信号
- issigned带符号信号
- ismul乘法信号
- mula输出HI/LO选择信号
- smul写入使能信号
- data写入数据
设计思路
利用start标记运算启动,issigned、ismul组合为带/无符号乘/除法。
利用busy标记正在运算,提供给冲突处理模块
利用mula、smul、data组成类似grf的结构
冲突解决
- 特别设计:每一集将grf待写入数据和地址写入grfwd和grfwtarget数据通路,以简化设计。
已有冲突模块已经很好地解决了冲突,故将新模块加入已有冲突解决模块。
对于mul类指令,加入新stall=原stall||(mulspe_d&&mulbusy_e)
,其中mulspe_e
表示d级时读取mul模块结果的指令,mulbusy_e
表示e级模块结果未出
当e级结果未出且d级需要结果时,向e级传空泡,D级F级暂停
测试方案
假设转发设计无误,构建能够测试所有指令的尽量短的指令序列,着重测试mul模块相关指令。
|
|
思考题
- 乘除法模块独立是因为乘除法很慢,加入alu会拖慢速度,独立出来可以在执行无关指令的时候进行计算,以加快指令执行速度。单独的寄存器可以统一访问和写入格式。
- 真实处理器按照循环进行运算,如乘法一次计算乘数每一位,将被乘数加于乘数的高32位。
- 见上文冲突处理部分
- 可以统一写入数据格式,写入具体位只需要调整使能信号。但是个人而言没有明显感受,反而增加了代码量,没有感觉更加清晰。
- 按字节写的写入量少于一字节,按字节读的读取量等于一字节。当dm对于按字操作有特殊优化时可以加快速度。
- 分布式译码可以极大减少流水信号,不需要考虑信号的传输,只需要流水一个32位的指令即可。针对冲突处理我将各级的待写入寄存器的数据和地址归入grfwd和grfwtarget数据通路,有较强的通用性。
- 遇到的冲突与p5相同,采用一致的处理方式。相应的测试样例类似如下:
|
|
- 我采用完全手动构造测试样例,先利用新加入的指令通过各种方式加载数据,再利用加载的数据放入乘除法模块计算。每次乘除法计算后立刻使用mfhi和mflo获取结果。为了测试冒险,我使用第七题所示的构造方式,构造冒险指令序列。