Tải bản đầy đủ (.docx) (37 trang)

Thiết kế alu và control theo kiến trúc mips 32 bit

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (760.69 KB, 37 trang )

ĐẠI HỌC QUỐC GIA TP.HỒ CHÍ MINH

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
--------------------------------

BÁO CÁO ĐỒ ÁN KTMT
Đề tài: Thiết kế Alu Và Control theo kiến trúc
Mips 32 bit

GV Hướng dẫn : TS. Nguyễn Minh Sơn

1


Thành phố Hồ Chí Minh – Năm 2015

2


MỤC LỤC

1 YÊU CẦU THIẾT KẾ
Thiết kế một bộ Sigle Cycle MIPs 32bit thực hiện các chức năng:




Thực hiện các phép toán Arithmetic: ADD, SUB, ADDI, SUBI,…
Thực hiện các phép tính logic: AND, OR, NOR, XOR, SLT, ANDI, ORI, XORI,…
Thực hiện các lệnh LW, SW, J, JR, BNE


2 TỔNG QUAN VỀ MIPS
2.1

GIỚI THIỆU

RICs – Reduced Instruction Set Computers, là một dạng của kiến trúc vi xử lý. Nó là một
phương pháp thiết kế các bộ vi xử lý theo hướng đơn giản hóa tập lệnh.
Các dự án về RICs đầu tiên bắt đầu từ IBM, Stanford và UC Berkeley vào cuối những năm
70, đầu những năm 80 của thế kỷ trước. Hiện nay, các bộ vi xử lý phổ biết là ARM, SuperH,
MIPs, SPARC, PIC, PowerPC…
MIPs – Microprocessor without Interlocked Pipeline Stages, là một kiến trúc xử lý kiểu
RICs được phát triển bởi MIPS technologies. Các bộ vi xử lý MIPs được phát triển như một
phần của chương trình nghiên cứu VLSI của trường đại học Stanford đầu những năm 80. Nhóm
nghiên cứu Stanford đã phát triển một bộ xử lý giảm bớt sự tác động của trình biên dịch ở cấp độ
phần cứng, trái ngược với sự tăng lên của phần cứng với phần mềm, nó là một bước tiến dài
trong quá trình thiết kế phần cứng.
Năm 1984, Hennessy rời trường Stanford rời trường Stanford và xây dựng hệ thống máy
tính MIPs sau khi nhận ra nhu cầu thương mại tương lai của thiết kế này. Phiên bản MIPs R2000
đầu tiên ra đời vào năm 1985 và sau đó là phiên bản MIPs R3000 năm 1988.
Kiến trúc MIPs là kiến trúc thanh ghi. Tất cả các phép toán số học, logic đều chỉ xoay
quanh thanh ghi (hoặc ta có thể xem như một hằng số được lưu trữ như thành phần của lệnh).
Kiến trúc MIPs cũng bao gồm các câu lệnh đơn dùng đề đọc dữ liệu từ bộ nhớ vào thanh ghi và
ghi dữ liệu từ thanh ghi vào bộ nhớ. Vì vậy, kiến trúc MIPs còn được gọi là kiến trúc nạp/lưu do
chỉ có những câu lệnh nạp, lưu mới có thể truy cập vào bộ nhớ còn tất cả các câu lệnh khác chỉ
có thể truy cập tới thanh ghi.

3


2.2


KIẾN TRÚC TẬP LỆNH MIPS

Kiến trúc tập lệnh MIPs định nghĩa một tập các câu lệnh 32bit và 64bit để đảm bảo tương
thích với mọi bộ xử lý áp dụng kiến trúc MIPs.
Kiến trúc tập lệnh MIPs (ISA) được phát triển từ kiến trúc tập lệnh MIPsI đến kiến trúc
MIPsV. Vào cuối những năm 1990, kiến trúc MIPs được thiết kế xung quanh hai kiên trúc cơ bản
sau:



MIPs32 cho kiến trúc 32 bit: kiến trúc này dựa vào tập lệnh MIPsII cùng với một vài lệnh
được thêm vào từ tập lệnh MIPsIII, MIPsIV và MIPsV.
MIPs64 cho kiến trúc 64 bit: kiến trúc này chủ yếu dựa vào tập lệnh của kiến trúc MIPsV
Tập lệnh MIPs bao gồm tổng cộng 111 câu lệnh ở hệ 32bit.

Máy tính làm việc bằng cách lấy lệnh từ bộ nhớ, giải mã và tính toán chúng. Lệnh và các
giá trị sẽ được tính toán và mã hóa thành mã nhị phân. Máy tính chỉ làm việc với các gia trị nhị
phân.
Để thực hiện xây dựng một kiến trúc máy tính sử dụng kiến trúc MIPs thì các thành phần
cơ bản phải bao gồm:







Program Counter (PC): Con trỏ chương trình.
Instruction Memory: Bộ nhớ lệnh.

Data Memory: Bộ nhớ.
Register File: Tập thanh ghi.
ALU: Bộ tính toán số học và logic.
Control Unit: Khối điều khiển.

Tất cả các thành phần ngoại trừ Control Unit đều được kết nối với nhau bằng bus. Bus là
tập hợp đường dẫn điện tử với sự khác nhau về thiết lập giá trị nhị phân được vận chuyển trên
đường dẫn đó. Hầu hết các bus trong kiến trúc MIPs đều có bề rộng 32bit.

2.3

CÁC ĐỊNH DẠNG LỆNH CƠ BẢN TRONG MIPS

Có 3 loại lệnh trong MIPs là:


Register (R-type)



Immediate (I-type)

4




Jump (J-type)

Các lệnh sử dụng các trường sau:

Trường
opcode
rs
rt

Số bit
6bit
5bit
5bit

rd
Immediate

5bit
5bit

Instr_inde
x
sa
funct

26bit
5bit
6bit

Ý nghĩa
Xác định mã lệnh
Xác định thanh ghi nguồn
Xác định thanh ghi tạm (nguồn/đích) hoặc
dùng để chỉ ra các hàm trong phạm vi

REGIMM của opcode
Xác định thanh ghi đích
Dùng cho các toán hạng logic, phép toán có
dấu, nạp/nhớ các byte độ lệch dữ liệu và các
dấu hiệu rẽ nhánh
Chỉ số dịch trái 2bit để cung cấp 28 bit thấp
của địa chỉ đích trong lệnh Jump
Dịch
Xác định các hàm trong phạm vi Special
Opcode

3 THIẾT KẾ
3.1
3.1.1

PHÂN LOẠI CÁC LỆNH CƠ BẢN TRONG KIẾN TRÚC MIPS

Các lệnh nạp ghi

Các lệnh nạp, ghi (Load, store Instruction) là các lệnh di chuyển dữ liệu giữa bộ nhớ và
các thanh ghi. Chúng để là các lệnh có định dạng kiểu immediate (I-type), do đó phương thức
đánh địa chỉ duy nhất được hỗ trợ là lấy thanh ghi cơ sở cộng 16bit immediate.


Bao gồm các lệnh: LW, SW,…

5


3.1.2


Các lệnh số học và logic
Thực hiện các phép tính số học, logic, dịch chuyển trên các giá trị của các thanh ghi.

Các lệnh này bao gồm lệnh có định dạng Register (R-type) và định dạng kiểu Immediate
(I-type).


3.1.3

Các lệnh R-type: Add, Sub, SLT, And, Or, Xor, Nor,...
Các lệnh I-type: AddI, SubI, AndI, OrI, XorI,…

Các lệnh nhảy và rẽ nhánh

Các lệnh nhảy và rẽ nhánh (Jump and Branch Instructions) là các lệnh thay đổi dòng kiểm
soát của một chương trình. Lệnh nhảy luôn được làm đến một trang, dạng địa chỉ tuyệt đối bởi
một biên dịch địa chỉ 26-bit, với các bit cao của con trỏ chương trình (kiểu J-type) hoặc địa chỉ
thanh ghi (dạng R-type). Các lệnh rẽ nhánh có bù 16-bit liên quan đến con trỏ chương trình
(dạng I-type).


Bao gồm các lệnh: J, JR, BNE,…

3.2
3.2.1

CÁC THÀNH PHẦN CỦA MIPS

Program Counter


Program Counter là một thanh ghi được khởi tạo bởi hệ điều hành chứa địa chỉ của lệnh
đầu tiên của chương trình trong bộ nhớ. Địa chỉ chứa trong Program Counter sẽ được đưa đến
ngõ vào của bộ nhớ lệnh thông qua một bus.
Sau một chu kỳ, Program Counter sẽ được tăng lên để có được địa chỉ của lệnh cần thực
hiện tiếp theo. Trong trường hợp các lệnh thông thường, địa chỉ lưu trong Program Counter sẽ
được cộng thêm 4, còn đối với các lệnh nhảy và rẽ nhánh, địa chỉ lưu trong Program Counter sẽ
được thay đổi tương ứng với địa chỉ lấy được từ lệnh.

Cấu tạo cơ bản của Program Counter là một thanh ghi 32bit. Ta có thể xây dựng một
Program Counter với 32 D-FlipFlop.

module D_FF(q, d, reset, clk, en);
output q;
input d, reset, clk, en;
6


reg q;
wire clock;
`And and_clk (clock, clk, en);
always@(posedge clock or posedge reset)
if(reset)
q = 0; //khi co tin hieu reset, thiet lap
gia tri ra bang 0
else
q = d; //neu k co tin hieu reset, thiet
lap gia tri ra bang gia tri vao
endmodule
module PC_regs(PC_out, PC_in, rst, clk);

output [31:0]PC_out;
input [31:0]PC_in;
input rst,clk;
D_FF bit0(PC_out[0], PC_in[0], rst, clk, 1'b1);
D_FF bit1(PC_out[1], PC_in[1], rst, clk, 1'b1);
D_FF bit2(PC_out[2], PC_in[2], rst, clk, 1'b1);

D_FF bit31(PC_out[31], PC_in[31], rst, clk,
1'b1);
endmodule

3.2.2

Instruction Memory

Bộ nhớ lệnh là nơi lưu giữ các lệnh của chương trình, mỗi lệnh có một địa chỉ riêng. Bộ
nhớ lệnh có chức năng giống như một mảng hai chiều với thông tin được lưu trữ thành các word,
mỗi word tương ứng với 32bit dữ liệu. Mỗi vùng nhớ trong bộ nhớ có 32bit địa chỉ. Trong kiến
trúc MIPs, đơn vị nhỏ nhất có thể của thông tin là byte, một byte có giá trị bằng 8bit. Như vậy,
một word được cấu thành từ 4 byte. Địa chỉ của byte đầu tiên trong word cũng chính là địa chỉ
của word. Tất cả các lệnh trong kiến trúc MIPs đều có độ dài 32bit, vi vậy Program Counter sẽ
được tăng lên 4 sau khi mỗi lệnh được thực hiện.

module Instruction_Memory(Inst_out, Addr_in);
output [31:0]Inst_out;
input [31:0]Addr_in;
7


reg

reg

[7:0]Inst_Mem [1023:0];
[31:0]temp;

buf #1000 buf0(Inst_out[0], temp[0]),
buf1(Inst_out[1], temp[1]),
buf2(Inst_out[2], temp[2]),

buf31(Inst_out[31], temp[31]);
always @(Addr_in)
begin
temp[31:24] = Inst_Mem [(Addr_in)];
Inst_Mem [(Addr_in+1)];
temp[15:8] = Inst_Mem [(Addr_in+2)];
Inst_Mem [(Addr_in+3)];
end
endmodule

8

temp[23:16] =
temp[7:0] =


3.2.3

Register File

MIPS hỗ trợ 32 thanh ghi đánh số từ $0 - $31, mỗi thanh ghi có kích thước là 32 bit. Trong

đó, 8 thanh ghi thường được sử dụng để thực hiện các phép tính được đánh số $16 - $23.
Số
$0
$1
$2 -> $3
$4 -> $7
$8 -> $15

Tên
$zero
$at
$v0 » $v1
$a0 » $a3
$t0 » $t7

$16 -> $23

$s0 » $s7

$24 -> $25
$26 -> 27
$28
$29
$30
$31

$t8 » $t9
$k0 » $k1
$gp
$sp

$fp
$ra

Ý nghĩa
Hằng số 0
Assembler Temporary
Giá trị trả về của hàm hoặc biểu thức
Các tham số của hàm
Thanh ghi tạm (không giữ giá trị trong quá trình gọi
hàm)
Thanh ghi lưu trữ (giữ giá trị trong suốt quá trình
gọi hàm)
Thanh ghi tạm
Dự trữ cho nhân HĐH
Con trỏ toàn cục (global pointer)
Con trỏ Stack
Con trỏ Frame
Địa chỉ trả về

Ngõ vào Read register1, Read register 2: xác định địa chỉ của thanh ghi mà muốn đọc dữ
liệu.
Ngõ ra Read data1, Read data2: chứa nội dung của thanh ghi mà Read register1,
Readregister2 chỉ đến.
Khi tín hiệu RegWrite =1 quá trình ghi dữ liệu vào Register File sẽ được thực hiện, ngõ
vào Write register dùng để xác định địa chỉ mà chúng ta muốn ghi dữ liệu vào, Write data chứa
giá trị mới để ghi vào Register File. Dữ liệu mới sẽ được ghi vào khi có tín hiệu clock.

module Register_File(Read_Data1, Read_Data2, Write_Data,
Write_Addr, Reg_Write, clk, Read_Addr1, Read_Addr2);
input [4:0] Read_Addr1; Read_Addr2;

input [4:0] Write_Addr;
input [31:0] Write_Data;
9


input Reg_Write;
input clk;
output [31:0] Read_Data1, Read_Data2;
// Register File: 32
reg [31:0] Regs_File
integer i;
initial
begin
for(i = 0; i < 32;
begin
Regs_File[i] =
end
end

Register, moi Register 32 bit
[31:0];

i = i+1)
0;

// Write
always @(posedge clk) begin
if (Reg_Write) begin
Regs_File[Write_Addr] <= Write_Data;
end

end
//Read
assign Read_Data1 = Regs_File[Read_Addr1];
assign Read_Data2 = Regs_File[Read_Addr2];
endmodule
3.2.4

ALU (Arthmetic- Logic Unit)

Bộ số học và logic là nơi thực hiện các phép toán số học và logic trong kiến trúc MIPs. Đối
với các lệnh thuộc nhóm lệnh toán học và logic, khối ALU được sử dụng để thực hiện các phép
tính. Các lệnh nạp, ghi sử dụng khối để tính toán địa chỉ bộ nhớ. Lệnh BNE sử dụng khối này để
so sánh. Lệnh J,JR không sử dụng khối này.
ALU Control
10000x
10001x
100100
100101
100110
100111
101xx0
101xx1

Function
ADD
SUB
AND
OR
XOR
NOR

SLT Sign
SLT Unsign

Mô tả
A+B
A–B
A& B
A|B
A^B
~(A | B)
Signed(A) < signed(B)
A
Cấu tạo MIPs ALU gồm:

10






Hai ngõ vào 32bit: BusA, BusB
Một ngõ ra 32bit: Output
Các cờ ngõ ra: zero, overflow, carryout, negative
• Cờ zero: được set khi kết quả bằng 0
• Cờ overflow: được set khi xảy ra tràn khi thực hiện các phép cộng trừ các số có dấu
• Cờ carryout: được set khi có nhớ từ MSB
• Cờ negative: được set khi kết quả âm


3.2.4.1 Thiết kế bộ cộng, trừ 32bit
3.2.4.1.1 Thiết kế bộ cộng 32bit:
Thiết kế bộ cộng 1bit:
A
0
0
0
0
1
1
1
1

Input
B Cin
0
0
0
1
1
0
1
1
0
0
0
1
1
0
1

1

Output
Sum Cout
0
0
1
0
1
0
0
1
1
0
0
1
0
1
1
1

Bảng chân trị

Sau khi tối thiểu hóa, ta được phương trình trạng thái:



Sum = A xor B xor Cin
Cout = AB + Cin(A+B)
module Add_1bit(Sum,Cout,A,B,Cin);

output Sum;
output Cout;
input
A,B;
input
Cin;
wire
temp1,temp2,temp3;
`Xor xor_0 (temp1,A,B);
`And and_0 (temp2,A,B);
`And and_1 (temp3,temp1,Cin);
`Xor Sum_Result (Sum,temp1,Cin);
`Or
Cout_Result (Cout,temp2,temp3);
endmodule
11


12


Bộ cộng 32 bit được thiết kế bằng cách sử dụng 32 bộ 1bit:
module Add(Sum,Overflow,Cout,A,B,Cin);
output [31:0]Sum;
output Overflow,Cout;
input
[31:0]A,B;
input
Cin;
wire

[31:0]C_out;
Add_1bit
Add_1bit
Add_1bit

Add_1bit

bit0 (Sum[0] ,C_out[0] ,A[0] ,B[0] ,Cin);
bit1 (Sum[1] ,C_out[1] ,A[1] ,B[1] ,C_out[0]);
bit2 (Sum[2] ,C_out[2] ,A[2] ,B[2] ,C_out[1]);
bit31(Sum[31],Cout

,A[31],B[31],C_out[30]);

//Overflow = Cout[31] xor Cout[30]
`Xor OverFlow(Overflow,Cout,C_out[30]);
endmodule
3.2.4.1.2 Thiết kế bộ cộng, trừ 32bit
Thực tế, việc thực hiện phép toán A – B cũng chính là thực hiện phép toán A + (~B) với
Cin = 1.
Do đó, ta có thể sử dụng một bộ cộng 32bit để thực hiện cả phép cộng và phép trừ. Việc
cần chú ý chỉ là lựa chọn giá trị input tại bus B và Cin sao cho phù hợp với từng phép toán. Ta sử
dụng một ngõ vào Select để lựa chọn phép tính. Với Select = 0 thực hiện phép toán cộng và
ngược lại.
B
0
0
1
1


Select
0
1
0
1

B_select
0
1
1
0

Lựa chọn B_select
Select
0
1

Cin
0
1

Lựa chọn Cin

Bảng chân trị trên cho ta thấy rõ hơn việc lựa chọn giá trị của B và Cin để thực hiện phép
toán (với B_select là giá trị B được lựa chọn). Từ đó có thể xác định được phương trình trạng
thái của B_select va Cin như sau:
13






B_select = B xor Select
Cin = Select
module AddSub(Add_Sub_result, Overflow,
Cout,A,B,Select);
output [31:0]Add_Sub_result;
output Overflow, Cout;
input
[31:0] A, B;
input
Select;
wire
[31:0] temp;
Xor_32_1 Slct(temp,B,Select);
Add Add_Sub(Add_Sub_result,Overflow,Cout,A,temp,Select);
Endmodule

3.2.4.2 Thiết kế bộ logic
Bộ logic thực hiện các phép tính logic gồm And, Or, Xor, Nor. Ta có thể thiết kế các bộ
And, Or, Xor, Nor 32bit từ các bộ And, Or, Xor, Nor 1bit. Dưới đây là ví dụ về 1 bộ Xor 32bit sử
dụng 32 bộ Xor 1bit. Ta thực hiện tương tự với các bộ And, Or, Nor.
module Xor_32bit(Xor_32,A, B);
output [31:0] Xor_4;
input [31:0] A, B;
`Xor
`Xor
`Xor

`Xor


Xor0(Xor_32[0], A[0], B[0]);
Xor1(Xor_32[1], A[1], B[1]);
Xor2(Xor_32[2], A[2], B[2]);
Xor31(Xor_32[31], A[31], B[31]);

Endmodule
Sử dụng ngõ vào Select 2bit để lựa chọn kết quả của bộ logic tương ứng với các phép logic
Select
Phép logic
00
And
01
Or
10
Xor
11
Nor
module Logic(Logic_result, A,B,Select);
output reg [31:0] Logic_result;
input [31:0] A,B;
input [1:0] Select;
wire
[31:0]
And_Result,Or_Result,Nor_Result,Xor_Result;
14


And32 Logic_And(And_Result,A,B);
Or32 Logic_Or (Or_Result,A,B);

Nor32 Logic_Nor(Nor_Result,A,B);
Xor32 Logic_Xor(Xor_Result,A,B);
always@(*)
begin
case (Select[1:0])
2'b00: Logic_result = And_Result;
2'b01: Logic_result = Or_Result;
2'b10: Logic_result = Xor_Result;
2'b11: Logic_result = Nor_Result;
endcase
end
endmodule
3.2.4.3 Khối ALU
module ALU(ALU_result,Zero, Overflow, Cout,
Negative,A,B,Funct);
output reg [31:0]ALU_result;
output Zero, Overflow, Cout, Negative;
input [31:0]A,B;
input [5:0] Funct;
wire [31:0] Add_Sub_result,Logic_result;
wire Of,C_out;
reg
[31:0] SLT_result;
wire zero;
AddSub Add_Sub(Add_Sub_result,Of,C_out,A,B,Funct[1]);
Logic Logic_r(Logic_result,A,B,Funct[1:0]);
always@(*)
begin
//Set less than
if (Funct[0])begin

SLT_result = A < B;
end else begin
SLT_result = $signed(A) < $signed(B);
end
//chon ket qua alu
//-----------------------------s--------------------------if (Funct[5:2] == 4'b1000) begin
15


ALU_result = Add_Sub_result;
end else if (Funct[5:2] == 4'b1001) begin
ALU_result = Logic_result;
end else if (Funct[5:3] == 3'b101) begin
ALU_result = SLT_result;
end else begin
ALU_result = B;
end
end
`Nor32 zero_result(zero, ALU_result,
'b00000000000000000000000000000000);
assign Zero = zero;
assign Negative = ALU_result[31];
assign Cout = C_out;
assign Overflow = Of;
endmodule
3.2.4.4 ALU Control
Bộ ALU Control kết hợp tín hiệu điều khiển của Control Unit và 6bit Function từ mã lệnh,
để tạo tín hiệu điều khiển cho bộ ALU.

Lệnh

LW
SW
BNE
XORI
ANDI
ORI
ADDI
AND
OR
NOR
XOR
ADD
SUB
SLT

ALU
Opcode
100011
101011
000101
001110
001100
001101
001000
000000
000000
000000
000000
000000
000000

000000

Function

ALU Function

xxxxxx
xxxxxx
xxxxxx
xxxxxx
xxxxxx
xxxxxx
xxxxxx
100100
100101
100111
100110
100000
100010
101xx0

100000
100000
100010
100110
100100
100101
100000
100100
100101

100111
100110
100000
100010
101xx0

Bảng tín hiệu điều khiển ALU
module ALU_Ctrl(ALU_Funct,Opcode, funct_in);
output reg [5:0]ALU_Funct;
input [5:0]Opcode;
16


input [5:0]funct_in;
// Constants
localparam ALU_DONT_CARE = 6'b000000;
localparam R_TYPE = 6'd0;
localparam ADDI = 6'b001000;
localparam ADD_FUNC = 6'b100000;
localparam SUB_FUNC = 6'b100010;
localparam LW = 6'b100011;
localparam SW = 6'b101011;
localparam BNE = 6'b000101;
localparam FANDI= 6'b100100;
localparam FORI= 6'b100101;
localparam FXORI= 6'b100110;
localparam FLUI= 6'b100101;
localparam ADDIU= 6'b001001;
localparam ANDI= 6'b001100;
localparam ORI= 6'b001101;

localparam XORI= 6'b001110;
always @(*)
begin
//defaults
ALU_Funct = ALU_DONT_CARE;
if(Opcode == R_TYPE)
begin
ALU_Funct = funct_in;
end
else
begin
case(Opcode)
BNE:
begin
ALU_Funct = SUB_FUNC;
end
ADDI:
begin
ALU_Funct = ADD_FUNC;
end
LW:
begin
ALU_Funct = ADD_FUNC;
end
SW:
begin
ALU_Funct = ADD_FUNC;
17



end
ANDI:
begin
ALU_Funct = FANDI;
end
ORI:
begin
ALU_Funct = FORI;
end
XORI:
begin
ALU_Funct = FXORI;
end
endcase
end
end
endmodule
3.2.5

Data Memory
Là nơi lưu trữ dữ liệu.
Nhận kết quả của ALU làm địa chỉ tại ngõ vào.
Khi tín hiệu MemWrite=1 thì dữ liệu mới sẽ được ghi vào.

Khi tín hiệu MemRead=1 thì khối này đọc dữ liệu, trong quá trình đọc dữ liệu khối này
“phản ứng” theo combination logic.

module Data_Memory(Read_Data, Addr, Write_Data,
Write_En, Read_En, clk);
output [31:0]Read_Data;

input [31:0]Addr, Write_Data;
input Write_En, Read_En;
input clk;
18


reg
reg

[31:0]Data_Mem[1023:0];
[31:0]temp;

buf #100

buf0(Read_Data[0], temp[0]),
buf1(Read_Data[1], temp[1]),
buf2(Read_Data[2], temp[2]),


buf31(Read_Data[31], temp[31]);
always @(posedge clk)
if(Write_En)
begin
Data_Mem[Addr]
end

= Write_Data[31:0];

always @(Addr or Data_Mem[Addr])
if(Read_En)

begin
temp = Data_Mem[Addr];
end
endmodule
3.2.6

Control Unit

Control Unit nhận tín hiệu đầu vào là 6bit opcode trong mã lệnh. Dựa vào giá trị của 6bit
opcode này, Control Unit sẽ tạo ra các tín hiệu điều khiển để điều khiển các khối khác trong
MIPs.
Các tín hiệu điều khiển:















RegDst: chọn thanh ghi đích cho Register File
RegDst = 0 đối với lệnh loại I, rt là thanh ghi đích
RegDst = 0 đối với lệnh loại R, rd là thanh ghi đích

Jump: Cho phép thực hiện lệnh nhảy Jump
Branch: Cho phép thực hiện lệnh rẽ nhánh BNE
MemRead: Cho phép đọc dữ liệu từ bộ nhớ
MemWrite: Cho phép ghi dữ liệu vào bộ nhớ
ALUSrc: Chọn ngõ vào thứ 2 cho bộ ALU
ALUSrc = 0: ngõ vào là giá trị của thanh ghi rt
ALUSrc = 1: ngõ vào là giá trị Immediate đã được mở rộng thành 32bit
RegWrite: Cho phép ghi dữ liệu vào thanh ghi đích
MemtoReg: Chọn giá trị để ghi vào Register File.
MemtoReg = 0: ghi dữ liệu từ kết quả ALU vào Register File
MemtoReg = 1: ghi dữ liệu từ bộ nhớ vào Register File
19





SignZero: xác định phương thức mở rộng bit
 SignZero = 0: Mở rộng dấu
 SignZero = 1: Mở rộng không
ALUopcode: Xác định phép toán cần thực hiện

Lện
h

Opcode

Output
Reg Jump
Dst


Branch

Mem
Read

Mem
Write

ALU
Src

Reg
Write

R
type
Lw
Sw
BNE
J
XorI
Add
I
And
I
OrI

000000


1

0

0

0

0

0

100011
101011
000101
000010
001110
001000

0
X
X
x
0
0

0
0
0
1

0
0

0
0
1
0
0
0

1
0
0
0
0
0

0
1
0
0
0
0

001100

0

0


0

0

001101

0

0

0

0

3.2.7

Sign
Zero

ALU
opcode

1

Mem
to
Reg
0

x


000000

1
1
0
x
1
1

1
0
0
0
1
1

1
X
x
x
0
0

0
0
0
x
1
1


100011
101011
000101
xxxxxx
001110
001000

0

1

1

0

1

001100

0

1

1

0

1


001101

Các thành phần khác

3.2.7.1 JR Control
Kết hợp giá trị của tín hiệu điều khiển ALU opcode từ Control Unit và 6 bit Function giải
mã từ lệnh để tạo ra tín hiệu JR_ctrl điều khiển thực hiện lệnh Jump Register.
Địa chỉ lệnh Jump Register chính là dữ liệu lưu trong thanh ghi Rs.
module JR_control(JR_ctr, Funct, ALU_Opcode);
output reg JR_ctr;
input [5:0]Funct;
input [5:0]ALU_Opcode;
wire [11:0]temp;
assign temp = {ALU_Opcode,Funct};
always@(temp)
begin
case(temp)
20


12'b000000001000: JR_ctr = 1'b1;
default: JR_ctr = 1'b0;
endcase
end
endmodule

21


3.2.7.2 Extender

Dùng để mở rộng 16bit Immediate
Dữ liệu vào 16 bit sẽ được mở rộng thành 32 bit. Tùy thuộc vào tín hiệu điều khiển
SignZero từ Control Unit mà dữ liệu vào sẽ được mở rộng với các giá trị 0 hoặc với bit thứ 16
của dữ liệu vào.

3.2.7.3 Shift left 2
Dùng để nhân dịch dữ liệu sang trái 2 bit.

3.2.7.4 MUX
Bộ chọn kênh dùng để lựa chọn một ngõ vào trong nhiều ngõ vào.

22


3.3

DATAPATH CỦA MIPS CPU

Tổng quát việc thực thi lệnh bao gồm các bước sau:
 Lấy lệnh
 Giải mã lệnh
 Thực hiện lệnh
Các lệnh khác nhau có chung các bước lấy lệnh và giải mã lệnh. Chúng ta sử dụng thanh
ghi PC (chứa địa chỉ của câu lệnh hiện thời ) để lấy lệnh từ Instruction memory và sau đó tăng
PC thành PC+4 để chỉ đến lệnh tiếp theo. Tiếp theo câu lệnh sẽ được đưa đến khối Control Unit
và Register File để giải mã câu lệnh, xác định thanh ghi nào cần sử dụng, mục đích của câu lệnh
là thực hiện nhiệm vụ gì.

Các bước tiếp theo của quá trình thực thi lệnh phụ thuộc vào các cấu trúc của từng lệnh.
Chúng ta sẽ xem xét các khuôn dạng lệnh để thiết kế các datapath cho từng lệnh sao cho phù

hợp.

3.3.1

Datapath của các lệnh toán học và logic :
 ADD, SUB, AND, OR, XOR, NOR, SLT :
Các lệnh này thuộc khuôn dạng lệnh R-type :

Các toán hạng của các phép toán là các giá trị chứa trong các thanh ghi có địa chỉ nằm
trong trường rs,rt. Trường op và func cho biết chính xác chúng ta phải thực hiện phép toán nào.
Kết quả tính toán được sẽ được lưu vào thanh ghi trong Register File có địa chỉ nằm trong trường
rd.
23


 ADDI, ANDI, ORI, XORI :
Lệnh này thuộc dạng I- type :

Lệnh này thực hiện phép toán XOR giữa một giá trị được chứa trong thanh ghi( thanh ghi
này có địa chỉ chứa trong trường rs ) với một giá trị hằng. Giá trị hằng này chứa trong câu lệnh là
16bit nhưng nó sẽ được mở rộng thành giá trị 32 bit. Kết quả của phép toán sẽ được lưu vào
thanh ghi trong Register File, thanh ghi này có địa chỉ nằm trong trường rt.

24


3.3.2

Datapath của các lệnh nạp, ghi :


Các lệnh LW và SW thuộc khuôn dạng lệnh I-type. Trong khuôn dạng lệnh I-type trường
address 16bit tương ứng với offset và trường rs tương ứng với base register trong câu lện LW,
SW. Đối với lệnh LW thì trường rt là địa chỉ đến và đối với lệnh SW thì trường này là nguồn.
 LW :
Các offset 16 bit sẽ được mở rộng dấu thành 32 bit. Khối ALU được sử dụng để tính tổng
giữa offset đã được mở rộng với giá trị chứ trong thanh ghi mà base register chỉ đến. Kết
quả của phép tính này được xem là địa chỉ của vị trí nhớ trong Data memory. Giá trị của ô
nhớ này sẽ được ghi lại vào trong Register File, vào thanh ghi có địa chỉ nằm trong trường
rt.



SW :

Các offset 16 bit sẽ được mở rộng dấu thành 32 bit. Khối ALU được sử dụng để tính tổng
giữa offset đã được mở rộng với giá trị chứ trong thanh ghi mà base register chỉ đến. Kết
25


×