Khối HazardUnit có nhiệm vụ phát hiện các xung đột về dữ liệu và xung đột điều khiển rồi tạo ra các tín hiệu chuyển tiếp cho dữ liệu (ForwardAE,ForwardBE…), các tín hiệu điều khiển thanh ghi như stallF, stallD,flushE.
* Khối chuyển tiếp dữ liệu
* Dữ liệu được chuyển tiếp từ giai đoạn MEM, WB về giai đoạn EX, do vậy ta sẽ dùng bộ mux 4 đầu vào để chọn dữ liệu cho ALU tính toán
Tín hiệu điểu khiển bộ lựa chọn
Register File MEM WB
ForwardAE 00 10 01 ForwardBE 00 10 01 * Mã lệnh trong Verilog if((RsE!=0)&&(RsE==WriteRegM)&&(RegWriteM))ForwardAE=2'b10; else if((RsE!=0)&&(RsE==WriteRegW)&&(RegWriteW))ForwardAE=2'b01; else ForwardAE=2'b00;
if((RtE!=0)&&(RtE==WriteRegM)&&(RegWriteM))ForwardBE=2'b10; else if((RtE!=0)&&(RtE==WriteRegW)&&(RegWriteW))ForwardBE=2'b01; else ForwardBE=2'b00;
Điều khiển thanh ghi Pipeline
* Khi xảy ra xung đột điều khiển, các thanh ghi IF, ID cần được giữ nguyên giá trị cũ (stall), thanh ghi EX cần được xóa, khối HazardUnit sẽ làm nhiệm vụ phát hiện xung đột và tạo ra các tín hiệu stallF, stallD, FlushE tương ứng để xóa,giữ giá trị cũ cho các thanh ghi.
Hazard khi thực hiện lệnh lw
* Hazard do lệnh lw cần dừng 1 chu kì xủ lý, do vậy khối HazardUnit sẽ tạo ra tín hiệu stallF,stallD,FlushE điều khiển thanh ghi xử lý hazard
StallF StallD flushE
Giá trị 1 1 1
Nhiệm vụ Giữ lại giá trị cũ cho thanh ghi IF
Giữ lại giá trị cũ cho thanh ghi ID
Xóa thanh ghi EX
* Mã lệnh trong Verilog.
lwstall=((RsD==RtE)||(RtD==RtE))&&(MemtoRegE); {StallF,StallD,FlushE}={3{lwstall}}; //ghép bit
Hazard khi thực hiện lệnh điều khiển chương trình
* Khi thực hiện lệnh điều khiển chương trình bne,beq,…chúng ta cần xóa các thanh ghi IF,ID khi điều kiện nhảy đúng, khối HazardUnit phát hiện và tạo ra các tín hiệ stallF,StallD,FlushE để điều khiển thanh ghi pipeline
StallF StallD flushE
Giá trị 1 1 1
Nhiệm vụ Giữ lại giá trị cũ cho thanh ghi IF
Giữ lại giá trị cũ cho thanh ghi ID
* Mã verilog
branchstall=(branchD&&((RsD==WriteRegE)|| (RtD==WriteRegE))&&RegWriteE)||
(branchD&&MemtoRegM&&((RsD==WriteRegM)||(RtD==WriteRegM))); {StallF,StallD,FlushE}={3{branchstall}}; //ghép bit
* Dễ thấy các tín hiệu stallF,stallD,FlushE được sinh ra do lệnh lw và lệnh điều khiển chương trình có tác dụng giống nhau, do vậy ta có cộng hai tín hiệu này thành 1 tín hiệu duy nhất.
{StallF,StallD,FlushE}={3{lwstall}}|{3{branchstall}};
Khối tính toán rẽ nhánh sớm
* Để giảm ảnh hưởng của các lệnh rẽ nhánh có điều kiện, chúng ta cần tính toán điều kiện nhảy sớm nhất có thể, ở đây ta sẽ tính toán trong giai đoạn ID.
Xử lý xung đột dữ liệu cho lệnh nhảy
* Xét lệnh sau: add $1,$2,$3 bne $1,$2,Lable
* Do khối so sánh đặt ở giai đoạn ID nên ta phải chuyển tiếp dữ liệu từ giai đoạn EX (lệnh add) về giai đoạn ID, Giai đoạn EX sẽ được thêm 1 bộ lựa chọn để chọn dữ liệu từ registerfile hoặc từ dữ liệu chuyển tiếp, tín hiệu điều khiển được sinh ra từ khối HazardUnit.
RegisterFile MEM
ForwardAD 0 1
ForwardBD 0 1
* Mã Verilog cho tín hiệu lựa chọn
ForwardAD=(RsD!=0)&&(RsD==WriteRegM)&&RegWriteM; ForwardBD=(RtD!=0)&&(RtD==WriteRegM)&&RegWriteM;