19
BÁO CÁO LAB 3 ĐỒ ÁN VI XỬ LÝ VÀ CẤU TRÚC MÁY TÍNH Nhóm 22A

Mips Single-Cycle 32bit Report

Embed Size (px)

Citation preview

Page 1: Mips Single-Cycle 32bit Report

BÁO CÁO LAB 3ĐỒ ÁN VI XỬ LÝ VÀ CẤU TRÚC MÁY TÍNH

Nhóm 22A

Page 2: Mips Single-Cycle 32bit Report

1. Yêu cầu:

- Thiết kế chip Mips Single-Cycle 32bit bao gồm các lệnh LW, SW, J, JR,

BNE, XORI, ADD, SUB và SLT.

- Các lệnh đều được xử lý trong 1 chu kỳ lệnh (Single Cycle).

- Thiết kế dựa trên các module có sẵn regfife, alu, instrmem và datamem

2. Tập lệnh:

Các lệnh chia làm 3 nhóm:

- R-format: ADD, SUB, SLT, JR.

- I-format: LW, SW, BNE, XORI.

- J-format: J.

2.1. R-format:

- Ý nghĩa lệnh:

+ ADD rd, rs, rt:

Reg[rd] = Reg[rs] + Reg[rt].

+ SLT rd, rs, rt:

If (Reg[rs] < Reg[rt])

Reg[rd] = 1

else

Reg[rd] = 0.

+ SUB rd, rs, rt:

Reg[rd] = Reg[rs] – Reg[rt].

+ JR rs:

PC = Reg[rs].

- Khuôn dạng:

opcode rs rt rd shamt function

6 bit 5 bit 5 bit 5 bit 5 bit 6 bit

Page 3: Mips Single-Cycle 32bit Report

2.2. I-format:

- Ý nghĩa lệnh:

+ 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).

- Khuôn dạng:

opcode rs rt address/immediate

6 bit 5 bit 5 bit 16 bit

2.3. J-format:

- Ý nghĩa lệnh:

+ J target:

PC = { PC[31:28], target, 00 }.

- Khuôn dạng:

opcode target address

6 bit 26 bit

Page 4: Mips Single-Cycle 32bit Report

3. Thiết kế:

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

Page 5: Mips Single-Cycle 32bit Report

3.2. Thiết kế các module:

3.2.1. Module Control:

Page 6: Mips Single-Cycle 32bit Report

MainControl

RegDst

Jump

Branch

MemRead

MemReg

ALUop

Memwrite

Aluscr

Regwrite

Instruction [31:26]

- Khối điều khiển trung tâm, có nhiệm vụ giải mã opcode của câu lệnh

thành các tín hiệu điều khiển đến các khối khác trong chip.

- Các tín hiệu điều khiển và giá trị tương ứng trong từng câu lệnh được

cho trong bảng sau:

R-format Jump BNE LW SW XORI

Opcode 000000 000010 000101 100011 101011 001110

RegDst 1 X X 0 X 0

ALUSrc 0 X 0 1 1 1

MemtoRe

g

0 X X 1 X 0

RegWrite 1 0 0 1 0 1

MemWrite 0 0 0 0 1 0

Branch 0 0 1 0 0 0

Jump 0 1 0 0 0 0

SignEx X X 1 1 1 0

ALUOp 0 1 X 0 0 0 1

ALUOp 1 1 X 1 0 0 0

Page 7: Mips Single-Cycle 32bit Report

- Từ bảng trạng thái, sử dụng các cổng logic AND và OR, ta lập được các tín

hiệu ra từ 6 bit Opcode

- Code:

module Control(ALUOp, RegDst, Branch, MemtoReg, MemWrite, ALUSrc, RegWrite, Jump, SignEx, InsOp);

output [1:0] ALUOp;output RegDst, Branch, MemtoReg, MemWrite, ALUSrc, RegWrite, Jump, SignEx;input [5:0] InsOp;

wire [5:0] nInsOp;wire ALUSrc1, ALUSrc2, ALUSrc3;wire RegWrite1, RegWrite2, RegWrite3;wire SignEx1, SignEx2, SignEx3;wire [1:0] ALUOp1, ALUOp2;

not #50 (nInsOp[0], InsOp[0]),(nInsOp[1], InsOp[1]),(nInsOp[2], InsOp[2]),(nInsOp[3], InsOp[3]),(nInsOp[4], InsOp[4]),(nInsOp[5], InsOp[5]);

and #100 (RegDst, nInsOp[0], nInsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], nInsOp[5]);

and #100 (ALUSrc1, InsOp[0], InsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], InsOp[5]), (ALUSrc2, InsOp[0], InsOp[1], nInsOp[2], InsOp[3], nInsOp[4], InsOp[5]), (ALUSrc3, nInsOp[0], InsOp[1], InsOp[2], InsOp[3], nInsOp[4], nInsOp[5]);

or #50 (ALUSrc, ALUSrc1, ALUSrc2, ALUSrc3);

and #100 (MemtoReg, InsOp[0], InsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], InsOp[5]);

and #100 (RegWrite1, nInsOp[0], nInsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], nInsOp[5]),

(RegWrite2, InsOp[0], InsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], InsOp[5]),

(RegWrite3, nInsOp[0], InsOp[1], InsOp[2], InsOp[3], nInsOp[4], nInsOp[5]);

or #50 (RegWrite, RegWrite1, RegWrite2, RegWrite3);

and #100 (MemWrite, InsOp[0], InsOp[1], nInsOp[2], InsOp[3], nInsOp[4], InsOp[5]);

and #100 (Branch, InsOp[0], nInsOp[1], InsOp[2], nInsOp[3], nInsOp[4], nInsOp[5]);

and #100 (Jump, nInsOp[0], InsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], nInsOp[5]);

and #100 (SignEx1, InsOp[0], nInsOp[1], InsOp[2], nInsOp[3], nInsOp[4], nInsOp[5]), (SignEx2, InsOp[0], InsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], InsOp[5]), (SignEx3, InsOp[0], InsOp[1], nInsOp[2], InsOp[3], nInsOp[4], InsOp[5]);

or #50 (SignEx, SignEx1, SignEx2, SignEx3);

and #100 (ALUOp1[1], nInsOp[0], nInsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], nInsOp[5]),

Page 8: Mips Single-Cycle 32bit Report

(ALUOp2[1], InsOp[0], nInsOp[1], InsOp[2], nInsOp[3], nInsOp[4], nInsOp[5]);

or #50 (ALUOp[1], ALUOp1[1], ALUOp2[1]);

and #100 (ALUOp1[0], nInsOp[0], nInsOp[1], nInsOp[2], nInsOp[3], nInsOp[4], nInsOp[5]),

(ALUOp2[0], nInsOp[0], InsOp[1], InsOp[2], InsOp[3], nInsOp[4], nInsOp[5]);

or #50 (ALUOp[0], ALUOp1[0], ALUOp2[0]);

endmodule

3.2.2. Module ALUControl:

- Giải mã tín hiệu điều khiển ALUOp từ khối Control, kết hợp với 6 bit

Function để đưa ra tín hiệu điều khiển cho khối ALU thực hiện một trong bốn phép

toán ADD, SUB, SLT và XOR

- Tín hiệu điều khiển cho ALU được cho trong bảng sau:

ALUOp Function ALUCtr

00 (Load hoặc Store) X 00 (ADD)

01 (XOR) X 01 (XOR)

10 (BNE) X 10 (SUB)

11 (Lệnh R)

100000 00 (ADD)

100010 10 (SUB)

101010 11 (SLT)

- Ngoài ra khối ALUControl còn đưa ra một tín hiệu điều khiển

JumpReg cho câu lệnh JR với ALUOp = 11 và Function = 001000.

- Code:

module ALUControl(ALUCtr, JumpReg, ALUOp, Function);output [1:0] ALUCtr;output JumpReg;input [1:0] ALUOp;input [5:0] Function;

wire [1:0] nALUOp;wire [5:0] nFunction;wire [1:0] R, nR;wire R1, R2, ALUCtr01, ALUCtr02, ALUCtr11, ALUCtr12, ALUCtr13;

not #50 (nALUOp[0], ALUOp[0]),(nALUOp[1], ALUOp[1]),(nFunction[0], Function[0]),

Page 9: Mips Single-Cycle 32bit Report

(nFunction[1], Function[1]),(nFunction[2], Function[2]),(nFunction[3], Function[3]),(nFunction[4], Function[4]),(nFunction[5], Function[5]),(nR[0], R[0]),(nR[1], R[1]);

and #100 (R[0], nFunction[0], Function[1], nFunction[2], Function[3], nFunction[4], Function[5]);

and #100 (R1, nFunction[0], Function[1], nFunction[2], Function[3], nFunction[4], Function[5]),

(R2, nFunction[0], Function[1], nFunction[2], nFunction[3], nFunction[4], Function[5]);

or #50 (R[1], R1, R2);

and #50 (ALUCtr11, nALUOp[0], ALUOp[1]), (ALUCtr12, nR[0], R[1], ALUOp[0], ALUOp[1]), (ALUCtr13, R[0], R[1], ALUOp[0], ALUOp[1]);

or #50 (ALUCtr[1], ALUCtr11, ALUCtr12, ALUCtr13);

and #50 (ALUCtr01, ALUOp[0], nALUOp[1]), (ALUCtr02, ALUOp[0], ALUOp[1], R[0], R[1]);

or #50 (ALUCtr[0], ALUCtr01, ALUCtr02);

and #100 (JumpReg, ALUOp[0], ALUOp[1], nFunction[0], nFunction[1], nFunction[2], Function[3], nFunction[4], nFunction[5]);endmodule

3.2.3. Khối dịch trái 2 (nhân 4):

Page 10: Mips Single-Cycle 32bit Report

- Do bộ nhớ chương trình được đánh địa chỉ byte và cấu trúc lệnh được

lưu trong 1 word, do đó đối với các lệnh rẽ nhánh, giá trị trước khi đưa vào thanh ghi

PC phải nhân với 4, hay nói cách khác là dịch trái giá trị nhị phân đi 2 đơn vị.

- Code:

module ShiftLeft2_1(data_out, data_in);output [31:0] data_out;input [31:0] data_in;

genvar i;generate

for (i=2; i<32; i=i+1) begin: SL2assign data_out[i] = data_in[i-2];

endendgenerate

assign data_out[0] = 0;assign data_out[1] = 0;

endmodule

module ShiftLeft2_2(data_out, data_in);output [27:0] data_out;input [25:0] data_in;

genvar i;generate

for (i=2; i<28; i=i+1) begin: SL2assign data_out[i] = data_in[i-2];

endendgenerateassign data_out[0] = 0;assign data_out[1] = 0;

endmodule

3.2.4. Khối mở rông (Extend):

- Phần address/immediate của các câu lệnh I-format gồm 16bit, trong khi

đối số của các lệnh hoặc địa chỉ bao gồm 32bit, do đó cần có bước mở rông trước khi

dùng để tính toán.

- Tùy theo lệnh mà mở rộng dấu hay mở rông zero, ta sử dụng 1 bit điều

khiển từ khối Control để lựa chọn kiểu mở rộng (SignEx).

- Code:

Page 11: Mips Single-Cycle 32bit Report

module Extend(data_out, data_in, SignEx);output [31:0] data_out;input [15:0] data_in;input SignEx;

assign data_out[15:0] = data_in;

genvar i;generate

for (i=16; i<32; i=i+1) begin: Exand #50 (data_out[i], data_in[15], SignEx);

endendgenerate

endmodule

3.2.5. Các bộ chọn kênh

- Các bộ chọn kênh được sử dụng để chọn 1 tín hiệu ra từ 2 tín hiệu vào

- Các tín hiệu điều khiển phụ thuộc vào từng câu lệnh và được đưa ra từ

khối Control

- Code:

module Muxer32(data_out, data_in1, data_in2, sel);output [31:0] data_out;input [31:0] data_in1, data_in2;input sel;

wire [31:0] f1, f2;wire nsel, dsel;

not #50 (nsel, sel);buf #50 (dsel, sel);

genvar i;generate

for (i=0; i<32; i=i+1) begin: Muxerand #50 (f1[i], nsel, data_in1[i]);and #50 (f2[i], dsel, data_in2[i]);or #50 (data_out[i], f1[i], f2[i]);

endendgenerate

endmodule

module Muxer5(data_out, data_in1, data_in2, sel);output [4:0] data_out;input [4:0] data_in1, data_in2;input sel;

Page 12: Mips Single-Cycle 32bit Report

wire [4:0] f1, f2;wire nsel, dsel;

not #50 (nsel, sel);buf #50 (dsel, sel);

genvar i;generate

for (i=0; i<5; i=i+1) begin: Muxerand #50 (f1[i], nsel, data_in1[i]);and #50 (f2[i], dsel, data_in2[i]);or #50 (data_out[i], f1[i], f2[i]);

endendgenerate

endmodule

3.2.6. Bộ nhớ chương trình và bộ nhớ dữ liệu:

- Bộ nhớ chương trình dùng để lưu mã máy của các câu lệnh. Bộ nhớ

chương trình có 210 word và được lưu trong file instr.dat.

- Bộ nhớ dữ liệu dùng để lưu các giá trị trong quá trình tính toán. Bộ nhớ

dữ liệu có 28 word và được lưu trong file data.dat.

- cả 2 bộ nhớ đều được đánh địa chỉ byte.

3.3. Module chính:

Page 13: Mips Single-Cycle 32bit Report

3.3.1. Thanh ghi PC:

- Thanh ghi PC được sử dụng để chỉ đến vị trí của câu lệnh tiếp theo sẽ

được thực hiện.

- Khi không có các câu lệnh rẽ nhánh, giá trị của thanh ghi PC sau mỗi

chu kỳ lệnh sẽ tự động tăng lên 4. Các câu lệnh rẽ nhánh J, JR, BNE sẽ có tác động

làm thay đổi giá trị của thanh ghi PC.

- Ta sử dụng 1 thanh ghi PC để lưu giá trị hiện thời và 1 thanh ghi PCIn

để lưu giá trị tiếp theo của PC khi có xung clk.

- Mỗi khi có xung clk, giá trị của thanh ghi PCIn sẽ được đặt vào thành

ghi PC, bộ nhớ chương trình sẽ sử dụng giá trị của thanh ghi PC để lấy ra câu lệnh tiếp

theo. Giá trị mới của PC sau khi thực hiện xong câu lệnh sẽ được lưu vào thanh ghi

PCIn để đợi đưa vào PC khi có xung clk tiếp theo.

3.3.2. Tính toán xung clk:

- Có 4 khối trong chip cần có xung clk theo thứ tự sau:

+ Thanh ghi PC

+ Bộ nhớ dữ liệu (data memory)

+ Bộ thanh ghi (Registers)

+ Thanh ghi PCIn

- Từ lúc có xung clk đến thanh ghi PC, tín hiệu đi qua bộ nhớ chương

trình (1000ps), bộ thanh ghi (khoảng 500ps), khối ALU (khoảng 6000ps). Do đó, ta

chọn độ trễ của xung clk cho bộ nhớ dữ liệu so với xung clk của PC là 10000ps để

đảm bảo giá trị nhận được là chính xác.

- Tương tự ta chọn độ trễ của xung clk cho thanh ghi PCIn là 10000ps.

- Tín hiệu đi qua bộ nhớ dữ liệu mất 1000ps, ta chọn độ trễ của xung clk

cho bộ thanh ghi so với bộ nhớ dữ liệu là 2000ps.

+ Việc thực hiện 1 câu lệnh phải hoàn tất trong vòng 1 chu kỳ xung clk,

do vậy ta phải chọn độ rộng của xung clk đủ lớn. Dựa vào tính toán ở trên, ta chọn độ

rộng của xung clk là 15000ps, hay chu kỳ của xung clk là 30000ps.

3.3.3. Code:

module CPU(clk);input clk;

reg reset;wire [31:0] PC, PCIn, PCIn1, PCIn2, PCIn3, PCplus4, Instruction, ExImm, SL2Imm,

JumpAdr, BranchAdr;

Page 14: Mips Single-Cycle 32bit Report

wire [31:0] ReadData1, ReadData2, RegWriteData, ALU2ndIn, ALUResult, MemOutput;wire [4:0] WriteRegister;wire [1:0] ALUOp, ALUCtr;wire CarryOut, zero, overflow, negative, nzero;wire RegDst, Branch, MemtoReg, MemWrite, ALUSrc, RegWrite, Jump, SignEx,

JumpReg, BranchSel;wire Memclk, Regclk, PCInclk, PCclk;

initial beginreset = 0;#50 reset = 1;#50 reset = 0;

end

assign PCclk = clk;buf #10000 (Memclk, PCclk);buf #1000 (Regclk, Memclk);buf #10000 (PCInclk, PCclk);

SinReg PCInReg(PCIn, PCIn3, reset, PCInclk, 1'b1);SinReg PCReg(PC, PCIn, 1'b0, PCclk, 1'b1);InstructionMemInsMem(Instruction, PC);Regfile Registers(ReadData1, ReadData2, RegWriteData, Instruction[25:21] ,

Instruction[20:16], WriteRegister, RegWrite, Regclk, reset);alu ALU(ALUResult, CarryOut, zero, overflow, negative,

ReadData1, ALU2ndIn, ALUCtr);DataMem DataMem(MemOutput, ALUResult, ReadData2, MemWrite,

Memclk);Control Ctrl(ALUOp, RegDst, Branch, MemtoReg, MemWrite, ALUSrc,

RegWrite, Jump, SignEx, Instruction[31:26]);ALUControl ALUCtrl(ALUCtr, JumpReg, ALUOp, Instruction[5:0]);Extend Ext(ExImm, Instruction[15:0], SignEx);ShiftLeft2_1 SL1(SL2Imm, ExImm);ShiftLeft2_2 SL2(JumpAdr[27:0], Instruction[25:0]);AddCPU Add1(PCplus4, PC, 32'h00000004);AddCPU Add2(BranchAdr, PCplus4, SL2Imm);

not #50 (nzero, zero);and #50 (BranchSel, Branch, nzero);assign JumpAdr[31:28] = PCplus4[31:28];

Muxer5 RegDstMux(WriteRegister, Instruction[20:16], Instruction[15:11], RegDst);Muxer32 ALUSrcMux(ALU2ndIn, ReadData2, ExImm, ALUSrc);Muxer32 MemtoRegMux(RegWriteData, ALUResult, MemOutput,

MemtoReg);Muxer32 BraSelMux(PCIn1, PCplus4, BranchAdr, BranchSel);Muxer32 JumpMux(PCIn2, PCIn1, JumpAdr, Jump);Muxer32 JumpRegMux(PCIn3, PCIn2, ReadData1, JumpReg);

Endmodule