有人问过如何将加载字节实现到单周期数据路径而不必更改数据存储器,解决方案如下所示。
alt text http://img214.imageshack.us/img214/7107/99897101.jpg
这实际上非常现实 题;大多数内存系统都是 完全基于单词,个人 通常只处理字节 在处理器内部。当你看到一个 许多计算机上的“总线错误”,这个 通常意味着处理器尝试过 访问一个内存地址 不正确的字对齐,和 内存系统引发了异常。 无论如何,因为字节地址可能 不是4的倍数,我们不能通过 他们直接记忆。但是,我们 仍然可以得到任何字节,因为 在某些内容中可以找到每个字节 字,所有字地址都是 4的倍数。所以我们首先要做的事情 我们要确保我们做对了 字。如果我们采取高30位 地址(即ALUresult [31-2]) 并将它们与两个0位组合在一起 低端(这就是“左边” 转移2“单位真的在做”,我们 有字的字节地址 包含所需的字节。这是 只是字节自己的地址,四舍五入 下降到4的倍数。这种变化 意味着lw现在也会变圆 地址低至4的倍数,但是 这是没有对齐的地址 不管怎样,这对lw都不起作用 记忆单元。好的,现在我们得到了数据 从记忆中回来的话。我们如何得到 我们想要的字节呢?好, 注意字节的字节偏移量 在这个词里面只是给出了 字节的低位2位 地址。所以,我们只是使用那些2 用于选择适当字节的位 使用多路复用器。请注意 使用big-endian字节编号,如 适用于MIPS。接下来,我们 必须将字节零扩展为32 比特(即,只是将它与24结合起来 在它的高端零),因为 问题指定这样做。其实, 这是一个轻微的错误 问题:实际上,lbu 指令零扩展字节,但是 lb标志 - 扩展它。那好吧。 最后,我们必须延长 MemtoReg控制的多路复用器接受一个 新输入:零扩展字节 lb案件。 MemtoReg控件 信号必须加宽到2位。该 原0和1的情况变为00 和01分别,我们添加一个新的 案例10仅用于案件 lb。
即使在阅读了解释之后,我也不太明白它是如何工作的,特别是关于左移ALU结果为2会给出字节地址......这怎么可能?所以,如果我想加载一个半字,那么我会做一个左移,我会得到半个字的地址?什么是更好的方法来加载字节,通过修改数据内存加载半字? (上面的问题提出了我们无法修改数据存储器的约束)
答案 0 :(得分:3)
原作者似乎只是在从内存中读取的32位数据中添加一个字节多路复用器。该存储器允许完整的32位自然对齐加载(lw指令),附加字节多路复用器和零扩展允许加载字节指令(lbu指令)。
ALU结果的左移产生一个字地址, NOT 一个字节地址,并说明在信号路由中隐式右移两位。最终结果就是ALU结果的低两位在被发送到存储器之前被屏蔽(归零)。 ALU值的两个LSB从存储器的下游馈送到字节多路复用器,允许字存储器读取任意字节。
显示的逻辑没有直接支持加载半字(16位),只是字节和完整的32位字。但是,您可以使用类似的方法轻松修改字节寻址逻辑以支持字而不是字节(甚至两者)。