mips pipelined cpu

94
MIPS PIPELINED CPU SVTH : Hoàng Ngọc Nhân Lớp 08DT1 Nguyễn Gia Phong Lớp 08DT2 Nguyễn Nguyên Vủ Lớp 08DT2 Nhóm 14

Upload: nguyen-gia-phong

Post on 28-Apr-2015

519 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: MIPS PIPELINED CPU

MIPS PIPELINED CPU

SVTH : Hoàng Ngọc Nhân Lớp 08DT1

Nguyễn Gia Phong Lớp 08DT2

Nguyễn Nguyên Vủ Lớp 08DT2

Nhóm 14

Page 2: MIPS PIPELINED CPU

1. Yêu cầu:

- Thiết kế chip Mips Pipeline 32bit dựa trên thiết kế và tập lệnh của chip

Mips Single-Cycle đã thực hiện ở lab3.

2. Giới thiệu về chip pipelined:

- Khác với chip Single-cycle khi các lệnh đều được thực hiện xong trong

1 chu kỳ máy, chip pipelined chia một câu lệnh ra thành 5 bước (steps):

+ Đọc lệnh từ bộ nhớ (Instruction Fetch – IF)

+ Giải mã lệnh và đọc các thanh ghi (Instruction Decode – ID)

+ Tính toán kết quả của câu lệnh hoặc địa chỉ (Execution –EX)

+ Đọc hoặc ghi dữ liệu trên bộ nhớ dữ liệu (Memory access – MEM)

+ Ghi kết quả vào thanh ghi (Write back – WB)

- Câu lệnh sau không cần đợi câu lệnh trước hoàn tất mới bắt đầu thực

hiện mà mỗi step sẽ được thực hiện liên tiếp, do đó cải thiện đáng kể về tốc độ

thực hiện các chương trình

Page 3: MIPS PIPELINED CPU

3. Thiết kế:

3.1. Sơ đồ khối tổng quát:

Page 4: MIPS PIPELINED CPU

3.2. Các bước thực hiện 1 câu lệnh:

*Có 5 bước với các chức năng riêng:

+ Đọc lệnh từ bộ nhớ (Instruction Fetch – IF)

Sử dụng địa chỉ lưu trong thanh ghi PC để giải mã ra mã máy của câu

lệnh tiếp theo và lưu vào thanh ghi trung gian IF/ID.

Giá trị PC được cộng thêm 4 và lưu vào thanh ghi trung gian IF/ID.

+ Giải mã lệnh và đọc các thanh ghi (Instruction Decode – ID)

Sử dụng mã máy của câu lệnh lưu trong thanh ghi IF/ID làm đầu vào cho

khối Regfile.

Khối Control sử dụng phần opcode của mã máy của câu lệnh để giải mã

thành các tín hiệu điều khiển, ngoài tín hiệu SignEx được sử dụng cho khối mở

rộng, các tín hiệu khác được lưu vào thanh ghi trung gian ID/EX.

- Đọc các thanh ghi Rs, Rt từ bộ thanh ghi và lưu vào thanh ghi trung

gian ID/EX.

- Khối mở rộng sử dụng tín hiệu SignEx từ khối Control để mở rộng dấu

hay mở rộng zero của 16 bit thấp của mã máy thành 32 bit và lưu vào thanh ghi

ID/EX.

- Địa chỉ của các thanh ghi Rs, Rt, Rd được lưu vào thanh ghi ID/EX.

+ Tính toán kết quả của câu lệnh hoặc địa chỉ (Execution –EX)

- Khối ALU sử dụng các đầu vào đã được lưu trong thanh ghi ID/EX để

tính toán và lưu kết quả vào thanh ghi trung gian EX/MEM.

- Một bộ mux được dùng để lựa chọn thanh ghi đích từ 2 thanh ghi Rt, Rd

và lưu địa chỉ vào thanh ghi EX/MEM.

Page 5: MIPS PIPELINED CPU

- Địa chỉ mới của PC sau câu lệnh BNE cũng được tính toán trong khối

này. Một số bộ mux được dùng để lựa chọn giá trị mới cho PC từ các câu lệnh

rẽ nhanh BNE, J, JR.

- Các tín hiệu điều khiển MemWrite, MemtoReg và RegWrite được lưu

tiếp vào thanh ghi EX/MEM.

+ Đọc hoặc ghi dữ liệu trên bộ nhớ dữ liệu (Memory access – MEM)

- Sử dụng kết quả tính toán từ khối ALU và tín hiệu điều khiển

MemWrite từ thanh ghi EX/MEM để thực hiện đọc hoặc ghi vào bộ nhớ dữ

liệu. Kết quả đọc ra được ghi vào thanh ghi trung gian MEM/WB.

- Các giá trị đầu ra của ALU, địa chỉ thanh ghi đích cùng với 2 tín hiệu

điều khiển MemtoReg và RegWrite được ghi lại vào thanh ghi MEM/WB.

+ Ghi kết quả vào thanh ghi (Write back – WB)

- Sử dụng tín hiệu MemtoReg từ thanh ghi MEM/WB để lựa chọn dữ liệu

cần ghi vào thanh ghi.

- Sử dụng địa chỉ thanh ghi đích và tín hiệu cho phép ghi RegWrite để

thực hiện công việc ghi dữ liệu vào bộ thanh ghi.

Page 6: MIPS PIPELINED CPU

3.3. Thiết kế các thanh ghi pipelind:

- Ta sử dụng các thanh ghi pipeline làm trung gian lưu kết quả thực hiện

của mỗi khối trong mỗi chu kỳ để làm đầu vào cho các khối sau trong chu kỳ

tiếp theo

- Có 4 thanh ghi pipelined nằm giữa các khối :

+ Thanh ghi IF/ID :

Để lưu các giá trị PC+4 và mã máy của câu lệnh .

+ Thanh ghi ID/EX :

Để lưu các giá trị, PC + 4, địa chỉ của lệnh Jump, 2 giá trị đọc ra từ bộ

thanh ghi.

Giá trị mở rộng 32bits từ 16bits.

Địa chỉ các thanh ghi Rs, Rt, Rd.

Các tín hiệu điều khiển từ khối Control: ALUOp, ALUSrc, RegDst,

Branch, Jump, MemWrite, RegWrite, MemtoReg.

Page 7: MIPS PIPELINED CPU

+ Thanh ghi EX/MEM :

Để lưu các giá trị : Kết quả tính toán của khối ALU, giá trị dùng để ghi

vào bộ nhớ file thanh ghi, địa chỉ của thanh ghi đích. Các tín hiệu điều khiển:

MemWrite, RegWrite, MemtoReg.

+ Thanh ghi MEM/WB :

Để lưu các giá trị: Giá trị đọc ra từ bộ nhớ dữ liệu, kết quả của khối ALU,

địa chỉ thanh ghi đích

3.3. Một số xung đột trong cấu trúc Pipelined

a. Stuctural hazard:

- Là xung đột xảy ra khi phần cứng không hỗ trợ việc kết hợp xử lý các

lệnh đồng thời.

b. Data hazard:

- Xảy ra khi mà dữ liệu cần cho lệnh tiếp theo chưa có sẵn vì đang được

xử lý ở các lệnh trước đó.

Page 8: MIPS PIPELINED CPU

c. Control hazard:

- Là xung đột xảy ra khi có lệnh rẽ nhánh

- Khi một lệnh rẽ nhánh được thực thi thì chưa biết được địa chỉ lệnh tiếp theo

3.4. Cách xử lý Hazard

a. Structural hazard:

- Thêm các thanh ghi giữa các tiến trình để chứa dữ liệu được xử lý từ các tiến

trình trước.

- Các thanh ghi sẽ chia phần cứng thành những phần tương ứng với các Stage

b. Data hazard:

Có 2 kĩ thuật xử lý data hazard:

- Forwarding

- Stalling

* Kĩ thuật forwarding:

- Là kĩ thuật chuyển tiếp dữ liệu đầu ra sau khi tính toán từ bộ ALU hoặc sau

khi truy cập bộ nhớ dữ liệu vào sử dụng ở lệnh sau đó, không chờ đến khi ghi

vào file thanh ghi

Page 9: MIPS PIPELINED CPU

Datapath

Điều kiện xảy ra Forwarding :

EX\MEM.RegsRd=ID\EX.RegsRs

EX\MEM.RegsRd=ID\EX.RegsRt

MEM\WB.RegsRd= ID\EX.RegsRs

MEM\WB.RegsRd= ID\EX.RegsRt

Bảng giá trị các tín hiệu điều khiển

*Kỹ thuật stalling

- Là kĩ thuật trì hoãn việc thực thi 1 lệnh để chờ dữ liệu có được từ các câu lệnh

trước

Page 10: MIPS PIPELINED CPU

Datapath

Điều kiện xảy ra Stalling: Toán hạng nguồn của 1 lệnh được lấy từ lệnh

lw đứng sát trước nó. Lúc này chưa thể forwarding được, phải trì hoãn 1 chu kì.

ID/EX.MemRead=1

IF/ID.RegsRs=ID/EX.RegsRd IF/ID.RegsRt=ID/EX.RegsRd

Page 11: MIPS PIPELINED CPU

c. Control Hazard

Là xung đột xảy ra khi có lệnh rẽ nhánh

Khi một lệnh rẽ nhánh được thực thi thì chưa biết được địa chỉ lệnh tiếp theo

Cách xử lý :

Thực thi các lệnh bình thường. Nếu xảy ra rẽ nhánh thì flush các lệnh vừa tìm, giải mã ở sau.

- Xây dựng 1 khối có thể flush các lệnh đã tìm và giải mã ở tiến trình IF và ID.

- Điều kiện flush: 1 trong những điều kiện:

+ khi thực thi lệnh Jump, JR

+ lệnh BNE thỏa điều kiện nhảy

4. Thiết kế datapath cho MIPS Pipelined CPU

4.1. Khối InstructionMem

Dùng để lưu trữ lệnh dưới dạng mã máy (nhị phân).Kích thước mỗi lệnh khi dịch ra mã máy là 32 bits, tốn 32 bits để lưu trữ.Đầu vào bộ nhớ lệnh là địa chỉ lệnh cần lấy, đầu ra là mã máy của câu lệnh tương ứng lấy được

module InstructionMem (address,instruction);

input [31:0]address;

output [31:0]instruction;

reg [31:0]instrmem[25:0];

reg [31:0] temp;

buf #150 buf0(instruction[0],temp[0]),

buf1(instruction[1],temp[1]),

buf2(instruction[2],temp[2]),

Page 12: MIPS PIPELINED CPU

buf3(instruction[3],temp[3]),

buf4(instruction[4],temp[4]),

buf5(instruction[5],temp[5]),

buf6(instruction[6],temp[6]),

buf7(instruction[7],temp[7]),

buf8(instruction[8],temp[8]),

buf9(instruction[9],temp[9]),

buf10(instruction[10],temp[10]),

buf11(instruction[11],temp[11]),

buf12(instruction[12],temp[12]),

buf13(instruction[13],temp[13]),

buf14(instruction[14],temp[14]),

buf15(instruction[15],temp[15]),

buf16(instruction[16],temp[16]),

buf17(instruction[17],temp[17]),

buf18(instruction[18],temp[18]),

buf19(instruction[19],temp[19]),

buf20(instruction[20],temp[20]),

buf21(instruction[21],temp[21]),

buf22(instruction[22],temp[22]),

buf23(instruction[23],temp[23]),

buf24(instruction[24],temp[24]),

buf25(instruction[25],temp[25]),

buf26(instruction[26],temp[26]),

Page 13: MIPS PIPELINED CPU

buf27(instruction[27],temp[27]),

buf28(instruction[28],temp[28]),

buf29(instruction[29],temp[29]),

buf30(instruction[30],temp[30]),

buf31(instruction[31],temp[31]);

always @(address)

begin

temp=instrmem[address/4];

end

initial

begin

$readmemh("instr.dat", instrmem);

end

endmodule

4.2Khối thanh ghi lệnh PCLà thanh ghi chứa địa chỉ của lệnh sắp được thực thi.Vì địa chỉ lệnh có 32 bits nên PC là thanh ghi 32 bits.Xây dựng thanh ghi này tương tự xây dựng thanh ghi trong LAB 1 đã làm, nguyên tắc vẫn dùng DFF.

module PC_Block(DataIN, DataOUT,PCWrite, clk, Reset);

input clk;

Page 14: MIPS PIPELINED CPU

input Reset;

input PCWrite;

input [31:0] DataIN;

output [31:0] DataOUT;

reg [31:0] DataOUT;

always @(negedge clk or negedge Reset)

begin

if( Reset == 1)

DataOUT <= 0;

else

begin

if(PCWrite == 1'b1)

begin

DataOUT <= DataIN;

end

else

begin

DataOUT <= DataOUT;

end

end

end

Page 15: MIPS PIPELINED CPU

4.3 Bộ cộng Add

Vì thông thường sau mỗi chu kì xung clock, MIPS CPU cần thực thi lệnh tiếp theo, do đó địa chỉ lệnh cần tăng lên , tức giá trị của thanh ghi PC tăng lên.Vì cấu trúc bộ nhớ lệnh, nên sau mỗi chu kì clock PC tăng lên 4.

module Add(Add_In1,Add_In2,out_Add);

input [31:0] Add_In1;

input [31:0] Add_In2;

output [31:0] out_Add;

wire [31:0] Cout;

add_bit bit0(Add_In1[0],Add_In2[0], 1'b0, out_Add[0], Cout[0]) ;

add_bit bit1(Add_In1[1],Add_In2[1], Cout[0], out_Add[1], Cout[1]);

add_bit bit2(Add_In1[2],Add_In2[2], Cout[1], out_Add[2], Cout[2]);

add_bit bit3(Add_In1[3],Add_In2[3], Cout[2], out_Add[3], Cout[3]);

add_bit bit4(Add_In1[4],Add_In2[4], Cout[3], out_Add[4], Cout[4]);

add_bit bit5(Add_In1[5],Add_In2[5], Cout[4], out_Add[5], Cout[5]);

add_bit bit6(Add_In1[6],Add_In2[6], Cout[5], out_Add[6], Cout[6]);

add_bit bit7(Add_In1[7],Add_In2[7], Cout[6], out_Add[7], Cout[7]);

add_bit bit8(Add_In1[8],Add_In2[8], Cout[7], out_Add[8], Cout[8]);

add_bit bit9(Add_In1[9],Add_In2[9], Cout[8], out_Add[9], Cout[9]);

add_bit bit10(Add_In1[10],Add_In2[10], Cout[9], out_Add[10], Cout[10]);

add_bit bit11(Add_In1[11],Add_In2[11], Cout[10], out_Add[11], Cout[11]);

add_bit bit12(Add_In1[12],Add_In2[12], Cout[11], out_Add[12], Cout[12]);

add_bit bit13(Add_In1[13],Add_In2[13], Cout[12], out_Add[13], Cout[13]);

Page 16: MIPS PIPELINED CPU

add_bit bit14(Add_In1[14],Add_In2[14], Cout[13], out_Add[14], Cout[14]);

add_bit bit15(Add_In1[15],Add_In2[15], Cout[14], out_Add[15], Cout[15]);

add_bit bit16(Add_In1[16],Add_In2[16], Cout[15], out_Add[16], Cout[16]);

add_bit bit17(Add_In1[17],Add_In2[17], Cout[16], out_Add[17], Cout[17]);

add_bit bit18(Add_In1[18],Add_In2[17], Cout[17], out_Add[18], Cout[18]);

add_bit bit19(Add_In1[19],Add_In2[19], Cout[18], out_Add[19], Cout[19]);

add_bit bit20(Add_In1[20],Add_In2[20], Cout[19], out_Add[20], Cout[20]);

add_bit bit21(Add_In1[21],Add_In2[21], Cout[20], out_Add[21], Cout[21]);

add_bit bit22(Add_In1[22],Add_In2[22], Cout[21], out_Add[22], Cout[22]);

add_bit bit23(Add_In1[23],Add_In2[23], Cout[22], out_Add[23], Cout[23]);

add_bit bit24(Add_In1[24],Add_In2[24], Cout[23], out_Add[24], Cout[24]);

add_bit bit25(Add_In1[25],Add_In2[25], Cout[24], out_Add[25], Cout[25]);

add_bit bit26(Add_In1[26],Add_In2[26], Cout[25], out_Add[26], Cout[26]);

add_bit bit27(Add_In1[27],Add_In2[27], Cout[26], out_Add[27], Cout[27]);

add_bit bit28(Add_In1[28],Add_In2[28], Cout[27], out_Add[28], Cout[28]);

add_bit bit29(Add_In1[29],Add_In2[29], Cout[28], out_Add[29], Cout[29]);

add_bit bit30(Add_In1[30],Add_In2[30], Cout[29], out_Add[30], Cout[30]);

add_bit bit31(Add_In1[31],Add_In2[31], Cout[30], out_Add[31], Cout[31]);

endmodule

module add_bit(r1,r2,cin,outbit,cout);

input r1,r2,cin;

output cout,outbit;

wire c1,c2,c3;

xor #(50) or1(outbit,r1,r2,cin);

Page 17: MIPS PIPELINED CPU

and #(50) and1(c1,r1,r2);

and #(50) and2(c2,r2,cin);

and #(50) and3(c3,r1,cin);

or #(50) or2(cout,c1,c2,c3);

endmodule

4.3Khối DataMem

module datamem(read_data, address_data, writedata, readenable,writeenable, clk);

input [31:0] address_data, writedata;

input writeenable, readenable, clk;

output [31:0] read_data;

reg [7:0] datamemory[1023:0];

reg [31:0] temp;

buf #100 buf0(read_data[0],temp[0]),

buf1(read_data[1],temp[1]),

buf2(read_data[2],temp[2]),

buf3(read_data[3],temp[3]),

buf4(read_data[4],temp[4]),

buf5(read_data[5],temp[5]),

buf6(read_data[6],temp[6]),

buf7(read_data[7],temp[7]),

buf8(read_data[8],temp[8]),

Page 18: MIPS PIPELINED CPU

buf9(read_data[9],temp[9]),

buf10(read_data[10],temp[10]),

buf11(read_data[11],temp[11]),

buf12(read_data[12],temp[12]),

buf13(read_data[13],temp[13]),

buf14(read_data[14],temp[14]),

buf15(read_data[15],temp[15]),

buf16(read_data[16],temp[16]),

buf17(read_data[17],temp[17]),

buf18(read_data[18],temp[18]),

buf19(read_data[19],temp[19]),

buf20(read_data[20],temp[20]),

buf21(read_data[21],temp[21]),

buf22(read_data[22],temp[22]),

buf23(read_data[23],temp[23]),

buf24(read_data[24],temp[24]),

buf25(read_data[25],temp[25]),

buf26(read_data[26],temp[26]),

buf27(read_data[27],temp[27]),

buf28(read_data[28],temp[28]),

buf29(read_data[29],temp[29]),

buf30(read_data[30],temp[30]),

buf31(read_data[31],temp[31]);

Page 19: MIPS PIPELINED CPU

// if writeenable

always @(posedge clk)

if (writeenable)

begin

datamemory[address_data]=writedata[31:24];

datamemory[address_data+1]=writedata[23:16];

datamemory[address_data+2]=writedata[15:8];

datamemory[address_data+3]=writedata[7:0];

end

// if readenable

always @(address_data or datamemory[address_data] or datamemory[address_data+1] or datamemory[address_data+2] or datamemory[address_data+3])

if (readenable)

begin

temp={datamemory[address_data],datamemory[address_data+1],datamemory[address_data+2],datamemory[address_data+3]};

end

initial

begin

Page 20: MIPS PIPELINED CPU

$readmemh("data.dat", datamemory);

end

endmodule

4.5. Khối file thanh ghi

module regfile(ReadData1,ReadData2,WriteData,ReadRegister1,

ReadRegister2,WriteRegister,RegWrite,clk,reset);

input [4:0]ReadRegister1,ReadRegister2,WriteRegister;

input [31:0] WriteData;

input RegWrite, clk,reset;

output [31:0] ReadData1, ReadData2;

wire [31:0] W0,W1,W2,W3,W4,W5,W6,W7,W8,W9,W10, W11,W12,W13,W14,W15,W16,W17,W18,W19,W20, W21,W22,W23,W24,W25,W26,W27,W28,W29,W30,W31;

wire [31:0] GroupOfBit[0:31];

wire [31:0] WriteEnable;

//----Decoder Block

Decoder Decoder1(RegWrite, WriteRegister, WriteEnable);

//----32 Register Blocks----

Register Reg0 ({1'b1}, {32'b0}, W0, clk,reset);

Register Reg1 (WriteEnable[1 ], WriteData, W1, clk,reset);

Register Reg2 (WriteEnable[2 ], WriteData, W2, clk,reset);

Register Reg3 (WriteEnable[3 ], WriteData, W3, clk,reset);

Register Reg4 (WriteEnable[4 ], WriteData, W4, clk,reset);

Register Reg5 (WriteEnable[5 ], WriteData, W5, clk,reset);

Page 21: MIPS PIPELINED CPU

Register Reg6 (WriteEnable[6 ], WriteData, W6, clk,reset);

Register Reg7 (WriteEnable[7 ], WriteData, W7, clk,reset);

Register Reg8 (WriteEnable[8 ], WriteData, W8, clk,reset);

Register Reg9 (WriteEnable[9 ], WriteData, W9, clk,reset);

Register Reg10(WriteEnable[10], WriteData, W10, clk,reset);

Register Reg11(WriteEnable[11], WriteData, W11, clk,reset);

Register Reg12(WriteEnable[12], WriteData, W12, clk,reset);

Register Reg13(WriteEnable[13], WriteData, W13, clk,reset);

Register Reg14(WriteEnable[14], WriteData, W14, clk,reset);

Register Reg15(WriteEnable[15], WriteData, W15, clk,reset);

Register Reg16(WriteEnable[16], WriteData, W16, clk,reset);

Register Reg17(WriteEnable[17], WriteData, W17, clk,reset);

Register Reg18(WriteEnable[18], WriteData, W18, clk,reset);

Register Reg19(WriteEnable[19], WriteData, W19, clk,reset);

Register Reg20(WriteEnable[20], WriteData, W20, clk,reset);

Register Reg21(WriteEnable[21], WriteData, W21, clk,reset);

Register Reg22(WriteEnable[22], WriteData, W22, clk,reset);

Register Reg23(WriteEnable[23], WriteData, W23, clk,reset);

Register Reg24(WriteEnable[24], WriteData, W24, clk,reset);

Register Reg25(WriteEnable[25], WriteData, W25, clk,reset);

Register Reg26(WriteEnable[26], WriteData, W26, clk,reset);

Register Reg27(WriteEnable[27], WriteData, W27, clk,reset);

Register Reg28(WriteEnable[28], WriteData, W28, clk,reset);

Register Reg29(WriteEnable[29], WriteData, W29, clk,reset);

Page 22: MIPS PIPELINED CPU

Register Reg30(WriteEnable[30], WriteData, W30, clk,reset);

Register Reg31(WriteEnable[31], WriteData, W31, clk,reset);

//----32x32to32 Multiplexor1 Block----

multiplexor32x32to32 Multi1(W0, W1, W2,W3, W4,W5,W6,W7,W8,W9,

W10, W11, W12, W13, W14, W15, W16,W17,W18, W19,

W20, W21, W22, W23, W24, W25, W26, W27, W28,

W29, W30,W31, ReadRegister1, ReadData1);

//----32x32to32 Multiplexor2 Block----

multiplexor32x32to32 Multi2(W0, W1, W2,W3, W4,W5,W6,W7,W8,W9,

W10, W11, W12, W13, W14, W15, W16,W17,W18, W19,

W20, W21, W22, W23, W24, W25, W26, W27, W28,

W29, W30,W31, ReadRegister2, ReadData2);

endmodule

`timescale 1 ps / 100 fs

module Decoder(RegWrite, WriteRegister, WriteEnable);

input RegWrite;

input [4:0] WriteRegister;

output [31:0] WriteEnable;

Page 23: MIPS PIPELINED CPU

DEC5_32 a(WriteEnable[31:0],WriteRegister[4:0],RegWrite);

endmodule

module Dec2(Q,A,EN);

input [1:0]A;

input EN;

output [3:0]Q;

wire [1:0]AN;

not #(50)n[1:0](AN,A);

and #(50)(Q[3],A[1],A[0],EN);

and #(50)(Q[2],A[1],AN[0],EN);

and #(50)(Q[1],AN[1],A[0],EN);

and #(50)(Q[0],AN[1],AN[0],EN);

endmodule

//mach giai ma 3->8

module Dec3(Q,A,S);

input [2:0]A;

input S;

output [7:0]Q;

wire [2:0]AN;

not #(50)n[2:0](AN,A);

and #(50)(Q[7],A[2],A[1],A[0],S);

and #(50)(Q[6],A[2],A[1],AN[0],S);

Page 24: MIPS PIPELINED CPU

and #(50)(Q[5],A[2],AN[1],A[0],S);

and #(50)(Q[4],A[2],AN[1],AN[0],S);

and #(50)(Q[3],AN[2],A[1],A[0],S);

and #(50)(Q[2],AN[2],A[1],AN[0],S);

and #(50)(Q[1],AN[2],AN[1],A[0],S);

and #(50)(Q[0],AN[2],AN[1],AN[0],S);

endmodule

module DEC5_32(Q,A,EN);

input [4:0]A;

input EN;

output [31:0]Q;

wire [3:0]S;

Dec2 d(S,A[4:3],EN);

Dec3 d1(Q[31:24],A[2:0],S[3]);

Dec3 d2(Q[23:16],A[2:0],S[2]);

Dec3 d3(Q[15:8],A[2:0],S[1]);

Dec3 d4(Q[7:0],A[2:0],S[0]);

endmodule

module D_FF (q, d, reset, clk,enable);

output q;

input d, reset, clk,enable;

Page 25: MIPS PIPELINED CPU

reg q;

wire clock;

and #50 and0(clock,clk,enable);

// Indicate that q is stateholding

always @(posedge clock or posedge reset)

if (reset)

q = 0; // On reset, set to 0

else

q = d; // Otherwise out = d endmodule

endmodule

`timescale 1 ps / 100 fs

module Multiplexor32to1(GroupOfBit, ReadRegister, ReadData);

input [31:0] GroupOfBit;

input [4:0] ReadRegister;

output ReadData;

wire [7:0]t;

MUX4 m1(t[7],ReadRegister [1:0],GroupOfBit[31],GroupOfBit[30],GroupOfBit[29],GroupOfBit[28]);

MUX4 m2(t[6],ReadRegister [1:0],GroupOfBit[27],GroupOfBit[26],GroupOfBit[25],GroupOfBit[24]);

MUX4 m3(t[5],ReadRegister [1:0],GroupOfBit[23],GroupOfBit[22],GroupOfBit[21],GroupOfBit[20]);

MUX4 m4(t[4],ReadRegister [1:0],GroupOfBit[19],GroupOfBit[18],GroupOfBit[17],GroupOfBit[16]);

Page 26: MIPS PIPELINED CPU

MUX4 m5(t[3],ReadRegister [1:0],GroupOfBit[15],GroupOfBit[14],GroupOfBit[13],GroupOfBit[12]);

MUX4 m6(t[2],ReadRegister [1:0],GroupOfBit[11],GroupOfBit[10],GroupOfBit[9],GroupOfBit[8]);

MUX4 m7(t[1],ReadRegister [1:0],GroupOfBit[7],GroupOfBit[6],GroupOfBit[5],GroupOfBit[4]);

MUX4 m8(t[0],ReadRegister[1:0],GroupOfBit[3],GroupOfBit[2],GroupOfBit[1],GroupOfBit[0]);

MUX8 m9(ReadData,ReadRegister[4:2],t[7],t[6],t[5],t[4],t[3],t[2],t[1],t[0]);

endmodule

module MUX8(Q, sel, D7,D6,D5,D4,D3,D2,D1,D0);

input [2:0]sel;

input D7,D6,D5,D4,D3,D2,D1,D0;

outputQ;

wire [2:0]selN;

wire [7:0]t;

not #(50)nots[2:0](selN,sel);

and #(50)(t[0],D0,selN[2],selN[1],selN[0]);

and #(50)(t[1],D1,selN[2],selN[1],sel[0]);

and #(50)(t[2],D2,selN[2],sel[1],selN[0]);

and #(50)(t[3],D3,selN[2],sel[1],sel[0]);

Page 27: MIPS PIPELINED CPU

and #(50)(t[4],D4,sel[2],selN[1],selN[0]);

and #(50)(t[5],D5,sel[2],selN[1],sel[0]);

and #(50)(t[6],D6,sel[2],sel[1],selN[0]);

and #(50)(t[7],D7,sel[2],sel[1],sel[0]);

or #(50)(Q,t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7]);

endmodule

module MUX4(Q, sel, D3,D2,D1,D0);

input [1:0]sel;

input D3,D2,D1,D0;

outputQ;

wire [1:0]selN;

wire [3:0]t;

not #(50)nots[1:0](selN,sel);

and #(50)(t[0],D0,selN[1],selN[0]);

and #(50)(t[1],D1,selN[1],sel[0]);

and #(50)(t[2],D2,sel[1],selN[0]);

and #(50)(t[3],D3,sel[1],sel[0]);

or #(50)(Q,t[0],t[1],t[2],t[3]);

endmodule

Page 28: MIPS PIPELINED CPU

module multiplexor32x32to32(MuxIn0, MuxIn1,MuxIn2,MuxIn3,MuxIn4, MuxIn5,MuxIn6,MuxIn7,MuxIn8,MuxIn9,MuxIn10,MuxIn11,MuxIn12,

MuxIn13,MuxIn14,MuxIn15,MuxIn16,MuxIn17,MuxIn18,MuxIn19,MuxIn20, MuxI21 ,MuxIn22,MuxIn23,MuxIn24,MuxIn25,MuxIn26,MuxIn27,MuxIn28, MuxIn29,MuxIn30,MuxIn31,ReadRegister, ReadData);

input [31:0] MuxIn0, MuxIn1,MuxIn2,MuxIn3,MuxIn4,

MuxIn5,MuxIn6,MuxIn7,MuxIn8,MuxIn9,MuxIn10,

MuxIn11,MuxIn12,MuxIn13,MuxIn14,MuxIn15,MuxIn16,

MuxIn17,MuxIn18,MuxIn19,MuxIn20,MuxIn21,MuxIn22,

MuxIn23,MuxIn24,MuxIn25,MuxIn26,MuxIn27,MuxIn28,

MuxIn29,MuxIn30,MuxIn31;

input [4:0] ReadRegister;

output [31:0] ReadData;

wire [31:0] GroupOfBit[0:31];

parameter SIZE =32;

//-----chuong trinh tao GroupOfBit[0]->GroupOfBit[31] dung vong lap---

genvar i;

generate for (i=0; i<SIZE; i=i+1) begin:grbit

assign GroupOfBit[i] ={MuxIn31[i],MuxIn30[i],MuxIn29[i],MuxIn28[i],

MuxIn27[i],MuxIn26[i],MuxIn25[i],MuxIn24[i],

MuxIn23[i],MuxIn22[i],MuxIn21[i],MuxIn20[i],

MuxIn19[i],MuxIn18[i],MuxIn17[i],MuxIn16[i],

Page 29: MIPS PIPELINED CPU

MuxIn15[i],MuxIn14[i],MuxIn13[i],MuxIn12[i],

MuxIn11[i],MuxIn10[i],MuxIn9 [i],MuxIn8 [i],

MuxIn7 [i],MuxIn6 [i],MuxIn5 [i],MuxIn4 [i],

MuxIn3 [i],MuxIn2 [i],MuxIn1 [i],MuxIn0 [i]};

end endgenerate

//----32 Multiplexors Of 32-to-1 Multiplexor to get 32-bit ReadData----

Multiplexor32to1 Mux_0 (GroupOfBit[0 ], ReadRegister, ReadData[0 ]);

Multiplexor32to1 Mux_1 (GroupOfBit[1 ], ReadRegister, ReadData[1 ]);

Multiplexor32to1 Mux_2 (GroupOfBit[2 ], ReadRegister, ReadData[2 ]);

Multiplexor32to1 Mux_3 (GroupOfBit[3 ], ReadRegister, ReadData[3 ]);

Multiplexor32to1 Mux_4 (GroupOfBit[4 ], ReadRegister, ReadData[4 ]);

Multiplexor32to1 Mux_5 (GroupOfBit[5 ], ReadRegister, ReadData[5 ]);Multiplexor32to1 Mux_6 (GroupOfBit[6 ], ReadRegister, ReadData[6 ]);

Multiplexor32to1 Mux_7 (GroupOfBit[7 ], ReadRegister, ReadData[7 ]);

Multiplexor32to1 Mux_8 (GroupOfBit[8 ], ReadRegister, ReadData[8 ]);

Multiplexor32to1 Mux_9 (GroupOfBit[9 ], ReadRegister, ReadData[9 ]);

Multiplexor32to1 Mux_10(GroupOfBit[10], ReadRegister, ReadData[10]);

Multiplexor32to1 Mux_11(GroupOfBit[11], ReadRegister, ReadData[11]);

Multiplexor32to1 Mux_12(GroupOfBit[12], ReadRegister, ReadData[12]);

Multiplexor32to1 Mux_13(GroupOfBit[13], ReadRegister, ReadData[13]);

Multiplexor32to1 Mux_14(GroupOfBit[14], ReadRegister, ReadData[14]);

Page 30: MIPS PIPELINED CPU

Multiplexor32to1 Mux_15(GroupOfBit[15], ReadRegister, ReadData[15]);

Multiplexor32to1 Mux_16(GroupOfBit[16], ReadRegister, ReadData[16]);

Multiplexor32to1 Mux_17(GroupOfBit[17], ReadRegister, ReadData[17]);

Multiplexor32to1 Mux_18(GroupOfBit[18], ReadRegister, ReadData[18]);

Multiplexor32to1 Mux_19(GroupOfBit[19], ReadRegister, ReadData[19]);

Multiplexor32to1 Mux_20(GroupOfBit[20], ReadRegister, ReadData[20]);

Multiplexor32to1 Mux_21(GroupOfBit[21], ReadRegister, ReadData[21]);

Multiplexor32to1 Mux_22(GroupOfBit[22], ReadRegister, ReadData[22]);

Multiplexor32to1 Mux_23(GroupOfBit[23], ReadRegister, ReadData[23]);

Multiplexor32to1 Mux_24(GroupOfBit[24], ReadRegister, ReadData[24]);

Multiplexor32to1 Mux_25(GroupOfBit[25], ReadRegister, ReadData[25]);

Multiplexor32to1 Mux_26(GroupOfBit[26], ReadRegister, ReadData[26]);

Multiplexor32to1 Mux_27(GroupOfBit[27], ReadRegister, ReadData[27]);

Multiplexor32to1 Mux_28(GroupOfBit[28], ReadRegister, ReadData[28]);

Multiplexor32to1 Mux_29(GroupOfBit[29], ReadRegister, ReadData[29]);

Page 31: MIPS PIPELINED CPU

Multiplexor32to1 Mux_30(GroupOfBit[30], ReadRegister, ReadData[30]);

Multiplexor32to1 Mux_31(GroupOfBit[31], ReadRegister, ReadData[31]);

Endmodule

Module Registermodule Register (enable, d_in,d_out,clk,reset);

input clk, enable,reset;

input [31:0] d_in;

output [31:0] d_out;

D_FF dff0(d_out[0] ,d_in[0] ,reset,clk,enable);

D_FF dff1(d_out[1] ,d_in[1] ,reset,clk,enable);

D_FF dff2(d_out[2] ,d_in[2] ,reset,clk,enable);

D_FF dff3(d_out[3] ,d_in[3] ,reset,clk,enable);

D_FF dff4(d_out[4],d_in[4] ,reset,clk,enable);

D_FF dff5(d_out[5] ,d_in[5] ,reset,clk,enable);

D_FF dff6(d_out[6] ,d_in[6] ,reset,clk,enable);

D_FF dff7(d_out[7] ,d_in[7] ,reset,clk,enable);

D_FF dff8(d_out[8] ,d_in[8] ,reset,clk,enable);

D_FF dff9(d_out[9] ,d_in[9] ,reset,clk,enable);

D_FF dff10(d_out[10] ,d_in[10] ,reset,clk,enable);

D_FF dff11(d_out[11] ,d_in[11] ,reset,clk,enable);

D_FF dff12(d_out[12] ,d_in[12] ,reset,clk,enable);

D_FF dff13(d_out[13] ,d_in[13] ,reset,clk,enable);

D_FF dff14(d_out[14] ,d_in[14] ,reset,clk,enable);

D_FF dff15(d_out[15] ,d_in[15] ,reset,clk,enable);

Page 32: MIPS PIPELINED CPU

D_FF dff16(d_out[16] ,d_in[16] ,reset,clk,enable);

D_FF dff17(d_out[17] ,d_in[17] ,reset,clk,enable);

D_FF dff18(d_out[18] ,d_in[18] ,reset,clk,enable);

D_FF dff19(d_out[19] ,d_in[19] ,reset,clk,enable);

D_FF dff20(d_out[20] ,d_in[20] ,reset,clk,enable);

D_FF dff21(d_out[21] ,d_in[21] ,reset,clk,enable);

D_FF dff22(d_out[22] ,d_in[22] ,reset,clk,enable);

D_FF dff23(d_out[23] ,d_in[23] ,reset,clk,enable);

D_FF dff24(d_out[24] ,d_in[24] ,reset,clk,enable);

D_FF dff25(d_out[25] ,d_in[25] ,reset,clk,enable);

D_FF dff26(d_out[26] ,d_in[26] ,reset,clk,enable);

D_FF dff27(d_out[27] ,d_in[27] ,reset,clk,enable);

D_FF dff28(d_out[28] ,d_in[28] ,reset,clk,enable);

D_FF dff29(d_out[29] ,d_in[29] ,reset,clk,enable);

D_FF dff30(d_out[30] ,d_in[30] ,reset,clk,enable);

D_FF dff31(d_out[31] ,d_in[31] ,reset,clk,enable);

endmodule

module D_FF (q, d, reset, clk,enable);

output q;

input d, reset, clk,enable;

reg q;

wire clock;

Page 33: MIPS PIPELINED CPU

and #50 and0(clock,clk,enable);

// Indicate that q is stateholding

always @(posedge clock or posedge reset)

if (reset)

q = 0; // On reset, set to 0

else

q = d; // Otherwise out = d endmodule

endmodule

4.6. Khối ALUcontrol

module ALU_control(ALUcontrol,jr_control, ALUop,funct);

input [1:0]ALUop;

input [5:0]funct;

output [1:0]ALUcontrol;

output jr_control;

wire [7:0]a;

and #(50) and1(a[0],ALUop[1],ALUop[0]);

and #(50) and2(a[1],ALUop[1],~(ALUop[0]));

and #(50) and3(a[2],funct[5],~(funct[4]),funct[3],~(funct[2]),funct[1],~(funct[0]));

and #(50) and4(a[3],funct[5],~(funct[4]),~(funct[2]),funct[1],~(funct[0]));

and #(50) and5(a[5],~(ALUop[1]),ALUop[0]);

and #(50) and6(a[6],a[1],a[2]);

and #(50) and7(a[7],a[1],a[3]);

or #(50) or1(ALUcontrol[0],a[0],a[6]);

Page 34: MIPS PIPELINED CPU

or #(50) or2(ALUcontrol[1],a[5],a[7]);

// Jr

and #(50) andjr(jr_control,a[1],~(funct[5]),~(funct[4]),funct[3],~(funct[2]),~(funct[1]),~(funct[0]));

endmodule

4.7 Khối ALU

module ALU(Output, carryout, zero, overflow, negative, bussa, bussb, alucontrol);

input [1:0] alucontrol;

input [31:0] bussa;

input [31:0] bussb;

output [31:0] Output;

output carryout,zero,overflow,negative;

wire lessthan,notcarryout31;

wire [10:0] x;

wire [31:0] cout;

wire soverflow,scarryout;

setlessthan slt1(lessthan,bussa,bussb);

alu1bit bit0(Output[0],cout[0],bussa[0],bussb[0],alucontrol[1],lessthan,alucontrol);

alu1bit bit1(Output[1],cout[1],bussa[1],bussb[1],cout[0],1'b0,alucontrol);

Page 35: MIPS PIPELINED CPU

alu1bit bit2(Output[2],cout[2],bussa[2],bussb[2],cout[1],1'b0,alucontrol);

alu1bit bit3(Output[3],cout[3],bussa[3],bussb[3],cout[2],1'b0,alucontrol);

alu1bit bit4(Output[4],cout[4],bussa[4],bussb[4],cout[3],1'b0,alucontrol);

alu1bit bit5(Output[5],cout[5],bussa[5],bussb[5],cout[4],1'b0,alucontrol);

alu1bit bit6(Output[6],cout[6],bussa[6],bussb[6],cout[5],1'b0,alucontrol);

alu1bit bit7(Output[7],cout[7],bussa[7],bussb[7],cout[6],1'b0,alucontrol);

alu1bit bit8(Output[8],cout[8],bussa[8],bussb[8],cout[7],1'b0,alucontrol);

alu1bit bit9(Output[9],cout[9],bussa[9],bussb[9],cout[8],1'b0,alucontrol);

alu1bit bit10(Output[10],cout[10],bussa[10],bussb[10],cout[9],1'b0,alucontrol);

alu1bit bit11(Output[11],cout[11],bussa[11],bussb[11],cout[10],1'b0,alucontrol);

alu1bit bit12(Output[12],cout[12],bussa[12],bussb[12],cout[11],1'b0,alucontrol);

alu1bit bit13(Output[13],cout[13],bussa[13],bussb[13],cout[12],1'b0,alucontrol);

alu1bit bit14(Output[14],cout[14],bussa[14],bussb[14],cout[13],1'b0,alucontrol);

alu1bit bit15(Output[15],cout[15],bussa[15],bussb[15],cout[14],1'b0,alucontrol);

alu1bit bit16(Output[16],cout[16],bussa[16],bussb[16],cout[15],1'b0,alucontrol);

alu1bit bit17(Output[17],cout[17],bussa[17],bussb[17],cout[16],1'b0,alucontrol);

alu1bit bit18(Output[18],cout[18],bussa[18],bussb[18],cout[17],1'b0,alucontrol);

alu1bit bit19(Output[19],cout[19],bussa[19],bussb[19],cout[18],1'b0,alucontrol);

Page 36: MIPS PIPELINED CPU

alu1bit bit20(Output[20],cout[20],bussa[20],bussb[20],cout[19],1'b0,alucontrol);

alu1bit bit21(Output[21],cout[21],bussa[21],bussb[21],cout[20],1'b0,alucontrol);

alu1bit bit22(Output[22],cout[22],bussa[22],bussb[22],cout[21],1'b0,alucontrol);

alu1bit bit23(Output[23],cout[23],bussa[23],bussb[23],cout[22],1'b0,alucontrol);

alu1bit bit24(Output[24],cout[24],bussa[24],bussb[24],cout[23],1'b0,alucontrol);

alu1bit bit25(Output[25],cout[25],bussa[25],bussb[25],cout[24],1'b0,alucontrol);

alu1bit bit26(Output[26],cout[26],bussa[26],bussb[26],cout[25],1'b0,alucontrol);

alu1bit bit27(Output[27],cout[27],bussa[27],bussb[27],cout[26],1'b0,alucontrol);

alu1bit bit28(Output[28],cout[28],bussa[28],bussb[28],cout[27],1'b0,alucontrol);

alu1bit bit29(Output[29],cout[29],bussa[29],bussb[29],cout[28],1'b0,alucontrol);

alu1bit bit30(Output[30],cout[30],bussa[30],bussb[30],cout[29],1'b0,alucontrol);

alu1bit bit31(Output[31],cout[31],bussa[31],bussb[31],cout[30],1'b0,alucontrol);

xor #50 xor1(soverflow,cout[30],cout[31]);

not #50 not1(notcout31,cout[31]);

mux2_1 mux1(scarryout,cout[31],notcout31,alucontrol[1]);

Page 37: MIPS PIPELINED CPU

and #50 and1(negative,Output[31],1'b1);

or #50 or0(x[0],Output[0],Output[1],Output[2],Output[3]);

or #50 or1(x[1],Output[4],Output[5],Output[6],Output[7]);

or #50 or2(x[2],Output[8],Output[9],Output[10],Output[11]);

or #50 or3(x[3],Output[12],Output[13],Output[14],Output[15]);

or #50 or4(x[4],Output[16],Output[17],Output[18],Output[19]);

or #50 or5(x[5],Output[20],Output[21],Output[22],Output[23]);

or #50 or6(x[6],Output[24],Output[25],Output[26],Output[27]);

or #50 or7(x[7],Output[28],Output[29],Output[30],Output[31]);

or #50 or8(x[8],x[0],x[1],x[2],x[3]);

or #50 or9(x[9],x[4],x[5],x[6],x[7]);

or #50 or10(x[10],x[8],x[9]);

not #50 not2(zero,x[10]);

mux2_1 mux2(overflow,soverflow,1'b0,alucontrol[0]);

mux2_1 mux3(carryout,scarryout,1'b0,alucontrol[0]);

endmodule

module setlessthan(lessthanout,a,b);

output lessthanout;

input [31:0] a;

input [31:0] b;

wire [31:0] subout;

Page 38: MIPS PIPELINED CPU

wire sltoverflow;

wire [31:0] sltcout;

wire [1:0] sltcontrol;

or or1(sltcontrol[1],1'b1,1'b1);

or or2(sltcontrol[0],1'b0,1'b0);

alu1bit sltbit0(subout[0],sltcout[0],a[0],b[0],sltcontrol[1],1'b0,sltcontrol);

alu1bit sltbit1(subout[1],sltcout[1],a[1],b[1],sltcout[0],1'b0,sltcontrol);

alu1bit sltbit2(subout[2],sltcout[2],a[2],b[2],sltcout[1],1'b0,sltcontrol);

alu1bit sltbit3(subout[3],sltcout[3],a[3],b[3],sltcout[2],1'b0,sltcontrol);

alu1bit sltbit4(subout[4],sltcout[4],a[4],b[4],sltcout[3],1'b0,sltcontrol);

alu1bit sltbit5(subout[5],sltcout[5],a[5],b[5],sltcout[4],1'b0,sltcontrol);

alu1bit sltbit6(subout[6],sltcout[6],a[6],b[6],sltcout[5],1'b0,sltcontrol);

alu1bit sltbit7(subout[7],sltcout[7],a[7],b[7],sltcout[6],1'b0,sltcontrol);

alu1bit sltbit8(subout[8],sltcout[8],a[8],b[8],sltcout[7],1'b0,sltcontrol);

alu1bit sltbit9(subout[9],sltcout[9],a[9],b[9],sltcout[8],1'b0,sltcontrol);

alu1bit sltbit10(subout[10],sltcout[10],a[10],b[10],sltcout[9],1'b0,sltcontrol);

alu1bit sltbit11(subout[11],sltcout[11],a[11],b[11],sltcout[10],1'b0,sltcontrol);

alu1bit sltbit12(subout[12],sltcout[12],a[12],b[12],sltcout[11],1'b0,sltcontrol);

alu1bit sltbit13(subout[13],sltcout[13],a[13],b[13],sltcout[12],1'b0,sltcontrol);

alu1bit sltbit14(subout[14],sltcout[14],a[14],b[14],sltcout[13],1'b0,sltcontrol);

alu1bit sltbit15(subout[15],sltcout[15],a[15],b[15],sltcout[14],1'b0,sltcontrol);

alu1bit sltbit16(subout[16],sltcout[16],a[16],b[16],sltcout[15],1'b0,sltcontrol);

alu1bit sltbit17(subout[17],sltcout[17],a[17],b[17],sltcout[16],1'b0,sltcontrol);

alu1bit sltbit18(subout[18],sltcout[18],a[18],b[18],sltcout[17],1'b0,sltcontrol);

Page 39: MIPS PIPELINED CPU

alu1bit sltbit19(subout[19],sltcout[19],a[19],b[19],sltcout[18],1'b0,sltcontrol);

alu1bit sltbit20(subout[20],sltcout[20],a[20],b[20],sltcout[19],1'b0,sltcontrol);

alu1bit sltbit21(subout[21],sltcout[21],a[21],b[21],sltcout[20],1'b0,sltcontrol);

alu1bit sltbit22(subout[22],sltcout[22],a[22],b[22],sltcout[21],1'b0,sltcontrol);

alu1bit sltbit23(subout[23],sltcout[23],a[23],b[23],sltcout[22],1'b0,sltcontrol);

alu1bit sltbit24(subout[24],sltcout[24],a[24],b[24],sltcout[23],1'b0,sltcontrol);

alu1bit sltbit25(subout[25],sltcout[25],a[25],b[25],sltcout[24],1'b0,sltcontrol);

alu1bit sltbit26(subout[26],sltcout[26],a[26],b[26],sltcout[25],1'b0,sltcontrol);

alu1bit sltbit27(subout[27],sltcout[27],a[27],b[27],sltcout[26],1'b0,sltcontrol);

alu1bit sltbit28(subout[28],sltcout[28],a[28],b[28],sltcout[27],1'b0,sltcontrol);

alu1bit sltbit29(subout[29],sltcout[29],a[29],b[29],sltcout[28],1'b0,sltcontrol);

alu1bit sltbit30(subout[30],sltcout[30],a[30],b[30],sltcout[29],1'b0,sltcontrol);

alu1bit sltbit31(subout[31],sltcout[31],a[31],b[31],sltcout[30],1'b0,sltcontrol);

xor xor1(sltoverflow,sltcout[31],sltcout[30]);

xor xor2(lessthanout,sltoverflow,subout[31]);

endmodule

module alu1bit(result,cout,a,b,cin,lessthan,alucontrol);

input a,b,cin,lessthan;

input [1:0] alucontrol;

output cout,result;

wire addsubout,xorout,xorlessthanout;

addsub addsub1(addsubout,cout,a,b,cin,alucontrol[1]);

Page 40: MIPS PIPELINED CPU

xor #50 xor1(xorout,a,b);

mux2_1 mux2(xorlessthanout,xorout,lessthan,alucontrol[1]);

mux2_1 mux3(result,addsubout,xorlessthanout,alucontrol[0]);

endmodule

module addsub(result,cout,a,b,cin,binvert);

input a,b,cin,binvert;

output result,cout;

wire notb,bmux;

not #50 not1(notb,b);

mux2_1 mux1(bmux,b,notb,binvert);

add_b add1(result,cout,a,bmux,cin);

endmodule

module add_b(sum,cout,a,b,cin);

input a,b,cin;

output sum,cout;

wire x1,x2,x3;

xor #50 xor1(sum,a,b,cin);

and #50 and1(x1,a,b);

or #50 or1(x2,a,b);

and #50 and2(x3,cin,x2);

or #50 or2(cout,x1,x3);

endmodule

Page 41: MIPS PIPELINED CPU

module mux2_1(muxout,in1,in2,select);

output muxout;

input in1,in2,select;

wire notselect,x1,x2;

not #50 not1(notselect,select);

and #50 and1(x1,in1,notselect);

and #50 and2(x2,in2,select);

or #50 or1(muxout,x1,x2);

endmodule

4.8. Khối Control

module Control(Opcode,Jump,Branch,EX,M,WB,ex_control);

input [5:0] Opcode;

output Jump, Branch,ex_control;

output [3:0]EX;

output [2:0]M;

output [1:0]WB;

//reg [5:0] Opcode;

reg RegDst, Jump, Branch, MemRead, MemtoReg, MemWrite, ALUSrc, RegWrite,ex_control;

reg [1:0] ALUOp;

always @(Opcode )

begin

Page 42: MIPS PIPELINED CPU

casex (Opcode)

6'b000000 : begin : Rtype

RegDst = 1'b1;

Jump = 1'b0;

Branch = 1'b0;

MemRead = 1'b0;

MemtoReg = 1'b0;

ALUOp = 2'b10;

MemWrite = 1'b0;

ALUSrc = 1'b0;

RegWrite = 1'b1;

ex_control=1'bx;

end

6'b100011 : begin : lw

RegDst = 1'b0;

Jump = 1'b0;

Branch = 1'b0;

MemRead = 1'b1;

MemtoReg = 1'b1;

ALUOp = 2'b00;

MemWrite = 1'b0;

ALUSrc = 1'b1;

RegWrite = 1'b1;

ex_control=1'b1;

Page 43: MIPS PIPELINED CPU

end

6'b101011 : begin : sw

RegDst = 1'b1; //x

Jump = 1'b0;

Branch = 1'b0;

MemRead = 1'b1;

MemtoReg = 1'b0; //x

ALUOp = 2'b00;

MemWrite = 1'b1;

ALUSrc = 1'b1;

RegWrite = 1'b0;

ex_control=1'b1;

end

6'b000101 : begin : bne

RegDst = 1'b1; //x

Jump = 1'b0;

Branch = 1'b1;

MemRead = 1'b0;

MemtoReg = 1'bx; //x

ALUOp = 2'b01;

MemWrite = 1'b0;

ALUSrc = 1'b0;

RegWrite = 1'b0;

ex_control=1'b1;

Page 44: MIPS PIPELINED CPU

end

6'b000010 : begin : j

RegDst = 1'b1; //x

Jump = 1'b1;

Branch = 1'b0; //x

MemRead = 1'b0; //x

MemtoReg = 1'b0; //x

ALUOp = 2'b00; //xx

MemWrite = 1'b0; //x

ALUSrc = 1'b0; //x

RegWrite = 1'b0; //x

ex_control=1'bx;

end

6'b001110 : begin : xori

RegDst = 1'b0;

Jump = 1'b0;

Branch = 1'b0;

MemRead = 1'b0; //x

MemtoReg = 1'b0;

ALUOp = 2'b11;

MemWrite = 1'b0; //x

ALUSrc = 1'b1;

RegWrite = 1'b1;

Page 45: MIPS PIPELINED CPU

ex_control=1'b0;

end

default : begin

RegDst = 1'b0; //x

Jump = 1'b0;

Branch = 1'b0;

MemRead = 1'b0;

MemtoReg = 1'b0; //x

ALUOp = 2'b00; //xx

MemWrite = 1'b0;

ALUSrc = 1'b0; //x

RegWrite = 1'b0;

ex_control=1'bx;

end

endcase

end

assign EX[3:0]={RegDst,ALUSrc,ALUOp[1:0]};

assign M[2:0]={Branch,MemRead,MemWrite};

assign WB[1:0]={RegWrite,MemtoReg};

endmodule

4.9. Khối Compare

`timescale 1 ps / 100 fs

module Compare(equal,Addr1,Addr2);

// module nay so sanh 2 dia chi 5 bit dau vao

Page 46: MIPS PIPELINED CPU

// neu bang nhau thi tra ve ket qua equal =1

// neu khong thi equal = 0

output equal;

wire equal;

input [31:0] Addr1,Addr2;

wire [31:0] Addr1,Addr2,xorAddress;

xor #(50) xorAddress0(xorAddress[31],Addr1[31],Addr2[31]);

xor #(50) xorAddress0(xorAddress[30],Addr1[30],Addr2[30]);

xor #(50) xorAddress0(xorAddress[29],Addr1[29],Addr2[29]);

xor #(50) xorAddress0(xorAddress[28],Addr1[28],Addr2[28]);

xor #(50) xorAddress0(xorAddress[27],Addr1[27],Addr2[27]);

xor #(50) xorAddress0(xorAddress[26],Addr1[26],Addr2[26]);

xor #(50) xorAddress0(xorAddress[25],Addr1[25],Addr2[25]);

xor #(50) xorAddress0(xorAddress[24],Addr1[24],Addr2[24]);

xor #(50) xorAddress0(xorAddress[23],Addr1[23],Addr2[23]);

xor #(50) xorAddress0(xorAddress[22],Addr1[22],Addr2[22]);

xor #(50) xorAddress0(xorAddress[21],Addr1[21],Addr2[21]);

xor #(50) xorAddress0(xorAddress[20],Addr1[20],Addr2[20]);

xor #(50) xorAddress0(xorAddress[19],Addr1[19],Addr2[19]);

xor #(50) xorAddress0(xorAddress[18],Addr1[18],Addr2[18]);

xor #(50) xorAddress0(xorAddress[17],Addr1[17],Addr2[17]);

xor #(50) xorAddress0(xorAddress[16],Addr1[16],Addr2[16]);

xor #(50) xorAddress0(xorAddress[15],Addr1[15],Addr2[15]);

xor #(50) xorAddress0(xorAddress[14],Addr1[14],Addr2[14]);

Page 47: MIPS PIPELINED CPU

xor #(50) xorAddress0(xorAddress[13],Addr1[13],Addr2[13]);

xor #(50) xorAddress0(xorAddress[12],Addr1[12],Addr2[12]);

xor #(50) xorAddress0(xorAddress[11],Addr1[11],Addr2[11]);

xor #(50) xorAddress0(xorAddress[10],Addr1[10],Addr2[10]);

xor #(50) xorAddress0(xorAddress[9],Addr1[9],Addr2[9]);

xor #(50) xorAddress0(xorAddress[8],Addr1[8],Addr2[8]);

xor #(50) xorAddress0(xorAddress[7],Addr1[7],Addr2[7]);

xor #(50) xorAddress0(xorAddress[6],Addr1[6],Addr2[6]);

xor #(50) xorAddress0(xorAddress[5],Addr1[5],Addr2[5]);

xor #(50) xorAddress4(xorAddress[4],Addr1[4],Addr2[4]);

xor #(50) xorAddress3(xorAddress[3],Addr1[3],Addr2[3]);

xor #(50) xorAddress2(xorAddress[2],Addr1[2],Addr2[2]);

xor #(50) xorAddress1(xorAddress[1],Addr1[1],Addr2[1]);

xor #(50) xorAddress0(xorAddress[0],Addr1[0],Addr2[0]);

or #(50) Orgate1(OrAddr,xorAddress[0],xorAddress[1],xorAddress[2],xorAddress[3],xorAddress[4],xorAddress[5],xorAddress[6],xorAddress[7],xorAddress[8], xorAddress[9],xorAddress[10],xorAddress[11],xorAddress[12],xorAddress[13],xorAddress[14],xorAddress[15],xorAddress[16],xorAddress[17] , xorAddress[18],xorAddress[19],xorAddress[20],xorAddress[21],xorAddress[22],xorAddress[23],xorAddress[24],xorAddress[24],xorAddress[26], xorAddress[27],xorAddress[28],xorAddress[29],xorAddress[30], xorAddress[31]);

not #(50) notgate1(equal,OrAddr);

endmodule

5. Thiết kế thanh ghi trung gian

Page 48: MIPS PIPELINED CPU

a. Thanh ghi IF/ID

module IFID(flush,clock,IFIDWrite,IFpc_plus_4,Inst,InstReg,IDpc_plus_4);

input [31:0] IFpc_plus_4,Inst;

input clock,IFIDWrite,flush;

output [31:0] InstReg, IDpc_plus_4;

reg [31:0] InstReg,IDpc_plus_4;

initial begin

InstReg = 32'b0;

IDpc_plus_4 = 32'b0;

end

always@(posedge clock)

begin

if(flush)

begin

InstReg <= 32'b0;

IDpc_plus_4 <=IFpc_plus_4;

end

else if(IFIDWrite)

begin

InstReg <= Inst;

IDpc_plus_4 <= IFpc_plus_4;

end

end

Page 49: MIPS PIPELINED CPU

endmodule

b.Thanh ghi ID/EX

module IDEX(clock,WB,M,EX,DataA,DataB,imm_value,RegRs,RegRt,RegRd,WBreg,Mreg,EXreg,DataAreg,

DataBreg,imm_valuereg,RegRsreg,RegRtreg,RegRdreg);

input clock;

input [1:0] WB;

input [2:0] M;

input [3:0] EX;

input [4:0] RegRs,RegRt,RegRd;

input [31:0] DataA,DataB,imm_value;

output [1:0] WBreg;

output [2:0] Mreg;

output [3:0] EXreg;

output [4:0] RegRsreg,RegRtreg,RegRdreg;

output [31:0] DataAreg,DataBreg,imm_valuereg;

reg [1:0] WBreg;

reg [2:0] Mreg;

reg [3:0] EXreg;

reg [31:0] DataAreg,DataBreg,imm_valuereg;

reg [4:0] RegRsreg,RegRtreg,RegRdreg;

Page 50: MIPS PIPELINED CPU

/* initial begin

WBreg = 0;

Mreg = 0;

EXreg = 0;

DataAreg = 0;

DataBreg = 0;

imm_valuereg = 0;

RegRsreg = 0;

RegRtreg = 0;

RegRdreg = 0;

end */

always@(posedge clock)

begin

WBreg <= WB;

Mreg <= M;

EXreg <= EX;

DataAreg <= DataA;

DataBreg <= DataB;

imm_valuereg <= imm_value;

RegRsreg <= RegRs;

RegRtreg <= RegRt;

RegRdreg <= RegRd;

end

Page 51: MIPS PIPELINED CPU

endmodule

c.Thanh ghi EX/MEM

module EXMEM(clock,WB,M,ALUOut,RegRD,WriteDataIn,Mreg,WBreg,ALUreg,RegRDreg,WriteDataOut);

input clock;

input [1:0] WB;

input [2:0] M;

input [4:0] RegRD;

input [31:0] ALUOut,WriteDataIn;

output [1:0] WBreg;

output [2:0] Mreg;

output [31:0] ALUreg,WriteDataOut;

output [4:0] RegRDreg;

reg [1:0] WBreg;

reg [2:0] Mreg;

reg [31:0] ALUreg,WriteDataOut;

reg [4:0] RegRDreg;

initial begin

WBreg=0;

Mreg=0;

ALUreg=0;

WriteDataOut=0;

Page 52: MIPS PIPELINED CPU

RegRDreg=0;

end

always@(posedge clock)

begin

WBreg <= WB;

Mreg <= M;

ALUreg <= ALUOut;

RegRDreg <= RegRD;

WriteDataOut <= WriteDataIn;

end

endmodule

d.Thanh ghi MEM/WB

module MEMWB(clock,WB,Memout,ALUOut,RegRD,WBreg,Memreg,ALUreg,RegRDreg);

input clock;

input [1:0] WB;

input [4:0] RegRD;

input [31:0] Memout,ALUOut;

output [1:0] WBreg;

output [31:0] Memreg,ALUreg;

output [4:0] RegRDreg;

Page 53: MIPS PIPELINED CPU

reg [1:0] WBreg;

reg [31:0] Memreg,ALUreg;

reg [4:0] RegRDreg;

initial begin

WBreg = 0;

Memreg = 0;

ALUreg = 0;

RegRDreg = 0;

end

always@(posedge clock)

begin

WBreg <= WB;

Memreg <= Memout;

ALUreg <= ALUOut;

RegRDreg <= RegRD;

end

endmodule

4.2. Thiết kế khối xử lý Hazard

a. Xử lý bằng Forwarding

module ForwardUnit(MEMRegRd,WBRegRd,EXRegRs,EXRegRt, MEM_RegWrite, WB_RegWrite, ForwardA, ForwardB);

input[4:0] MEMRegRd,WBRegRd,EXRegRs,EXRegRt;

Page 54: MIPS PIPELINED CPU

input MEM_RegWrite, WB_RegWrite;

output[1:0] ForwardA, ForwardB;

reg[1:0] ForwardA, ForwardB;

//Forward A

always@(MEM_RegWrite or MEMRegRd or EXRegRs or WB_RegWrite or WBRegRd)

begin

if((MEM_RegWrite)&&(MEMRegRd != 0)&&(MEMRegRd == EXRegRs))

ForwardA = 2'b01;

else if((WB_RegWrite)&&(WBRegRd != 0)&&(WBRegRd == EXRegRs)&&(MEMRegRd != EXRegRs) )

ForwardA = 2'b10;

else

ForwardA = 2'b00;

end

//Forward B

always@(WB_RegWrite or WBRegRd or EXRegRt or MEMRegRd or MEM_RegWrite)

begin

if((WB_RegWrite)&&(WBRegRd != 0)&&(WBRegRd == EXRegRt)&&(MEMRegRd != EXRegRt) )

ForwardB = 2'b01;

Page 55: MIPS PIPELINED CPU

else if((MEM_RegWrite)&&(MEMRegRd != 0)&&(MEMRegRd == EXRegRt))

ForwardB = 2'b10;

else

ForwardB = 2'b00;

end

endmodule

b.Xử lý bằng Stalling

module HazardUnit(IDRegRs,IDRegRt,EXRegRt,EXMemRead,PCWrite,IFIDWrite,HazMuxCon);

input [4:0] IDRegRs,IDRegRt,EXRegRt;

input EXMemRead;

output PCWrite, IFIDWrite, HazMuxCon;

//output IFflush;

reg PCWrite, IFIDWrite, HazMuxCon;

always@(IDRegRs,IDRegRt,EXRegRt,EXMemRead)

if(EXMemRead&((EXRegRt == IDRegRs)|(EXRegRt == IDRegRt)))

begin//stall

PCWrite = 0;

IFIDWrite = 0;

HazMuxCon = 0;

//IFflush = 1;

end

else

Page 56: MIPS PIPELINED CPU

begin//no stall

PCWrite = 1;

IFIDWrite = 1;

HazMuxCon = 1;

//IFflush = 0;

end

endmodule

c. Flush

module flushcontrol(IDEXcon,IDMcon,IDWBcon,WB,EX,M,HazMuxCon);

input [3:0]EX;

input [2:0]M;

input [1:0]WB;

input HazMuxCon;

output [3:0]IDEXcon;

output [2:0]IDMcon;

output [1:0]IDWBcon;

mux2to1 mux0 (1'b0, EX[0], HazMuxCon, IDEXcon[0 ]);

mux2to1 mux1 (1'b0, EX[1], HazMuxCon, IDEXcon[1 ]);

mux2to1 mux2 (1'b0, EX[2], HazMuxCon, IDEXcon[2 ]);

mux2to1 mux3 (1'b0, EX[3], HazMuxCon, IDEXcon[3 ]);

mux2to1 mux4 (1'b0, M[0], HazMuxCon, IDMcon[0 ]);

mux2to1 mux5 (1'b0, M[1], HazMuxCon, IDMcon[1 ]);

mux2to1 mux6 (1'b0, M[2], HazMuxCon, IDMcon[2 ]);

Page 57: MIPS PIPELINED CPU

mux2to1 mux7 (1'b0, WB[0], HazMuxCon, IDWBcon[0 ]);

mux2to1 mux8 (1'b0, WB[1], HazMuxCon, IDWBcon[1 ]);

endmodule

6. Jr

module Jr(MRd,IDRs,EXRd,ALUout,Rs,Jraddr);

input [4:0]MRd,IDRs,EXRd;

input [31:0]ALUout,Rs;

output [31:0]Jraddr;

reg seljr;

always@ (MRd or IDRs or EXRd)

begin

if ((MRd==IDRs)||(EXRd==IDRs))

seljr=1;

else

seljr=0;

end

mux2x32to32 muxjr(Rs,ALUout,seljr,Jraddr);

endmodule

7. mux2x5to5

module mux2x5to5(seg1,seg2,sel,segout);

input [4:0]seg1,seg2;

inout sel;

output [4:0]segout;

Page 58: MIPS PIPELINED CPU

mux2to1 sel1(seg1[0],seg2[0],sel,segout[0]);

mux2to1 sel2(seg1[1],seg2[1],sel,segout[1]);

mux2to1 sel3(seg1[2],seg2[2],sel,segout[2]);

mux2to1 sel4(seg1[3],seg2[3],sel,segout[3]);

mux2to1 sel5(seg1[4],seg2[4],sel,segout[4]);

endmodule

module mux2to1(DataIn0, DataIn1, Sel, DataOut);

input DataIn0, DataIn1, Sel;

output DataOut;

wire Data0, Data1;

and #(50) Sel0(Data0, DataIn0, (~Sel));

and #(50) Sel1(Data1, DataIn1, Sel );

or #(50) Out0(DataOut, Data0, Data1);

endmodule

8.Mux2x2to32

module mux2x32to32(DataIn0, DataIn1, Sel, DataOut);

input [31:0] DataIn0, DataIn1;

input Sel;

output [31:0] DataOut;

mux2to1 mux0 (DataIn0[0 ], DataIn1[0 ], Sel, DataOut[0 ]);

Page 59: MIPS PIPELINED CPU

mux2to1 mux1 (DataIn0[1 ], DataIn1[1 ], Sel, DataOut[1 ]);

mux2to1 mux2 (DataIn0[2 ], DataIn1[2 ], Sel, DataOut[2 ]);

mux2to1 mux3 (DataIn0[3 ], DataIn1[3 ], Sel, DataOut[3 ]);

mux2to1 mux4 (DataIn0[4 ], DataIn1[4 ], Sel, DataOut[4 ]);

mux2to1 mux5 (DataIn0[5 ], DataIn1[5 ], Sel, DataOut[5 ]);

mux2to1 mux6 (DataIn0[6 ], DataIn1[6 ], Sel, DataOut[6 ]);

mux2to1 mux7 (DataIn0[7 ], DataIn1[7 ], Sel, DataOut[7 ]);

mux2to1 mux8 (DataIn0[8 ], DataIn1[8 ], Sel, DataOut[8 ]);

mux2to1 mux9 (DataIn0[9 ], DataIn1[9 ], Sel, DataOut[9 ]);

mux2to1 mux10(DataIn0[10], DataIn1[10], Sel, DataOut[10]);

mux2to1 mux11(DataIn0[11], DataIn1[11], Sel, DataOut[11]);

mux2to1 mux12(DataIn0[12], DataIn1[12], Sel, DataOut[12]);

mux2to1 mux13(DataIn0[13], DataIn1[13], Sel, DataOut[13]);

mux2to1 mux14(DataIn0[14], DataIn1[14], Sel, DataOut[14]);

mux2to1 mux15(DataIn0[15], DataIn1[15], Sel, DataOut[15]);

mux2to1 mux16(DataIn0[16], DataIn1[16], Sel, DataOut[16]);

mux2to1 mux17(DataIn0[17], DataIn1[17], Sel, DataOut[17]);

mux2to1 mux18(DataIn0[18], DataIn1[18], Sel, DataOut[18]);

mux2to1 mux19(DataIn0[19], DataIn1[19], Sel, DataOut[19]);

mux2to1 mux20(DataIn0[20], DataIn1[20], Sel, DataOut[20]);

mux2to1 mux21(DataIn0[21], DataIn1[21], Sel, DataOut[21]);

mux2to1 mux22(DataIn0[22], DataIn1[22], Sel, DataOut[22]);

mux2to1 mux23(DataIn0[23], DataIn1[23], Sel, DataOut[23]);

mux2to1 mux24(DataIn0[24], DataIn1[24], Sel, DataOut[24]);

Page 60: MIPS PIPELINED CPU

mux2to1 mux25(DataIn0[25], DataIn1[25], Sel, DataOut[25]);

mux2to1 mux26(DataIn0[26], DataIn1[26], Sel, DataOut[26]);

mux2to1 mux27(DataIn0[27], DataIn1[27], Sel, DataOut[27]);

mux2to1 mux28(DataIn0[28], DataIn1[28], Sel, DataOut[28]);

mux2to1 mux29(DataIn0[29], DataIn1[29], Sel, DataOut[29]);

mux2to1 mux30(DataIn0[30], DataIn1[30], Sel, DataOut[30]);

mux2to1 mux31(DataIn0[31], DataIn1[31], Sel, DataOut[31]);

endmodule

/*module mux2to1(DataIn0, DataIn1, Sel, DataOut);

input DataIn0, DataIn1, Sel;

output DataOut;

wire Data0, Data1;

and #(50) Sel0(Data0, DataIn0, (~Sel));

and #(50) Sel1(Data1, DataIn1, Sel );

or #(50) Out0(DataOut, Data0, Data1);

endmodule*/

9. Mux3x32to32

module mux3x32to32(Sel, DataIN0, DataIN1, DataIN2, DataOUT);

parameter bitwidth = 32;

input [bitwidth-1:0] DataIN0;

input [bitwidth-1:0] DataIN1;

input [bitwidth-1:0] DataIN2;

input [1:0] Sel;

Page 61: MIPS PIPELINED CPU

output [bitwidth-1:0] DataOUT;

reg [bitwidth-1:0] DataOUT;

always @(Sel or DataIN0 or DataIN1 or DataIN2)

begin

case (Sel)

2'd0: DataOUT = DataIN0;

2'd1: DataOUT = DataIN1;

2'd2: DataOUT = DataIN2;

default: DataOUT = 32'hxxxx;

endcase

end

endmodule

10. Khối dịch trái

module Shiftleft2(Shift_in,Shift_out);

input [31:0]Shift_in;

output [31:0]Shift_out;

buf #(50) buf0(Shift_out[31],Shift_in[29]);

buf #(50) buf1(Shift_out[30],Shift_in[28]);

buf #(50) buf2(Shift_out[29],Shift_in[27]);

buf #(50) buf3(Shift_out[28],Shift_in[26]);

buf #(50) buf4(Shift_out[27],Shift_in[25]);

Page 62: MIPS PIPELINED CPU

buf #(50) buf5(Shift_out[26],Shift_in[24]);

buf #(50) buf6(Shift_out[25],Shift_in[23]);

buf #(50) buf7(Shift_out[24],Shift_in[22]);

buf #(50) buf8(Shift_out[23],Shift_in[21]);

buf #(50) buf9(Shift_out[22],Shift_in[20]);

buf #(50) buf10(Shift_out[21],Shift_in[19]);

buf #(50) buf11(Shift_out[20],Shift_in[18]);

buf #(50) buf12(Shift_out[19],Shift_in[17]);

buf #(50) buf13(Shift_out[18],Shift_in[16]);

buf #(50) buf14(Shift_out[17],Shift_in[15]);

buf #(50) buf15(Shift_out[16],Shift_in[14]);

buf #(50) buf16(Shift_out[15],Shift_in[13]);

buf #(50) buf17(Shift_out[14],Shift_in[12]);

buf #(50) buf18(Shift_out[13],Shift_in[11]);

buf #(50) buf19(Shift_out[12],Shift_in[10]);

buf #(50) buf20(Shift_out[11],Shift_in[9]);

buf #(50) buf21(Shift_out[10],Shift_in[8]);

buf #(50) buf22(Shift_out[9],Shift_in[7]);

buf #(50) buf23(Shift_out[8],Shift_in[6]);

buf #(50) buf24(Shift_out[7],Shift_in[5]);

buf #(50) buf25(Shift_out[6],Shift_in[4]);

buf #(50) buf26(Shift_out[5],Shift_in[3]);

buf #(50) buf27(Shift_out[4],Shift_in[2]);

buf #(50) buf28(Shift_out[3],Shift_in[1]);

Page 63: MIPS PIPELINED CPU

buf #(50) buf29(Shift_out[2],Shift_in[0]);

buf #(50) buf30(Shift_out[1],1'b0);

buf #(50) buf31(Shift_out[0],1'b0);

endmodule

11. Khối mở rộng

module sign_extend(In16, ex_control,Out32);

input [15:0] In16;

output [31:0] Out32;

input ex_control;

assign Out32[15:0]=In16;

and #(50) and1(Out32[16],ex_control,In16[15]);

and #(50) and2(Out32[17],ex_control,In16[15]);

and #(50) and3(Out32[18],ex_control,In16[15]);

and #(50) and4(Out32[19],ex_control,In16[15]);

and #(50) and5(Out32[20],ex_control,In16[15]);

and #(50) and6(Out32[21],ex_control,In16[15]);

and #(50) and7(Out32[22],ex_control,In16[15]);

and #(50) and8(Out32[23],ex_control,In16[15]);

and #(50) and9(Out32[24],ex_control,In16[15]);

and #(50) and10(Out32[25],ex_control,In16[15]);

and #(50) and11(Out32[26],ex_control,In16[15]);

and #(50) and12(Out32[27],ex_control,In16[15]);

and #(50) and13(Out32[28],ex_control,In16[15]);

and #(50) and14(Out32[29],ex_control,In16[15]);

Page 64: MIPS PIPELINED CPU

and #(50) and15(Out32[30],ex_control,In16[15]);

and #(50) and16(Out32[31],ex_control,In16[15]);

endmodule

12. Kết nối các khối đã thiết kế

`include "Add.v"

`include "ALU.v"

`include "ALU_control.v"

`include "Compare.v"

`include "Control.v"

`include "datamem.v"

`include "EXMEM.v"

`include "ForwardUnit.v"

`include "HazardUnit.v"

`include "IDEX.v"

`include "IFID.v"

`include "Instructionmem.v"

`include "MEMWB.v"

`include "mux2x5to5.v"

`include "mux2x32to32.v"

`include "mux3x32to32.v"

`include "regfile.v"

`include "Shiftleft2.v"

`include "sign_extend.v"

Page 65: MIPS PIPELINED CPU

`include "PC_Block.v"

`include "flushcontrol.v"

`include "Jr.v"

module MIPS2(clock,reset);

input clock,reset;

//debugging vars

reg [31:0] cycle;

//IF vars

wire [31:0]IFpc_plus_4,IFinst;

wire [31:0] PC,PCin;

wire IFFlush;

//ID vars

wire PCSrc;

wire [4:0] IDRegRs,IDRegRt,IDRegRd;

wire [31:0] IDpc_plus_4,IDinst;

wire [31:0] IDRegAout, IDRegBout;

wire [31:0] IDimm_value,BranchAddr,JumpTarget;

wire [31:0] Bran;

wire jr_control,branchsel,bneflag;

//control vars in ID stage

wire PCWrite,IFIDWrite,HazMuxCon,Branch,Jump,ex_control;

wire [8:0] IDcontrol;

wire branchflag;

Page 66: MIPS PIPELINED CPU

wire [3:0]EX,IDEXcon;

wire [2:0]M,IDMcon;

wire [1:0]WB,IDWBcon;

//EX vars

wire [1:0] ALUcontrol;

wire [1:0] EXWB,ForwardA,ForwardB,aluop;

wire [2:0] EXM;

wire [3:0] EXEX,ALUCon;

wire [4:0] EXRegRs,EXRegRt,EXRegRd,regtopass;

wire [31:0] EXRegAout,EXRegBout,EXimm_value, b_value;

wire [31:0] EXALUOut,ALUSrcA,ALUSrcB;

wire CarryFlag,ZeroFlag,OverflowFlag,NegativeFlag,jrcontrol;

wire [31:0]outbranch_jr,JrAddr;

//MEM vars

wire [1:0] MEMWB;

wire [2:0] MEMM;

wire [4:0] MEMRegRd;

wire [31:0] MEMALUOut,MEMWriteData,MEMReadData;

//WB vars

wire [1:0] WBWB;

wire [4:0] WBRegRd;

wire [31:0] datatowrite,WBReadData,WBALUOut;

PC_Block PCreg(PCin,PC,PCWrite,clock,reset);

Add Add1(PC,{29'b0,3'b100},IFpc_plus_4); // PC4 = PC + 4

Page 67: MIPS PIPELINED CPU

/**

* Instruction Decode (ID)

*/

InstructionMem IM(PC,IFinst);

IFID IFIDreg(IFFlush,clock,IFIDWrite,IFpc_plus_4,IFinst,IDinst,IDpc_plus_4);

Jr Jraddress(MEMRegRd,IDRegRs,EXRegRd,MEMALUOut,IDRegAout,JrAddr);

mux3x32to32 muxBranch_jr({branchsel,jr_control},IDpc_plus_4,JrAddr,BranchAddr,outbranch_jr);

mux2x32to32 muxjump(outbranch_jr,{IDpc_plus_4[31:28],JumpTarget[27:0]},Jump,PCin);

assign IDRegRs[4:0]=IDinst[25:21];

assign IDRegRt[4:0]=IDinst[20:16];

assign IDRegRd[4:0]=IDinst[15:11];

Shiftleft2 shiftleft2_2({6'b0,IDinst[25:0]},JumpTarget);

// harzard unit to stall or not stall

HazardUnit HU (IDRegRs,IDRegRt,EXRegRt,EXM[1],PCWrite, IFIDWrite,HazMuxCon);

or #(50) orflush(IFFlush,jr_control);

// control unit

Control thecontrol(IDinst[31:26],Jump,Branch,EX,M,WB,ex_control);

and #(50) andjr(jr_control,EX[1],~(EX[0]),~(IDinst[5]),~(IDinst[4]),

Page 68: MIPS PIPELINED CPU

IDinst[3],~(IDinst[2]),~(IDinst[1]),~(IDinst[0]));// Jr control

// register file

regfile regfile_block(IDRegAout,IDRegBout,datatowrite,IDRegRs,

IDRegRt,WBRegRd,WBWB[1],clock,reset);

sign_extend sign_extend1(IDinst[15:0],ex_control,IDimm_value); //signextend

Shiftleft2 shitfleft2_1(IDimm_value,Bran);

Add Add_branch(Bran,IDpc_plus_4,BranchAddr); // tinh dai chi lenh bracnh

flushcontrol flushct(IDEXcon,IDMcon,IDWBcon,WB,EX,M,HazMuxCon); // flush control signal if stall

// for branch inst

Compare compare_branch(branchflag,IDRegAout,IDRegBout);// compare rs , rs to sel branchflag fo branch inst

not #(50) notbranch(bneflag,branchflag);

and #(50) andbranch(branchsel,Branch,bneflag);// have bne control sig

// IDEX register

IDEX IDEXreg(clock,IDWBcon,IDMcon,IDEXcon,IDRegAout,IDRegBout,IDimm_value,

Page 69: MIPS PIPELINED CPU

IDRegRs,IDRegRt,IDRegRd,EXWB,EXM,EXEX,EXRegAout,EXRegBout,EXimm_value,EXRegRs,EXRegRt,EXRegRd);

/**

* Execution (EX)

*/

mux2x5to5 muxdest( EXRegRt,EXRegRd,EXEX[3],regtopass); // select EXRegRt,EXRegRd to EXMEM

mux2x32to32 muxalu(EXRegBout,EXimm_value,EXEX[2],b_value);

mux3x32to32 MUX0(ForwardA,EXRegAout,MEMALUOut,datatowrite,ALUSrcA);

//forward a

mux3x32to32 MUX2(ForwardB,b_value,MEMALUOut,datatowrite,ALUSrcB);

//forward b

//ALU control

ALU_control ALU_control1(ALUcontrol,jrcontrol, EXEX[1:0],EXimm_value[5:0]);

// ALU unit

ALU ALU1(EXALUOut,CarryFlag,ZeroFlag,OverflowFlag,NegativeFlag,ALUSrcA,ALUSrcB,ALUcontrol);

// EXMEM register

EXMEM EXMEMreg(clock,EXWB,EXM,EXALUOut,regtopass,EXRegBout,MEMM,MEMWB,MEMALUOut,MEMRegRd,MEMWriteData);

/**

Page 70: MIPS PIPELINED CPU

* Memory (Mem)

*/

datamem datamem1( MEMReadData, //data

MEMALUOut, //address

MEMWriteData, //writedata

MEMM[1], //readenable

MEMM[0], //writeenable

clock );

ForwardUnit FU(MEMRegRd,WBRegRd,EXRegRs, EXRegRt, MEMWB[1], WBWB[1], ForwardA, ForwardB); // forward unit: get forward control

MEMWB MEMWBreg(clock,MEMWB,MEMReadData,MEMALUOut,MEMRegRd,WBWB,WBReadData,WBALUOut,WBRegRd); // MEMWB register

/**

* Write Back (WB)

*/

mux2x32to32 muxWB(WBALUOut,WBReadData,WBWB[0],datatowrite); // mux select value to writeback

endmodule

13. Testbench

`timescale 1 ps / 100 fs

// The verilog file containing your register file must

Page 71: MIPS PIPELINED CPU

// be named "MIPS.v".

`include "MIPS2.v"

module MIPStimulus();

parameter ClockDelay = 10000;

reg reset, clk;

wire [31:0] PC;

wire [31:0] instruction;

integer i;

// Your register file MUST be named "regfile".

// Also you must make sure that the port declarations

// match up with the module instance in this stimulus file.

MIPS2 MIPS1(clk, reset);

initial begin

$dumpfile("single.vcd");

$dumpvars(-1, MIPS1);

end

initial clk = 0;

initial reset=1;

always #(ClockDelay/2) clk = ~clk;

initial

begin

Page 72: MIPS PIPELINED CPU

#(ClockDelay/2) reset=0;

// Try to write the value 0xA0 into register 0.

// Register 0 should begin and remain at the value of 0.

end

endmodule