• 沒有找到結果。

Computer Architecture Project 2

N/A
N/A
Protected

Academic year: 2022

Share "Computer Architecture Project 2"

Copied!
9
0
0

加載中.... (立即查看全文)

全文

(1)

Computer Architecture Project 2

 Team Work

陳縕儂-Report Writing、測試 呂鈺達-Coding、測試

王紹丞-測試

 Implementation of Pipelined CPU + Data Cache

Project 1 IF_ID.v

利用 clk 的 posedge 控制,並且判斷當 write_i 為 1 的時候,才將 input 的值 assign 給 output。

由於 instruction 中有 beq 和 jump,所以若為此兩個 instruction,可能會先 fetch 到錯誤的 instruction(因為先 fetch beq 的下一個 instruction,當最後發現 taken 時,則需要 flush 掉 Latch IF_ID 中的值)。故加一判斷,當 flush_i 為 1 時,將 output 全寫為 0。

而 Latch IF/ID 的值,只有在 clk 的 posedge 才能做更新。因為可能會有一種狀況,就是此時 經過判斷後,flush_i 的值變為 1,我們必須到下一個 cycle 才將存的內容 flush 掉,否則會 產生錯誤。所以不能讓 flush_i 改變則改變其中的值。

ID_EX.v

利用 clk 的 posedge 控制,直接將 input 的值 assign 給 output 即可。

比較特別的地方是要將 ALUSrc、ALUOp、RegDst 三個 control signal 從傳進來的 control 中分 開(因為原本是將所有的 control signal 合在一起傳進來),但 assign 到 output 時要將之分開。

EX_MEM.v

Group Members

資工三 B94902032 陳縕儂 B94902063 呂鈺達 B94902076 王紹丞

(2)

如同 Latch ID_EX 一樣,都只要在 clk 的 posedge 將 input 值 assign 給 output 即可,並且也 要將 MemRead 和 MemWrite 兩個 control signal 分開。

MEM_WB.v

如同上述兩個 Latch 一樣,都只要在 clk 的 posedge 將 input 值 assign 給 output 即可,並且 也要將 RegWrite 和 MemtoReg 兩個 control signal 分開。

Eq.v

是為了要提早判斷 instruction beq 的結果為 taken 或 non-taken,所以加此 component 判斷 data1_i 和 data2_i 兩者是否相等,若相等則 data_o 輸出 1,否則輸出 0。當此結果為 1 以 及此 instruction 為 beq 時,代表 taken,所以就要 flush 掉已存在 IF_ID 裡面的 data 了。

Adder.v

data_o 輸出 data1_in 和 data2_in 的和,是為了計算當 beq 為 taken 時的 PC 值。

PC.v

使用一個 control signal(write_i),並且判斷當 write_i 為 1 的時候才可以對 PC 做寫入的動作。

此目的是要 stall cycle 時,可以不要更改 PC 的值,讓下一個 fetch 到的 instruction 依然為同 樣的 instruction,進而達成 stall cycle 的目的。每次 PC 都是要在 clk 的 posedge 才可以更改,

若 write_i 被改為 0 的話,要在下一個 cycle 才能更改 PC 的值。

Signed_Extend.v

將 data_i 的最高位重複 16 次,然後和 data_i 自己 concatenation 起來,達到 sign extend 的 目的。

MUX_2.v, MUX5_2.v & MUX8_2.v

根據 input 的 bit 數將不同 bit 的 component 分開成不同的 module,並由 select_i 控制,若 為 0,data_o 則輸出 data1_i,否則為 data2_i。

MUX_3.v

由 select_i 控制並決定 output data 的值,如下表所示:

select_i data_o

(3)

00 data1_i

01 data2_i

10 data3_i

ShiftLeftTwo32.v & ShiftLeftTwo26.v

利用 concatenation 來達到 shift 的結果,只要將部分的 input 和 0 結合即可完成。

ALU.v

根據 instruction 並且決定 ALUCtrl 的值,控制 ALU 要做的 operation 為何,如下表所示:

ALUCtrl Instruction Action

000 AND data1_i & data2_i

001 OR data1_i | data2_i

010 ADD data1_i + data2_i

011 MUL data1_i * data2_i

110 SUB data1_i - data2_i

ALU_Control.v

由 ALUOp_i 和 funct_i 控制,ALUOp_i 為 0 則為 R-type,為 1 則為 ADDI,如下表:

ALUOp_i funct_i Instruction Action

10

100100 AND ALUCtrl = 000 100101 OR ALUCtrl = 001 100000 ADD ALUCtrl = 010 011000 MUL ALUCtrl = 011 100010 SUB ALUCtrl = 110 00

LW ALUCtrl = 010 SW ALUCtrl = 010 ADDI ALUCtrl = 010

01 BEQ ALUCtrl = 110

將之分為三種 types,分別是 R-type、I-type,以及 branch。由於每種情況要使 ALU 做不同 的加減乘除運算,所以依照應該做的運算去設定 ALUCtrl 的值(Ex.LW、SW、ADDI 要做加法,

BEQ 要做減法,都依照這些去設定 ALUCtrl 的值)。

Control.v

(4)

由於一開始的 PC 值是由 control signal 中的 Jump 和 Branch 來決定,所以若沒有將此 signal 的值歸零的話,可能會造成一開始 PC 的值就錯誤。所以我在開始之前,將所有 signal 的值 都設為 0,這樣才能得到 PC 的正確值。

由 Op_i 控制,決定下列 control signal 的值,設定如下表:

Instruction R-type LW SW Branch Jump ADDI Op_i 000000 100011 101011 000100 000010 001000

RegDst_o 1 0 0 X X 0

Jump_o 0 0 0 0 1 0

Branch_o 0 0 0 1 X 0

MemRead_o 0 1 0 0 0 0

MemtoReg_o 0 1 1 X X 0

ALUOp_o 00 00 00 01 X 0

MemWrite_o 0 0 1 0 0 0

ALUSrc_o 0 1 1 0 X 1

RegWrite_o 1 1 0 0 0 1

Hazard_Detection_Unit.v

判斷此時的 instruction 是否為 lw 並且與前一個 instruction 有 dependency,則必須 stall 一 cycle,要做以下的設定:

PC_Write_o = 0;  stall cycle 後,避免更新 PC 的值,因為要使 PC 停留在同一個 instruction 繼續做。

IF_ID_o = 0;  避免 Latch IF/ID 將下一個 instruction 往下傳。

Mux8_o = 1;  此時是要 stall cycle,故將 signal 設為 0,避免它做任何事。

若不為上述狀況的 hazard,可以藉由 forwarding 來完成,故都不需要 stall cycle。(不用考慮 beq 和前面一個 instruction 有 dependency 的狀況)

Forwarding_Unit.v

用於 R-type 或是 lw 的 forwarding,分成以下兩種狀況:

1. EX hazard

先判斷前一個 instruction 為 R-type(可以藉由 control signal RegWrite 判斷),並且藉由此 時在 ID 的 instruction 和MEM 的 instruction 兩者作判斷,若相同的話,代表有 dependency,

而由於此時前一個 instruction 所作的加減乘除值已經計算出來,所以可以直接從 stage MEM 中取出 ALU 的計算結果當作 forwarding 的值來用。

2. MEM hazard

(5)

不在情況 1 之中的結果,接著判斷前兩個 instruction 是否為 lw 或是 R-type,並且藉由 此時在 ID 中的 instruction 以及 WB 中的 instruction 兩者做判斷,若相同的話,代表此 時的 instruction 和前兩個 instruction 有 dependency,不管是 lw 或是 R-type,此時的結 果都已經計算完畢,所以可以從 stage WB 中 mux5 的結果取出 forwarding 的值來計算。

新增(修改)的 Component & Detailed Cache Controller dcache_data_sram.v

將原本 1K 的 cache size 改成 256B,並且給定適當的 index bit。

dcache_tag_sram.v

此檔案做了和 dcache_data_sram.v 一樣的修改以外,也將一個 tag 的 bit 數改為 26 個(24-bit 的 tag 加上 valid bit 和 dirty bit)。

dcache_top.v

cache 的主要架構都在此 component 中,如下圖所示:

(6)

 讀出 hit 和 data 的值

以上兩行 code 可以讀出 hit 和 data 的值。

 從 32-bit 到 255-bit 讀出 p1 傳來的 address 中的 data

在 cache 中總共有 256-bit,我現在要把 p1 address 所指向的 32-bit data 讀出來。

做法如下:

1. 先算出 p1 的 offset 與開頭會是 cache 中這 256bit 的第幾個 bit(long_offset)。

2. 將 cache 的 256bits 往右 shift long_offset 這麼多個 bits,我們可以發現要取的 32 個 bit 就是 shift 之後的 0-31。

3. 將這 32-bit 取出即可。

以下寫出詳細的 code 內容

 Wire 的接線部分

此時 cpu 傳來一組 32-bit 的 data 要存到 cache 中,我們的做法如下:

1. 先用一個 mask(bin_window)將 cache 256-bit 上要存放這 32-bit 的區間歸 0。

Ex. 這 32-bit 要放在第 128-159,則 bin_window = 11111….1000….0111…..1(第 128-159 是 0)。

2. 將此 32-bit 平移到該位置,再拿去跟原本的 256-bit 做 or 運算,就可以將 cache 的值更 新。

 這裡要注意的是,我們在平移的時候需要先做 bit extension。

例如當我在將 32-bit 的 data 往左 shift long_offset = 127 那麼多 bit 時,若沒有做 bit extension 則無法得到正確的值,最後的 data 會是 0錯誤值!

以下詳細列出此部分的 code,如下:

assign hit = (sram_tag == p1_tag && sram_valid)?1:0;

assign r_hit_data[255:0] = sram_cache_data[255:0];

assign long_offset = {{27{1'b0}}, p1_offset} << 3;

reg [255:0] temp_r;

always@(p1_offset or r_hit_data or long_offset) begin temp_r = r_hit_data[255:0] >> long_offset;

p1_data[31:0] = temp_r[31:0];

end

(7)

IF_ID.v, ID_EXE.v, EXE_MEM.v & MEM_WB.v

在 Project1 中我們沒有將初始值歸零。然而在 Project2 中,若不事先歸零,則會使得 mem stall 訊號呈現”x”,讓 latch 無法將 data 往下傳(因為 stall 訊號是”x”),因此必須將 rst 的 signal 傳入每個 latch 才能讓 latch 的初值是 0。

CPU.v

宣告許多 wire 變數,將 input 和 output 的值屬於同一條線的利用 assign 接起來(如圖所示),

詳細過程不贅述。如此一來,即完成此 pipeline 的 CPU。

reg [255:0] bin_window;

reg [255:0] bin_value;

reg [255:0] temp_value;

// write data : 32-bit to 256-bit

always@(p1_offset or r_hit_data or p1_data_i or long_offset) begin bin_window = ~({{224{1'b0}}, {32{1'b1}}} << long_offset);

bin_value = {{244{1'b0}}, p1_data_i} << long_offset;

temp_value = r_hit_data[255:0] & bin_window[255:0];

w_hit_data[255:0] = temp_value | bin_value;

end

(8)

 Implementation of TestBench

除了之前所新增的一些規定的 data,像是 cycle counts、pipeline stall…之類的,再 output 一 些 cache 的 data 內容, output 一些資訊讓我們知道每個 cycle 的結果,可以幫助 debug。

Cycle counts  此時 counter 的值 CPU Start  此時 start 的值

Pipeline Stall  藉由 IF_ID_Write 判斷此時是否要 stall cycle,若為 0 則代表要 stall。

並且還要加一判斷,當此時要 flush 時,代表原本 fetch 的 data 被 flush 掉,等同於 stall 一 cycle。所以也要 output Stall 為 1。

Pipeline Flush  此時 IF_ID_Flush 的值

當 count 為 150 時將所有的 cache 中的 data 存到 memory 中。

在每個 cycle 中傳入的 address 以及 hit 或 miss 的結果都 output 出來,並且 write back 時也 output 之。



Problems and solutions of this project

(9)

在 implement 這個 Project 時,由於已經有大部分的了解,以及上一個 project 的實作經驗,

所以較為容易上手,途中沒有遇到甚麼太大的問題,主要有以下兩個:

 原本的 latch 中,沒有將 signal 的值歸 0,所以可能在一開始的時候,mem stall 的 signal 為”x”,由於沒有正常的值存在,所以無法將 data 往下傳。

解決方法是在所有的 latch 上加上一個 signal(rst),將之傳入 latch,並且使 latch 在開始 的時候的初始值為 0。

 在平移 32-bit 並且跟原本的 256-bit 作 or 運算,若原本的 data 無法 shiftlong_offset 的 bit 數時,則會得到 data 的值為 0。

解決方法是在平移的時候先做 bit extension,這樣才會得到正確的數值。

 由於測資存在上次 project 中所忽略的狀況(beq 可能產生 hazard 但無法取到正確的值)。

我們有針對此問題去討論,覺得可以 stall cycle 或是由前面已經算出來的值接到 ID stage 去 forwarding beq 的正確結果,都可以達到最後判斷正確的情況。最後助教說不需要考 慮此問題,所以我們就沒有多加了,但是我們還是有針對這樣的問題去討論過,使我們 對 computer 的 architecture 瞭解更透徹☺。

參考文獻

相關文件

(realsites)所存在的意義,在 「抗拒場域」中,不斷的再現,也同時進行著辯證與 翻轉。對我們來說,異質空間的正確位置也許可在真實空間中理解,但卻又自外 於所有地方(outside of all

而要維持這樣的體溫,也只能生存在熱帶氣候區。同時恐龍的呼吸器官並不完

在 Riemann 映射定理中指出, 任意兩個邊界多於一點的單連通域是全純等價的, 即存在 雙方 單值 (即單葉) 的全純映射, 將一個映為另一個。

並將之列為 公務機關及非公務機關對一般個資蒐集、處理或利用的合法要 件之一。然在實務上,要求當事人同意都必須要「書面同意」 ,在當前科技

也就是我不要做一個『呷教』的和尚。我自許做一個報恩的 人,並且發願:我要給人,不希望人家給我。」 4 希望「佛

主帳冊 4C 4C 中只要有 中只要有 中只要有 中只要有 中只要有 中只要有 中只要有 中只要有任一個 任一個 任一個 任一個 任一個 C 任一個 任一個 任一個 C 不同 不同 不同 不同 不同 不同

以下簡單介紹魔術三角形: 如圖 1, 若三角形每邊有 三個數且數字和都是定值, 稱為 3 階 (傳統) 魔術三角形; 如圖 2, 若每邊有三 個數且較大兩數和減最小數的差都是定值, 稱為

這個都是很將來的事情,而現在我們都沒有答案的事情。我們現在必須要做 的也只是說,能不能把這個目前的情況先第一步減緩,