ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
PHÂN CÔNG CÔNG VIỆC ĐỒ ÁN CẤU TRÚC MÁY TÍNH
LAB3: DESIGN A MIPS 32-BIT SINGLE - CYCLE CPU 1. Công việc cụ thể STT
Tên thành viên
1
Nguyễn Văn Cường
2
Đặng Ngọc Hoàng
3
Lê Hữu Việt
Công việc + Tìm hiểu lại LAB 1: Thiết kế RegisterFile 32 by 32 +Tìm hiểu hoạt động và thiết kế : Khối Control, Khối dịch trái, Khối mở rộng + Slide: phần I. + Tìm hiểu lại LAB2: Thiết kế bộ tính toán ALU. +Tìm hiểu hoạt động và thiết kế: Thanh ghi PC, Khối JR_Control, Các khối Multiplexor + Slide: phần II 1,2. + Tìm hiểu lại chương 4 sách COD Tìm hiểu hoạt động và thiết kế: ALUControl, MIPS, Khối mô phỏng Stimulate + Slide: phần II3,III. + Báo cáo. + Mô phỏng lệnh trên Quartus
Đóng góp
30%
30%
40%
2. Tiến trình làm việc: - Tìm hiểu tài liệu theo nhiệm vụ được giao. - Thảo luận nhóm thống nhất sơ đồ khối cần thực hiện. - Viết Code cho từng khối. - Chia sẻ hiểu biết của từng thành viên trong nhóm về phần mình thiết kế. - Ghép nối các khối với nhau, hiệu chỉnh thiết kế. - Mô phỏng trên ModelSim và sơ đồ khối ở Quartus.
NHÓM 28
Page 1
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
Lab3: Design a MIPS 32-bit Single-Cycle CPU Yêu cầu thiết kế:
I.
1. Yêu cầu chung: - Thiết kế bộ xử lý trung tâm MIPS chu kì đơn 32-bit thực hiện các lệnh: ADD, SUB, SLT, JR, LW, SW, BNE, XORI, J - Các cổng logic không có quá 4 ngõ vào, với delay 50ps. - Các khối điều khiển logic có thể dùng cấu trúc lệnh behavioral. 2. Tập lệnh: -
Lệnh loại R:
ADD rd, rs, rt:
Reg[rd] = Reg[rs] + Reg[rt].
JR rs:
PC = Reg[rs].
SLT rd, rs, rt:
If (Reg[rs] < Reg[rt]) Reg[rd] = 0x00000001 else Reg[rd] = 0x00000000.
SUB rd, rs, rt:
Reg[rd] = Reg[rs] – Reg[rt].
NHÓM 28
Page 2
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
-
Lệnh loại I:
BNE rs, rt, imm16: if (Reg[rs]!= Reg[rt])PC = PC + 4 + Sign_ext(Imm16)<<2 else PC = PC + 4.
LW rt, imm16(rs): Reg[rt] = Mem[Reg[rs] + Sign_ext(Imm16)].
SW rt, imm16(rs): Mem[Reg[rs] + Sign_ext(Imm16)] = Reg[rt].
XORI rt, rs, imm16: Reg[rt] = Reg[rs] XOR Zero_ext(Imm16).
-
Lệnh JUMP:
J target: PC = { PC[31:28], target, 00 }
NHÓM 28
Page 3
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
II.
NHÓM 28
Xây dựng SingleClock CPU:
Page 4
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
-
Từ sơ đồ khối tổng quát của CPU, thiết kế 1 CPU đơn chu kì yêu cầu: + Thanh ghi lệnh PC + Bộ nhớ lệnh + Bộ thanh ghi + Bộ tính toán ALU + Bộ nhớ dữ liệu + Bộ điều khiển trung tâm + Bộ điều khiển khối ALU + Bộ điều khiển lệnh JR + Bộ mở rộng dấu + Bộ dịch trái + Bộ multiplexor
1. Program Counter: - Thanh ghi thực hiện nhiệm vụ trỏ tới lệnh tiếp theo được thực hiện. - Cấu tạo gồm 32 D-FlipFlop Code: module PC_Register(PCout,PCin,reset,clk); output [31:0] PCout; input [31:0] PCin; input reset,clk; D_FF dff0(PCout[0],PCin[0],reset,clk); D_FF dff2(PCout[2],PCin[2],reset,clk); D_FF dff4(PCout[4],PCin[4],reset,clk); D_FF dff6(PCout[6],PCin[6],reset,clk); D_FF dff8(PCout[8],PCin[8],reset,clk); D_FF dff10(PCout[10],PCin[10],reset,clk); D_FF dff12(PCout[12],PCin[12],reset,clk); D_FF dff14(PCout[14],PCin[14],reset,clk); D_FF dff16(PCout[16],PCin[16],reset,clk); D_FF dff18(PCout[18],PCin[18],reset,clk); D_FF dff20(PCout[20],PCin[20],reset,clk); D_FF dff22(PCout[22],PCin[22],reset,clk); D_FF dff24(PCout[24],PCin[24],reset,clk); D_FF dff26(PCout[26],PCin[26],reset,clk); D_FF dff28(PCout[28],PCin[28],reset,clk); D_FF dff30(PCout[30],PCin[30],reset,clk); Endmodule
D_FF dff1(PCout[1],PCin[1],reset,clk); D_FF dff3(PCout[3],PCin[3],reset,clk); D_FF dff5(PCout[5],PCin[5],reset,clk); D_FF dff7(PCout[7],PCin[7],reset,clk); D_FF dff9(PCout[9],PCin[9],reset,clk); D_FF dff11(PCout[11],PCin[11],reset,clk); D_FF dff13(PCout[13],PCin[13],reset,clk); D_FF dff15(PCout[15],PCin[15],reset,clk); D_FF dff17(PCout[17],PCin[17],reset,clk); D_FF dff19(PCout[19],PCin[19],reset,clk); D_FF dff21(PCout[21],PCin[21],reset,clk); D_FF dff23(PCout[23],PCin[23],reset,clk); D_FF dff25(PCout[25],PCin[25],reset,clk); D_FF dff27(PCout[27],PCin[27],reset,clk); D_FF dff29(PCout[29],PCin[29],reset,clk); D_FF dff31(PCout[31],PCin[31],reset,clk);
2. Bộ nhớ lệnh: - Bộ nhớ lệnh nhận ngõ ra của PC làm địa chỉ của lệnh tiếp theo được thực hiện. NHÓM 28
Page 5
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
-
Ngõ ra 32 bit là lệnh được thực hiên. Code:
module InstructionMem(instruction, address); input [31:0] address; output [31:0] instruction; reg [31:0]instrmem[1023:0]; reg [31:0] temp; buf #1000 buf0(instruction[0],temp[0]), buf1(instruction[1],temp[1]), buf2(instruction[2],temp[2]), 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]), 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 NHÓM 28
Page 6
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 begin $readmemb("instr.txt", instrmem); end endmodule module instrmemstimulous(); reg [31:0] addr; wire [31:0] instr; InstructionMem instructionmemory(instr, addr); initial begin $monitor("Mem Address=%h instruction=%b",addr,instr); addr=32'd0; #10000 addr=32'd4; #10000 addr=32'd8; #10000 addr=32'd12; #10000 addr=32'd16; #10000 addr=32'd20; #10000 addr=32'd24; #10000 addr=32'd28; #10000 addr=32'd32; #10000 addr=32'd36; #10000 addr=32'd40; #10000 addr=32'd44; #10000 addr=32'd48; #10000; $finish; end endmodule
3. Register File: + 32 thanh ghi 32 bit, riêng thanh ghi đầu tiên( R0) thì luôn mang giá trị 0. + Có 2 ngõ vào chọn thanh ghi đọc (Read Register 1 và Read Register 2) và 2 ngõ ra dữ liệu (Read Data 1 và Dead Data 2) + Có 1 ngõ vào chọn thanh ghi để ghi dữ liệu (Write register) , 1 ngõ vào cho phép ghi (RegWrite) và1 ngõ vào dữ liệu (Write Data) khi ghi vào file thanh ghi.
Sơ đồ khối:
NHÓM 28
Page 7
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
Code: module RegisterFile(RD1,RD2,WD,RR1,RR2,WR,RW,reset,clk); // RR : Read Register input [4:0]RR1,RR2,WR; // WR : Write Register input [31:0]WD ; // WD : Write Data input RW,clk,reset; // RW : RegWrite output [31:0]RD1,RD2; // RD : Read Data wire [31:0]x; // x : ngõ ra cua bo decoder5_32 wire[31:0]R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,R16,R17,R18,R19,R20,R21, R22,R23,R24,R25,R26,R27,R28,R29,R30,R31; decoder5_32 d(WR,x[31:0],RW); // chọn thanh ghi đích mux32x32_32 m1(RD1,RR1,R31,R30,R29,R28,R27,R26,R25,R24,R23,R22,R21,R20,R19,R18,R17,R16,R15,R14,R13,R1 2,R11,R10,R9,R8,R7,R6,R5,R4,R3,R2,R1,R0); // chọn thanh ghi nguồn Rs mux32x32_32 m2(RD2,RR2,R31,R30,R29,R28,R27,R26,R25,R24,R23,R22,R21,R20,R19,R18,R17,R16,R15,R14,R13,R1 2,R11,R10,R9,R8,R7,R6,R5,R4,R3,R2,R1,R0); // chọn thah ghi nguồn Rt reg32bit r0(32'b0,R0[31:0],clk,reset,x[0]); reg32bit r16(WD,R16[31:0],clk,reset,x[16]); reg32bit r1(WD,R1[31:0],clk,reset,x[1]); reg32bit r17(WD,R17[31:0],clk,reset,x[17]); reg32bit r2(WD,R2[31:0],clk,reset,x[2]); reg32bit r18(WD,R18[31:0],clk,reset,x[18]); reg32bit r3(WD,R3[31:0],clk,reset,x[3]); reg32bit r19(WD,R19[31:0],clk,reset,x[19]); reg32bit r4(WD,R4[31:0],clk,reset,x[4]); reg32bit r20(WD,R20[31:0],clk,reset,x[20]); reg32bit r5(WD,R5[31:0],clk,reset,x[5]); reg32bit r21(WD,R21[31:0],clk,reset,x[21]); reg32bit r6(WD,R6[31:0],clk,reset,x[6]); reg32bit r22(WD,R22[31:0],clk,reset,x[22]); reg32bit r7(WD,R7[31:0],clk,reset,x[7]); reg32bit r23(WD,R23[31:0],clk,reset,x[23]); reg32bit r8(WD,R8[31:0],clk,reset,x[8]); reg32bit r24(WD,R24[31:0],clk,reset,x[24]); reg32bit r9(WD,R9[31:0],clk,reset,x[9]); reg32bit r25(WD,R25[31:0],clk,reset,x[25]); reg32bit r10(WD,R10[31:0],clk,reset,x[10]); reg32bit r26(WD,R26[31:0],clk,reset,x[26]); reg32bit r11(WD,R11[31:0],clk,reset,x[11]); reg32bit r27(WD,R27[31:0],clk,reset,x[27]); reg32bit r12(WD,R12[31:0],clk,reset,x[12]); reg32bit r28(WD,R28[31:0],clk,reset,x[28]); reg32bit r13(WD,R13[31:0],clk,reset,x[13]); reg32bit r29(WD,R29[31:0],clk,reset,x[29]); reg32bit r14(WD,R14[31:0],clk,reset,x[14]); reg32bit r30(WD,R30[31:0],clk,reset,x[30]); reg32bit r15(WD,R15[31:0],clk,reset,x[15]); reg32bit r31(WD,R31[31:0],clk,reset,x[31]);
4. Bộ tính toán – ALU:
-
Cấu tạo MIPS ALU: + 2 ngõ vào BusA và BusB 32
bit + 1 ngõ ra Output 32 bit + Các cờ ngõ ra: zero, overflow, carryout, negative Cờ zero: được set khi kết quả bằng 0 NHÓM 28
Page 8
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
Cờ overflow (tràn khi thực hiện cộng trừ với số có dấu): đươc set khi xảy ra tràn Cờ carryout (tràn khi thực hiện cộng trừ với số không dấu): xảy ra khi có nhớ (mượn) từ MSB Cờ negative: được set nếu kết quả âm + Ngõ vào điều khiển ALUcontrol gồm 2 bit xác định phép toán mà ALU cần thực hiện:
Bảng 1. Tín hiệu điều khiển ALU module ALU(out,a,b,carry, zero, overflow,negative , AluControl); output [31:0]out; output zero, negative, overflow, carry; input [31:0]a, b; input [1:0] AluControl; wire [31:0]sum,sub,xo,slt; wire ofadd,ofsub; wire cadd,csub; Add_32bit add0(a,b,cadd,ofadd,sum); Sub_32bit sub0(a,b,csub,ofsub,sub); Slt_32bit slt0(a,b,slt); Xor_32bit xor0(a,b,xo); mux4x32_32 mux(out,AluControl,slt,sub,xo,sum); //CO OVERFLOW ( BO CONG VA TRU) wire [2:0]t; and #50 and0(t[0],(~AluControl[1]),ofadd); and #50and1(t[1],AluControl[1],ofsub); or #50 or0(t[2],t[0],t[1]); and #50 and2(overflow,t[2],(~AluControl[0])); // CO NEGATIVE assign negative = out[31]; //Co zero wire [9:0]x; or #50 or01(x[0],out[0],out[1],out[2],out[3]); or #50 or02(x[1],out[4],out[5],out[6],out[7]); NHÓM 28
Page 9
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 or or or or or or
#50 or03(x[2],out[8],out[9],out[10],out[11]); #50 or04(x[3],out[12],out[13],out[14],out[15]); #50 or05(x[4],out[16],out[17],out[18],out[19]); #50 or06(x[5],out[20],out[21],out[22],out[23]); #50 or07(x[6],out[24],out[25],out[26],out[27]); #50 or08(x[7],out[28],out[29],out[30],out[31]);
or or nor
#50 or9(x[8], x[3], x[2], x[1], x[0]); #50 or10(x[9], x[7], x[6], x[5], x[4]); #50 nor0(zero, x[8], x[9]);
//Co carry wire [2:0]y; and #50 and3(y[0],(~AluControl[1]),cadd); and #50and4(y[1],AluControl[1],csub); or #50 or11(y[2],y[0],y[1]); and #50 and5(carry,y[2],(~AluControl[0])); endmodule
NHÓM 28
Page 10
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
5. Bộ nhớ dữ liệu – Data Memory: - Nhận kết quả của bộ ALU làm địa chỉ ngõ vào. - Nếu có thao tác đọc dữ liệu ra ( lệnh LW) thì MemRead được set 1 ( cho phép đọc dữ liệu ra). - Nếu có thao tác ghi dữ liệu vào bộ nhớ (lệnh SW) thì MemWrite được set lên 1 ( cho phép ghi dữ liệu vào). Code: module DataMem(readdata, address, writedata, writeenable,MemRead,clk); input [31:0] address, writedata; input writeenable,MemRead, clk; output [31:0] readdata; reg [7:0] datamem[1023:0]; reg [31:0] temp; buf #1000 buf0(readdata[0],temp[0]), buf16(readdata[16],temp[16]), buf1(readdata[1],temp[1]), buf17(readdata[17],temp[17]), buf2(readdata[2],temp[2]), buf18(readdata[18],temp[18]), buf3(readdata[3],temp[3]), buf19(readdata[19],temp[19]), buf4(readdata[4],temp[4]), buf20(readdata[20],temp[20]), buf5(readdata[5],temp[5]), buf21(readdata[21],temp[21]), buf6(readdata[6],temp[6]), buf22(readdata[22],temp[22]), buf7(readdata[7],temp[7]), buf23(readdata[23],temp[23]), buf8(readdata[8],temp[8]), buf24(readdata[24],temp[24]), buf9(readdata[9],temp[9]), buf25(readdata[25],temp[25]), buf10(readdata[10],temp[10]), buf26(readdata[26],temp[26]), buf11(readdata[11],temp[11]), buf27(readdata[27],temp[27]), buf12(readdata[12],temp[12]), buf28(readdata[28],temp[28]), buf13(readdata[13],temp[13]), buf29(readdata[29],temp[29]), buf14(readdata[14],temp[14]), buf30(readdata[30],temp[30]), buf15(readdata[15],temp[15]), buf31(readdata[31],temp[31]); always @(posedge clk) if (writeenable) begin datamem[address]=writedata[31:24]; datamem[address+1]=writedata[23:16]; datamem[address+2]=writedata[15:8]; datamem[address+3]=writedata[7:0]; end always @(address or datamem[address] or datamem[address+1] or datamem[address+2] or datamem[address+3]) begin temp={datamem[address],datamem[address+1],datamem[address+2],datamem[address+3]}; end NHÓM 28
Page 11
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 initial begin $writememb("data.txt", datamem); end endmodule
6. Khối điều khiển trung tâm – Control Unit: - Tạo ra các tín hiệu điều khiển: + RegDst: Chọn thanh ghi đích cho RegisterFile. RegDst = 0: Rt là thanh ghi đích, lệnh loại I. RegDst = 1: Rd là thanh ghi đích, lệnh loại R. + Jump: Cho phép thực hiện lệnh nhảy JUMP. + Branch: Cho phép thực hiện lệnh nhảy BNE. + MemRead: Cho phép đọc từ bộ nhớ dữ liệu. + MemWrite Cho phép ghi dữ liệu vào DataMemory. + ALUSrc: Chọn ngõ vào thứ 2 cho bộ ALU. ALUSrc = 0: Ngõ vào là giá trị của thanh ghi nguồn ( lệnh loại R). ALUSrc = 1: Ngõ vào là giá 32-bit mở rộng dấu hoặc mở rộng không. + RegWrite: Cho phép ghi dữ liệu vào thanh ghi đích. + MemtoReg:Chọn giá trị ghi của RegisterFile là kết quả của bộ ALU hoặc dữ liệu từ Data Memory. MemtoReg = 0: đưa về kết quả của bộ ALU . MemtoReg = 1: đưa về dữ liệu từ DataMemory. + SignZero: Mở rộng dấu hoặc mở rộng không SignZero = 0: Mở rộng dấu SignZero = 1: Mở rộng không + ALUop: Cho biết phép toán thực hiện là cộng (01) đối với LW và SW, trừ (01) đối với BNE, lệnh loại R (10) hoặc lệnh XORI (11).
NHÓM 28
Page 12
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
Bảng 2. Giá trị điều khiển của Control_Unit. Code: module Control_Unit( RegDst, ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, Branch, ALUop, Jump, SignZero z,OpCode); input [5:0]OpCode; output Jump,RegDst,ALUSrc,MemtoReg,RegWrite,MemRead,MemWrite,Branch,SignZero; output [1:0]ALUop; reg Jump,RegDst,ALUSrc,MemtoReg,RegWrite,MemRead,MemWrite,Branch,SignZero; reg [1:0]ALUop; always @( OpCode) casex (OpCode) 6'b000000 : // R - type begin RegDst = 1'b1; // Thanh ghi dich giai ma tu bit [15:11] cua lenh ALUSrc = 1'b0; MemtoReg = 1'b0; RegWrite = 1'b1; // Cho phep ghi gia tri vao thanh ghi dich MemRead = 1'b0; MemWrite = 1'b0; Branch = 1'b0; ALUop = 2'b10; Jump = 1'b0; NHÓM 28
Page 13
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 SignZero = 1'bx; end 6'b100011 : // lw - load word begin RegDst = 1'b0; // thanh ghi dich duoc giai ma tu bit [20:16] cua lenh ALUSrc = 1'b1; // chon gia tri sign_extend dua vao bo ALU MemtoReg = 1'b1; // chon gia tri dua ve thanh ghi dich tu bo nho du lieu RegWrite = 1'b1; // cho phep gia tri dua ve duoc ghi vao thanh ghi dich MemRead = 1'b1; // cho phep doc du lieu tu bo nho du lieu MemWrite = 1'b0; Branch = 1'b0; ALUop = 2'b00; Jump = 1'b0; SignZero = 1'b0; // chon sign extend end 6'b101011 : // sw - store word begin RegDst = 1'bx; // ALUSrc = 1'b1; // chon gia tri sign_extend dua vao bo ALU MemtoReg = 1'bx; // khogn quan tam gia tri dua ve RegWrite = 1'b0; MemRead = 1'b0; MemWrite = 1'b1; // cho phep ghi du lieu vao bo nho du lieu Branch = 1'b0; ALUop = 2'b00; Jump = 1'b0; SignZero = 1'b0; end 6'b000101 : begin
// bne - branch if not equal RegDst = ALUSrc = MemtoReg = RegWrite = MemRead MemWrite = Branch = ALUop = Jump = SignZero =
end 6'b001110 : begin
// XORI - XOR immidiate RegDst = ALUSrc = MemtoReg = RegWrite = MemRead MemWrite = Branch =
NHÓM 28
1'bx; 1'b0; 1'bx; 1'b0; = 1'b0; 1'b0; 1'b1; // cho phep thuc hien lenh branch 2'b01; 1'b0; 1'b0; // sign extend
1'b0; 1'b1; // Chon zero_extend 32 bit dua vao ALU 1'b0; 1'b1; // Cho phep ghi du lieu vao thanh ghi dich = 1'b0; 1'b0; 1'b0; Page 14
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 ALUop = Jump = SignZero = end 6'b000010 : begin
2'b11; 1'b0; 1'b1; // zero extend
// j - Jump RegDst = ALUSrc = MemtoReg = RegWrite = MemRead MemWrite = Branch = ALUop = Jump = SignZero =
1'bx; 1'bx; 1'bx; 1'b0; = 1'b0; 1'b0; 1'bx; 2'bxx; 1'b1; 1'bx;
RegDst = ALUSrc = MemtoReg = RegWrite = MemRead MemWrite = Branch = ALUop = Jump = SignZero =
1'b0; 1'b0; 1'b0; 1'b0; = 1'b0; 1'b0; 1'b0; 2'b10; 1'b0; 1'b0;
end default : begin
end endcase endmodule
NHÓM 28
Page 15
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
7. ALU_Control_Unit : -
Kết hợp giá trị của tín hiệu điều khiển ALUop từ bộ điều khiển trung tâm và 6bit Function giãi mã từ lệnh để tạo ra tín hiệu điều khiển ALUControl cho bộ tính toán ALU
Bảng 3. Giá trị của ALUop và ALUControl
NHÓM 28
Page 16
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
Code: module ALU_Control_Unit(ALUControl,ALUop,Funct); input [1:0]ALUop; input [5:0]Funct; output [1:0]ALUControl; reg [1:0] ALUControl; wire [7:0] ALUCtrl; assign ALUCtrl = {ALUop,Funct}; always @(ALUCtrl) casex (ALUCtrl) 8'b00xxxxxx: ALUControl = 2'b00;
// LW & SW
8'b01xxxxxx: ALUControl = 2'b10;
// BNE
8'b11xxxxxx: ALUControl = 2'b01;
// XORI
8'b10100000: ALUControl = 2'b00;
// ADD
8'b10100010: ALUControl = 2'b10;
// SUB
8'b10101010: ALUControl = 2'b11;
// SLT
default: ALUControl=2'b00; endcase endmodule
8. JR_Control_Unit: -
-
Kết hợp giá trị của tín hiệu điều khiển ALUop từ bộ điều khiển trung tâm và 6bit Function giãi mã từ lệnh để tạo ra tín hiệu JR_Control cho phép thực hiện lệnh JUMP REGISTER. Địa chỉ của lênh JumpRegister chính là dữ liệu trong thanh ghi Rs.
NHÓM 28
Page 17
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
Code: module JR_Control_Unit(ALUop,Funct,JRControl); input [5:0]Funct; // 6 bit function cua lenh input [1:0] ALUop; // 2 bit ALU Opcode tu khoi dieu khien ALU output JRControl; // dieu khien chon dia chi cho PC reg JRControl; wire [7:0]x; assign x = {ALUop,Funct}; /* ALUop = 10 va function = 01000 => JRControl = 1 cac truong hop khac JRControl = 0 */ always @(x) case (x) 8'b10001000: JRControl = 1'b1; default: JRControl = 1'b0; endcase endmodule
9. Bộ mở rộng dấu – Extender: -
Từ ngõ vào 10-bit mở rộng thành ngõ ra 32-bit với tín hiệu điều khiển SignZero. Code:
module Extender ( out, in, select); output [31:0] out; input [15:0] in; input select; // select = 0: Sign_Extend reg [31:0]out; // select = 1: Zero_Extend always @(in or select) begin if (select) begin NHÓM 28
Page 18
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 out[31:16] = 16'b0; out[15:0] = in; end else assign out = {{16{in[15]}}, in}; end endmodule
10. Bộ dịch trái – ShiftLeft2: -
Dịch tín hiệu 32-bit qua trái 2 bit để thực hiện phép nhân với 4. Code:
module Shiftleft2(out,in); input [31:0]in; output [31:0]out; assign out = { in[29:0], 2'b0 }; endmodule
11. Bộ Multiplexor: -
Bộ multiplexor 2x5_5 chọn thanh ghi đích cho RegisterFile Bộ multiplexor 2x32_32 chọn ngõ vào thứ 2 cho bộ ALU, dữ liệu ghi về RegisterFile và chọn lựa địa chỉ của lệnh tiếp theo được thực hiện.
Code: module Mux_2to1(out,in1,in2,en); // en = 0: out = in1 input in1,in2,en; output out; module Mux_2x32to32(out,in1,in2,Sel); wire a1,a2; input [31:0]in1,in2; and #50 and1(a1,nen,in1); input Sel; and #50 and2(a2,en,in2); output [31:0]out; not #50 not1(nen,en); or #50 or1(out,a1,a2); Mux_2to1 mux0(out[0],in1[0],in2[0],Sel); endmodule Mux_2to1 mux1(out[1],in1[1],in2[1],Sel); Mux_2to1 mux2(out[2],in1[2],in2[2],Sel); module Mux_2x5to5(out,in1,in2,en); Mux_2to1 mux3(out[3],in1[3],in2[3],Sel); input [4:0] in1,in2; // 2 ngõ vào 5 bit Mux_2to1 mux4(out[4],in1[4],in2[4],Sel); input en; Mux_2to1 mux5(out[5],in1[5],in2[5],Sel); output [4:0]out; // Ngõ ra 5 bit Mux_2to1 mux6(out[6],in1[6],in2[6],Sel); Mux_2to1 m4(out[4],in1[4],in2[4],en); Mux_2to1 mux7(out[7],in1[7],in2[7],Sel); Mux_2to1 m3(out[3],in1[3],in2[3],en); Mux_2to1 mux8(out[8],in1[8],in2[8],Sel); Mux_2to1 m2(out[2],in1[2],in2[2],en); Mux_2to1 mux9(out[9],in1[9],in2[9],Sel); Mux_2to1 m1(out[1],in1[1],in2[1],en); Mux_2to1 mux10(out[10],in1[10],in2[10],Sel); Mux_2to1 m0(out[0],in1[0],in2[0],en); Mux_2to1 mux11(out[11],in1[11],in2[11],Sel); endmodule Mux_2to1 mux12(out[12],in1[12],in2[12],Sel); NHÓM 28
Page 19
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 Mux_2to1 mux13(out[13],in1[13],in2[13],Sel); Mux_2to1 mux14(out[14],in1[14],in2[14],Sel); Mux_2to1 mux15(out[15],in1[15],in2[15],Sel); Mux_2to1 mux16(out[16],in1[16],in2[16],Sel); Mux_2to1 mux17(out[17],in1[17],in2[17],Sel); Mux_2to1 mux18(out[18],in1[18],in2[18],Sel); Mux_2to1 mux19(out[19],in1[19],in2[19],Sel); Mux_2to1 mux20(out[20],in1[20],in2[20],Sel); Mux_2to1 mux21(out[21],in1[21],in2[21],Sel); Mux_2to1 mux22(out[22],in1[22],in2[22],Sel);
Mux_2to1 mux23(out[23],in1[23],in2[23],Sel); Mux_2to1 mux24(out[24],in1[24],in2[24],Sel); Mux_2to1 mux25(out[25],in1[25],in2[25],Sel); Mux_2to1 mux26(out[26],in1[26],in2[26],Sel); Mux_2to1 mux27(out[27],in1[27],in2[27],Sel); Mux_2to1 mux28(out[28],in1[28],in2[28],Sel); Mux_2to1 mux29(out[29],in1[29],in2[29],Sel); Mux_2to1 mux30(out[30],in1[30],in2[30],Sel); Mux_2to1 mux31(out[31],in1[31],in2[31],Sel); endmodule
Code Verilog cho MIPS: // MIPS 32BIT - SINGLE - CYLCE - CPU module MIPS(clk, reset); input clk, reset;
/************************************ ************* KHAI BAO ************* ************************************/ // KHAI BAO DIA CHI wire [31:0] PCin,PC;
// PCin: dia chi ngo vao cua thanh ghi PC
wire [31:0] PC_4, PC_Bne, PC_Jump, PC_JR, Bne_Address, Jump_Address, JR_Address;
// PC_4 : Dia chi lenh tiep theo // PC_Bne : Dia chi neu thuc hien lenh Branch // PC_Jump: Dia chi neu thuc hien lenh Jump // PC_JR : Dia chi neu thuc hien lenh Jump Register // Bne_Address: Dia chi Branch // Jump_Address: Dia chi Jump // JR_Address: Dia chi Jump Register ( = ReadData1)
// KHAI BAO INSTRUCTION MEMORY wire [31:0] Instruction; // Lenh dang xu ly wire [5:0] Opcode,Funct; wire [4:0] Rs,Rt,Rd; wire [15:0] Imm16; // gia tri 16bit immediate assign Opcode = Instruction[31:26]; assign Rs = Instruction[25:21]; assign Rt = Instruction[20:16]; assign Rd = Instruction[15:11]; assign Funct = Instruction[5:0]; NHÓM 28
Page 20
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 assign Imm16 = Instruction[15:0]; // KHAI BAO CONTROL UNIT wire RegDst, Jump, Branch, MemRead, MemtoReg, MemWrite, ALUSrc, RegWrite, SignZero; wire [1:0]ALUOp; // KHAI BAO ALU wire [31:0] ALUin1, ALUin2; wire [31:0] ALUResult; wire Zero, Negative, Overflow, Carry;
// 2 ngo vao cua bo ALU // Ket qua cua bo ALU
// Cac co` cua bo ALU
wire JR_Control; wire Bne_Control; wire [1:0] ALU_Control;
// Tin hieu dieu khien lenh Jump Register // Tin hieu dieu khien lenh BNE // Tin hieu ra cua ALU_Control_Unit
wire [31:0] Extend;
// 32bit mo rong dau cua 16bit immediate
// KHAI BAO REGISTER FILE wire [31:0] ReadData1,ReadData2; wire [31:0] Reg_WriteData; wire [4:0] WriteRegister;
// Gia tri cac thanh ghi // Gia tri ghi vao thanh ghi dich // Thanh ghi dich
// KHAI BAO DATA MEMORY wire [31:0] Mem_ReadData, Mem_Address, Mem_WriteData;
// Du lieu xuat ra tu bo nho // Dia chi DataMemory // Du lieu ghi vao bo nho ( = ReadData2)
// KHAI BAO SHIFTER wire [31:0] Bne_shift_in, Bne_shift_out, Jump_shift_in, Jump_shift_out;
// Ngo vao bo dich trai (BNE) // Ngo ra bo dich trai (BNE) // Ngo vao bo dich trai (JUMP) // Ngo ra bo dich trai (JUMP)
/************************************ ********* CAU TRUC MIPS ************ NHÓM 28
Page 21
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 ************************************/ /* KHOI THANH GHI PC */ PC_Register ProgramCounter( PC, PCin, reset, clk); // Dia chi lenh tiep theo duoc thuc hien Add_32bit Adder_PC( PC, // PC_4 = PC + 4 {29'b0,3'b100},,, PC_4);
/* INSTRUCTION MEMORY - BO NHO LENH */ InstructionMem InstructionMemory(Instruction, PC);
/* MAIN CONTROL UNIT - KHOI DIEU KHIEN CHINH */ Control_Unit Control( RegDst, ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, Branch, ALUOp, Jump, SignZero, Opcode ); /* REGISTER FILE - BO THANH GHI */ Mux_2x5to5 Mux_RegDst(WriteRegister,Rt,Rd,RegDst); // Chon WriteRegister ( giua lenh R-type & I-type) RegisterFile RegFile( ReadData1, ReadData2, Reg_WriteData, Rs, Rt, WriteRegister, RegWrite, reset, clk ); /* SIGN-ZERO EXTEND */ Extender Sign_Extend(Extend, Imm16, SignZero); /* ALU - KHOI TINH TOAN CHINH */ assign ALUin1 = ReadData1; Mux_2x32to32 Mux_Input_ALU( ALUin2, ReadData2, NHÓM 28
Page 22
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 Extend, ALUSrc); ALU ALU_Unit(ALUResult, ALUin1, ALUin2, Carry, Zero, Overflow, Negative, ALU_Control); ALU_Control_Unit ALUControl( ALU_Control, ALUOp, Funct); /* DATA MEMORY - BO NHO DU LIEU */ assign Mem_WriteData = ReadData2; assign Mem_Address = ALUResult; DataMem DataMemory( Mem_ReadData, ALUResult, Mem_WriteData, MemWrite, MemRead, clk); Mux_2x32to32 Mux_WriteData( Reg_WriteData, ALUResult, Mem_ReadData, MemtoReg);
/* BNE CONTROL */ assign Bne_shift_in = Extend; Shiftleft2 Shift_bne( Bne_shift_out, Bne_shift_in); Add_32bit Adder_bne( PC_4, Bne_shift_out,,, Bne_Address); not #(50) notBNE(NotZero,Zero); and #(50) andBNE(Bne_Control,Branch,NotZero); Mux_2x32to32 Mux_BNE( PC_Bne, PC_4, Bne_Address, Bne_Control); /* JUMP CONTROL */ assign Jump_shift_in = {6'b0,Instruction[25:0]}; assign Jump_Address = {PC_4[31:28],Jump_shift_out[27:0]}; Shiftleft2 Shift_jump(Jump_shift_out,Jump_shift_in); NHÓM 28
Page 23
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3 Mux_2x32to32 Mux_Jump(PC_Jump, PC_Bne, Jump_Address, Jump); /* JUMP REGISTER CONTROL */ assign JR_Address = ReadData1; assign PCin = PC_JR; JR_Control_Unit JRControlUnit1( ALUOp, Funct,JR_Control); Mux_2x32to32 MuxJR( PC_JR, PC_Jump, JR_Address, JR_Control); endmodule
NHÓM 28
Page 24
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
III. Mô phỏng: 1. Tập lệnh mô phỏng: Địa chỉ ( thập phân) 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56
Lệnh
Mã máy
Xori $1, $0, 0x0010 Xori $2, $0, 0x001F Sw $1, 0x00($0) Sw $2, 0x04($0) Add $3, $1, $2 Bne $1,$2, 0x01
001110 00000 00001 00000000 00010000 001110 00000 00010 00000000 00011111 101011 00000 00001 00000000 00000000 101011 00000 00010 00000000 00000100 000000 00001 00010 00011 00000 100000 000101 00001 00010 00000000 00000001
Add $7, $3, $2
000000 00011 00010 00111 00000 100000
Sub $4, $1, $2 J 0x0A
000000 00001 00010 00100 00000 100010 000010 00 00000000 00000000 00001010
Lw $12,0x00($0)
100011 00000 01100 00000 00000000000
Lw $5 , 0x00($0) Lw $6 , 0x04($0) Slt $7, $1, $2 Jr $0 .............
100011 00000 00101 00000000 00000000 100011 00000 00110 00000000 00000100 000000 00001 00010 00111 00000 101010 000000 00000 00000 00000 00000 001000
2. Dạng sóng mô phỏng:
NHÓM 28
Page 25
ĐỒ ÁN CẤU TRÚC MÁY TÍNH – LAB 3
NHÓM 28
Page 26