1. 程式人生 > >計算機組成與系統結構實驗-基於微程式控制的CPU設計

計算機組成與系統結構實驗-基於微程式控制的CPU設計

本文章主要是為了通俗的解釋計算機組成實驗的微程式彙編的實現方法:

實驗目的

在掌握部件單元電路實驗的基礎上,初步瞭解如何基於微程式控制進行CPU設計。

實驗軟體

Dais-CMStudio

實驗要求

1、學習教材3.1,3.2節,熟悉聯機方式下的開發環境。

2、完成以下內容:

任務1:用匯編語言編寫一個源程式,完成以下功能:

從I/O輸入56h,並存入記憶體的18號單元;

從I/O輸入78h,存入暫存器R0;

將兩者相加,存入19號單元;

將19號單元的內容輸出到I/O顯示。

任務2:增加一條減法指令,指令格式如下:

指令格式:SUB  R0, [addr]

機器指令碼:11000000  XXXXXXXX  XXXXXXXX

說明:R0 - [addr]→R0

任務3:增加一條暫存器加法指令,指令格式如下:

指令格式:ADR  Rd, Rs

機器指令碼:1110RdRs  

說明:Rd + Rs→Rd

任務實現

任務1:因為軟體內已經含有了5條基本指令助記符等的內容了,我們直接使用進行彙編即可(開啟CMX16檔案的MXJ6.ASM)

            具體實現的彙編程式碼如下:                                                

            IN  R0,IOL          (將IO低位的資料存入R0通用暫存器)

            STA 0018h,R0    (將R0中的資料存入記憶體的18號單元)

            IN  R0,IOL          

            ADD R0,0018h   (將0018h號單元的記憶體資料與R0相加存入R0)

            STA 0019h,R0    (將R0中的資料存入記憶體的19號單元)

            OUT IOH ,0019  (在IO高位地址輸出0019h號單元的記憶體資料)

            JMP  START

任務2:我們需要在指令系統中先模仿ADD助記符新增一條SUB的助記符,由機器指令碼11000000轉化為16進製得到C0,因此的到SUB的助記符為:SUB         R0,*        C0        3             ;R0 - [addr]→R0

接下來就是計算該機器指令碼對應的微程式的微地址:

每條指令的微程式入口地址怎樣確定?

位號:10 9   8     7     6      5 4 3 2 1 0

內容:1   1  IR7  IR6 IR5    0 0 0 0 0 0    (紅色即為上面的機器指令碼,將其帶入即可)

因此計算的SUB給出的這個機器指令碼要求的入口地址為0780(這是上面內容從後開始4位4位的轉換為16進位制的結果。入口地址就是當程式執行到這條指令時會根據你的助記符中的機器指令碼結合這個計算方法自動跳到微地址為780的地方繼續執行)

那麼接下來就容易了,在程式本身存在ADD指令的情況下,我們只需要照抄就行,將ADD微地址入口為0680開始的微指令照抄到SUB的微地址入口0780,然後將最後一條微指令的CPU加法運算改為減法運算就行。(即M=0,S2=1,S1=0,S0=1)


(第一條微指令的微地址為0780,這樣應該明白了吧~)

然後只需要把任務1的ADD改成SUB進行操作就可以驗證你寫的對不對了~

任務3:

思考:首先要將Rd作為源暫存器將資料放入AXL中,再將Rs作為源暫存器源暫存器將資料放入BXL中,將(AX+BX)L的結果存入Rd中即可。現在在問題是如何處理將Rd和Rs分別作為源暫存器,然而對於Rd和Rs暫存器,我們只要寫好指令系統裡的助記符就行。(如果用C++來解釋就類似一個函式入口吧)

這裡需要補充知識點:通用暫存器就是實驗箱上面的DX(R3,R2)和CX(R1,R0)  

因此檢視R0通用暫存器的資料就是看CX的後2位就行,其他同理。

然後根據題目要求的機械指令碼為1110RdRs

RsRd

選定的暫存器

00

01

10

11

R0

R1

R2

R3

具體實現見下:(如果上面看不懂請先繼續看下去,在回來看估計會恍然大悟,我也是摸了挺久的~)

首先是新增指令系統的助記符:

                                  助記符  運算元    指令碼    指令長度

通過編碼規則可得到    ADR    R0 ,R0     E0          1      ;

                                  ADR    R0 ,R1      E1          1      ;

                                  ADR    R0 ,R2      E2          1      ;

                                  ADR     R0 ,R3     E3          1      ;

                                  …(以下省略12條,類比上面寫下去即可)

至於IN的助記符也需要修改為   IN    R0,IOL    20      1;

IN   R1,IOL    21       1;

IN    R2,IOL   22       1;

IN   R3,IOL    23       1;

(上面的助記符很多,但是他們單純只是2條指令而已,不要誤會~)

他們的指令碼如何計算呢,下面舉個李子就知道了:

下面詳細解說一下指令碼如何計算還有通過指令碼如何得到該“函式”的微指令入口地址:

機器是通過計算機器指令碼去到相應的微指令入口地址的,具體實現就是

位號:10 9    8      7    6      5 4 3 2 1 0

內容:1   1   IR7  IR6 IR5    0 0 0 0 0 0 =>   07C0 

(標彩色的部分就是機器指令碼,而4,3組成Rs,2,1組成Rd,可以參考上面通用暫存器的表)

這個就是ADR  R0 ,R0  E0     1   ;這條助記符的微指令入口位置。

那麼我們只需要從7C0這個位置開始修改就行。 

至於ADR的其他助記符的微指令入口地址就不用計算了,機器會自動根據你的助記符R0~R3翻譯得到相應的通用暫存器進行操作。(具體我也不清楚,看到他微指令是那麼跑的,期初我修改了微指令4處想要實現IN的操作,可是寫了發現它並不執行我寫的後面三條,資料卻是正確的存入了對應的通用暫存器)

至於微指令怎麼寫,這裡先要提醒一點就是我們是通過XP來確定你的Rs和Rd的,因此在讀通用暫存器資料時根據XP的0和1來改變你使用的是哪個通用暫存器(Rs或Rd)

注意:下面這個任務三的微指令表中目錄行的第二個S2應該為S1(即M12下面那個是S1)


大致是上面這樣吧,反正我實驗成功了,若是Rs或者Rd反了可以修改的是它們的Xp的0,1值(至於溢位測試也沒有測,實驗時間有限,心有餘而力不足)

具體實現我懶的在寫一次,增加一條指令無非就是修改2處,1:指令系統的助記符;2:計算出對應微地址然後寫微指令即可!

如果有錯誤請指出,謝謝~