2010-03-03 36 views
5

有一個問題,有關在單個週期數據路徑中實現加載字節而不必更改數據存儲器的問題,並且解決方案如下所示。在單個週期數據路徑中加載半字和加載字節

alt text http://img214.imageshack.us/img214/7107/99897101.jpg

這其實是一個相當現實的問題 ;大多數存儲器系統是完全基於字的 ,而個別的 字節通常只在處理器內部處理 。當在許多計算機上看到 「總線錯誤」時,此 通常意味着處理器嘗試使用 來訪問內存地址,該地址是不正確字對齊的 ,並且 存儲器系統引發了異常。 無論如何,因爲字節地址可能是 不是4的倍數,所以我們不能直接將它們傳遞給內存。但是,我們 仍可以在任何字節,因爲 每個字節可一些 字中找到,所有的字地址是4的倍數 所以我們 要做的第一件事是要確保我們得到正確的 字。如果我們取地址(即ALUresult [31-2]) 的高30位,並將它們與低位的 的兩個0位(這是「左邊的 」單位實際上在做什麼) ,我們 具有 包含所需字節的字的字節地址。這是 只是字節自己的地址,圓潤 下降到4的倍數。這種變化 意味着LW現在也可以圓 地址到4的倍數,但 沒關係,因爲非對齊地址 是行不通的對於這個 內存單元無論如何。好的,現在我們從內存中獲取數據 。我們如何獲得 我們想要的字節?那麼, 請注意,該字內的字節的字節偏移量 剛好由該字節的 地址的 低位2位給出。因此,我們只需使用這些位即可使用多路複用器從字中選擇合適的字節 。注意 使用big-endian字節編號,因爲 適合MIPS。接下來,我們 必須將該字節零擴展爲32位(即,僅將其與其高端的零相結合),因爲 問題指定這樣做。實際上, 這是 問題中的一個小錯誤:實際上,指令零擴展字節,但是對其進行符號擴展。好吧。 最後,我們必須擴展MemtoReg控制的多路複用器 以接受一個 新的輸入: lb的情況下的零擴展字節。 MemtoReg控件 信號必須加寬到2位。該 原來0 1例改爲分別00 和01,和我們添加一個新的 情況下,10這是隻有在的情況下使用磅的

我不太實際就如何理解即使在閱讀了解釋之後,這種方法仍然有效,特別是關於左移ALU結果2將給出字節地址...這怎麼可能?所以如果我想加載一個半字,那麼我會做一個左移,我會得到半字的地址?通過修改數據存儲器可以更好地裝載字節,加載半字? (上面的問題提出了限制,我們不能修改數據存儲器)

回答

3

原作者似乎正在爲從內存中讀取的32位數據添加一個字節多路複用器。該存儲器允許一個完整的32位自然對齊的加載(lw指令),附加字節多路複用器和零擴展允許加載字節指令(lbu指令)。

ALU結果的左移產生了一個字地址,NOT一個字節地址,並且說明信號路由中隱含的右移兩位。最終的結果就是ALU結果的低兩位在發送到存儲器之前被屏蔽(置零)。 ALU值的兩個LSB由存儲器的下行流饋送到字節多路複用器,允許字存儲器讀取任意字節。

在顯示的加載半字(16位),只是字節和完整的32位字的邏輯中沒有直接的支持。但是,您可以輕鬆修改字節尋址邏輯,以使用類似方法支持字而不是字節(甚至兩個字)。

+0

所以重點是。 1.這個工作不需要左移2嗎? 2.如果我想做一個半字,那麼我需要一個2x1多路複用器,並使用最低有效位作爲控制信號? – aherlambang

+0

1)實際上沒有左移兩位。右移兩位(通過丟棄兩個LSB導致:ALUResult [31-2]),左移兩位則簡單地將這些位重新放回同一位置(兩個LSB中爲零)。簡單地掩蓋較低的兩位將更加明顯。 2)要執行一個對齊的半字讀取,您可以使用ALUresult [1]來控制一個16位2對1多路複用器。由於其中一個未對齊的情況(地址LSB = 11)需要來自兩個不同32位字(即:兩個存儲器訪問)的字節,所以不能支持任意單週期半字讀取。 –