有人问过这个问题,即在无需更改数据存储器的情况下将加载字节实现到单周期数据路径中,解决方案如下。
替代文字 http://img214.imageshack.us/img214/7107/99897101.jpg
这实际上是一个很现实的问题;大多数内存系统完全基于字,单个字节通常只在处理器内部处理。当您在许多计算机上看到“总线错误”时,这通常意味着处理器试图访问未正确字对齐的内存地址,并且内存系统引发了异常。无论如何,因为字节地址可能不是 4 的倍数,我们不能直接将它们传递到内存。但是,我们仍然可以获取任何字节,因为每个字节都可以在某个字中找到,并且所有字地址都是 4 的倍数。所以我们要做的第一件事是确保我们得到正确的字。如果我们取地址的高 30 位(即 ALUresult[31-2])并将它们与低端的两个 0 位组合(这就是“左移 2”单元真正在做的事情),我们得到了包含所需字节的字的字节地址。这只是字节自己的地址,向下舍入为 4 的倍数。此更改意味着 lw 现在也将地址向下舍入为 4 的倍数,但这没关系,因为未对齐的地址无论如何都不适用于此内存的 lw单元。好的,现在我们从内存中取回数据字。我们如何从中得到我们想要的字节?好吧,请注意,字中字节的字节偏移量仅由字节地址的低 2 位给出。因此,我们只需使用这 2 位来使用多路复用器从字中选择适当的字节。注意大端字节编号的使用,这适用于 MIPS。下一个,我们必须将字节零扩展为 32 位(即,只需将其与高端的 24 个零组合),因为问题指定这样做。实际上,这是问题中的一个小错误:实际上, lbu 指令对字节进行零扩展,但 lb 对其进行符号扩展。那好吧。最后,我们必须扩展 MemtoReg 控制的多路复用器以接受一个新的输入:lb 情况下的零扩展字节。MemtoReg 控制信号必须加宽到 2 位。原来的 0 和 1 的 case 分别变成了 00 和 01,我们添加了一个新的 case 10,它只在 lb 的情况下使用。lbu 指令对字节进行零扩展,但 lb 对其进行符号扩展。那好吧。最后,我们必须扩展 MemtoReg 控制的多路复用器以接受一个新的输入:lb 情况下的零扩展字节。MemtoReg 控制信号必须加宽到 2 位。原来的 0 和 1 的 case 分别变成了 00 和 01,我们添加了一个新的 case 10,它只在 lb 的情况下使用。lbu 指令对字节进行零扩展,但 lb 对其进行符号扩展。那好吧。最后,我们必须扩展 MemtoReg 控制的多路复用器以接受一个新的输入:lb 情况下的零扩展字节。MemtoReg 控制信号必须加宽到 2 位。原来的 0 和 1 的 case 分别变成了 00 和 01,我们添加了一个新的 case 10,它只在 lb 的情况下使用。
即使在阅读了解释之后,我也不太了解它是如何工作的,尤其是关于将 ALU 结果左移 2 会给出字节地址......这怎么可能?所以如果我想加载一个半字然后我会做一次左移,我会得到半字的地址??什么是更好的方法来加载字节,通过修改数据存储器加载半字?(上面的问题提出了我们不能修改数据存储器的限制)