You are on page 1of 87

ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH

TRƯỜNG ĐẠI HỌC BÁCH KHOA


KHOA ĐIỆN – ĐIỆN TỬ
------

BÁO CÁO XỬ LÝ TÍN HIỆU SỐ VỚI FPGA

BÀI TẬP LỚN

Giáo viên hướng dẫn : Nguyễn Lý Thiên Trường


Nhóm thực hiện : 10
Danh sách thành viên : Nguyễn Minh Tân 1813940
Phạm Đăng Long 1812930
Mai Phú Thành 1814014
Hoàng Bá Duy 1811704

Trang 1

TP. Hồ Chí Minh, Tháng 12/2021


Danh sách thành viên:

STT Họ và Tên MSSV Email

1 Nguyễn Minh Tân 1813940 tan.nguyen.28112000@hcmut.edu.vn

2 Phạm Đăng Long 1812930 long.phambkforever@hcmut.edu.vn

3 Mai Phú Thành 1814014 thanh.mai.1801@hcmut.edu.vn

4 Hoàng Bá Duy 1811704 duy.hoang123456@hcmut.edu.vn

Danh sách phân công nhiệm vụ:

STT Họ và Tên Nhiệm vụ cụ thể

Phần chung: Bài 1,


1 Nguyễn Minh Tân
Tổng hợp báo cáo

Phần chung: Bài 5


2 Phạm Đăng Long
Phần riêng: Bài 2

Phần chung: Bài 4


3 Mai Phú Thành
Phần riêng: Bài 1

4 Hoàng Bá Duy Phần chung: Bài 2, Bài 3

Trang 2
MỤC LỤC

1. Phần chung cho tất cả các nhóm: .....................................................................................5

1.1. Bài 1: ................................................................................................................................ 5

1.1.1. Đề bài: ...................................................................................................................... 5

1.1.2. Giải thuật thứ nhất: ................................................................................................ 6

1.1.3. Giải thuật thứ hai: ................................................................................................ 15

1.2. Bài 2: .............................................................................................................................. 21

1.2.1. Đề bài: .................................................................................................................... 21

1.2.2. Cơ sở lý thuyết : .................................................................................................... 21

1.2.3. Giải thuật tính toán: ............................................................................................. 22

1.2.4. Code mô phỏng: .................................................................................................... 23

1.2.5. Kết quả mô phỏng:................................................................................................ 28

1.2.6. Đánh giá tài nguyên phần cứng khi thực thi trên FPGA Cyclone II
EP2C35F672C6 ................................................................................................................... 31

1.3. Bài 3: .............................................................................................................................. 32

1.3.1. Đề bài: .................................................................................................................... 32

1.3.2. Giải thuật tính căn tính toán từng chữ số (Digit-by-digit calculation) ............ 32

1.3.3. Code thực hiện và kết quả mô phỏng .................................................................. 35

1.3.4. Đánh giá tài nguyên phần cứng khi thực thi trên FPGA Cyclone II
EP2C35F672C6 ................................................................................................................... 39

1.4. Bài 4: .............................................................................................................................. 40

1.4.1. Giới thiệu: .............................................................................................................. 40

1.4.2. Mô phỏng kết quả - Đánh giá tài nguyên: .......................................................... 43

1.4.3. Code design – code testbench: ............................................................................. 48

1.5. Bài 5: .............................................................................................................................. 57

Trang 3
1.5.1. Đề bài: .................................................................................................................... 57

1.5.2. Cơ sở lý thuyết: ..................................................................................................... 57

1.5.3. Code thực hiện và kết quả mô phỏng: ................................................................ 60

1.5.4. Kết quả đánh giá tài nguyên phần cứng khi thực thi trên FPGA Cyclone IV
EP4CGX15BF14C6: ........................................................................................................... 64

2. Phần riêng nhóm 10: ........................................................................................................65

2.1. Bài 1: .............................................................................................................................. 65

2.1.1. Đề bài: .................................................................................................................... 65

2.1.2. Câu 1: Tính giới hạn lặp 𝑇∞ bằng quan sát và giải thuật LPM (Sinh viên tự quy
ước cách đánh số thứ tự các phần tử delay). .................................................................... 66

2.1.3. Câu 2: Viết code Matlab kiểm tra lại kết quả thực hiện giải thuật LPM ở câu 1.
68

2.1.4. Câu 3: Chỉ ra (các) đường tới hạn và thời gian tính toán tới hạn Tcritical? ...... 72

2.1.5. Câu 4: Tái định thì hệ thống trên sao cho đường tới hạn mới T’critical = 10 u.t.
72

2.1.6. Câu 5: Viết code Matlab thực hiện giải thuật Bellman-Ford kiểm chứng lại giá
trị tái định thì các nút ......................................................................................................... 75

2.2. Bài 2: .............................................................................................................................. 86

Trang 4
Nội dung

1. Phần chung cho tất cả các nhóm:


1.1. Bài 1:
1.1.1. Đề bài:
Cho sơ đồ khối của hệ thống tìm số nhỏ nhất thứ nhất (min1), số nhỏ nhất thứ 2 (min2)
và vị trí của số nhỏ nhất thứ nhất (index_min1) trong 𝑛 số không dấu ngõ vào như hình bên
dưới.

Hình 1.1.1.Bộ min_finder

Lưu ý:

 Thực thi hệ thống trên với 𝑛 = 16


 Các ngõ vào I0, I1,…, In-1 là các số nhị phân 4 bit không dấu.
 Trường hợp ngõ vào có nhiều hơn 2 giá trị min1, thì ngõ ra index_min1 chỉ vị trí
ngõ vào có chỉ số nhỏ hơn.
1. Đề xuất 2 giải thuật thực thi hệ thống trên (sơ đồ khối, giải thích chi tiết).

2. Viết code Verilog mô tả 2 giải thuật đã đề xuất ở trên. Sử dụng phần mềm mô phỏng
(ví dụ: ModelSim) kiểm tra chức năng hệ thống (chụp lại hình kết quả mô phỏng).

Trang 5
3. Đánh giá tài nguyên phần cứng khi thực thi 2 giải thuật đề xuất trên FPGA Cyclone V
5CGXFC7C7F23C8.

1.1.2. Giải thuật thứ nhất:


 Lưu đồ giải thuật:

Hình 1.1.2. Lưu đồ giải thuật

Đầu tiên, ta ghép 2 phần gồm giá trị của port và số thứ tự của port đó vào để thực
hiện so sánh, gọi là IN[i]. Khi so sánh, nếu phần giá trị của 2 port bằng nhau, ta sẽ so
sánh số thứ tự của port đó.

Trang 6
Tiếp theo, ta lưu min_1 và index_min1 tương ứng với giá trị của port 0 và số thứ
tự của nó: 0 và min_2 là giá trị của port 1.

Ta lần lượt so sánh cặp min_1, index_min1 và giá trị min_2 với giá trị tương ứng
(có hoặc không có số thứ tự) của các port từ 1 đến 9. Khi đó sẽ có 2 trường hợp xảy ra:

Thứ nhất, cặp min_1, index_min1 lớn hơn IN[i]. Khi đó, ta thay min_1, index_min1
bởi các giá trị tương ứng của port thứ i và thay min_2 bởi min_1.

Thứ hai, cặp min_1, index_min1 bé hơn IN[i]. Ta sẽ tiếp tục so sánh giá trị của port
thứ i với min_2. Nếu min_2 lớn hơn giá trị của port thứ i thì ta cập nhật giá trị đó cho
min_2 và ngược lại thì ta giữ nguyên min_2.

 Code thực hiện:

module
min_finder(rst,clk,in0,in1,in2,in3,in4,in5,in6,in7,in8,in9,in10
,in11,in12,in13,in14,in15,min1,min2,index_min1,nflag);
localparam n = 16;
input rst,clk;
input[3:0] in0, in1, in2, in3, in4, in5, in6, in7, in8,
in9, in10, in11, in12, in13, in14, in15;
output reg[3:0] min1,min2;
output reg[3:0] index_min1;
output reg nflag;
reg[7:0] reg_in0 ,reg_in1, reg_in2, reg_in3, reg_in4,
reg_in5, reg_in6, reg_in7, reg_in8, reg_in9, reg_in10,
reg_in11, reg_in12, reg_in13, reg_in14, reg_in15, temp;
reg[7:0] reg_min1;
reg[3:0] reg_min2;
wire cp1,cp2,flag_0;
reg[3:0] count;

Trang 7
mf_compare CP1 (reg_min1,reg_in1,cp1);
cp CP2 (reg_min2,reg_in1[3:0],,cp2);
assign flag_0 = |(count);

always @(posedge clk) begin


if(rst||(~flag_0)) begin
reg_in0 = {4'b0000,in0};
reg_in1 = {4'b0001,in1};
reg_in2 = {4'b0010,in2};
reg_in3 = {4'b0011,in3};
reg_in4 = {4'b0100,in4};
reg_in5 = {4'b0101,in5};
reg_in6 = {4'b0110,in6};
reg_in7 = {4'b0111,in7};
reg_in8 = {4'b1000,in8};
reg_in9 = {4'b1001,in9};
reg_in10 = {4'b1010,in10};
reg_in11 = {4'b1011,in11};
reg_in12 = {4'b1100,in12};
reg_in13 = {4'b1101,in13};
reg_in14 = {4'b1110,in14};
reg_in15 = {4'b1111,in15};
end
else begin
temp = reg_in0;
reg_in0 = reg_in1;
reg_in1 = reg_in2;
reg_in2 = reg_in3;
reg_in3 = reg_in4;
reg_in4 = reg_in5;
reg_in5 = reg_in6;

Trang 8
reg_in6 = reg_in7;
reg_in7 = reg_in8;
reg_in8 = reg_in9;
reg_in9 = reg_in10;
reg_in10 = reg_in11;
reg_in11 = reg_in12;
reg_in12 = reg_in13;
reg_in13 = reg_in14;
reg_in14 = reg_in15;
reg_in15 = temp;
end
end

always @(posedge clk) begin


if(rst) begin
count = 4'b1111;
nflag = 1'b1;
end
else if(flag_0) count = count - 1;
else begin
{index_min1,min1} = reg_min1;
min2 = reg_min2;
nflag = 1'b0;
end
end

always @(negedge clk) begin


if (rst) begin
reg_min1 = {4'b0000,in0};
reg_min2 = in1;
end

Trang 9
else if(cp1&flag_0) begin
reg_min2 = reg_min1[3:0];
reg_min1 = reg_in1;
end
else if(cp2&flag_0) reg_min2 = reg_in1[3:0];
end
endmodule

module mf_compare(in0,in1,out);
input[7:0] in0,in1;
output reg out;
wire[1:0] eq, grt;

cp COMP0 (in0[3:0],in1[3:0],eq[0],grt[0]);
cp COMP1 (in0[7:4],in1[7:4],eq[1],grt[1]);
always @* begin
if(eq[0])
out <= grt[1];
else
out <= grt[0];
end
endmodule

module cp(in0,in1,eq,grt);
//grt = 1 if in1<in0
input[3:0] in0,in1;
output eq,grt;
wire[4:0] node_eq, node_ge;

assign node_eq[0] = 1'b1;


assign node_ge[0] = 1'b1;

Trang 10
cp_slice SLICE0
(node_eq[0],node_ge[0],in0[0],in1[0],node_eq[1],node_ge[1]);
cp_slice SLICE1
(node_eq[1],node_ge[1],in0[1],in1[1],node_eq[2],node_ge[2]);
cp_slice SLICE2
(node_eq[2],node_ge[2],in0[2],in1[2],node_eq[3],node_ge[3]);
cp_slice SLICE3
(node_eq[3],node_ge[3],in0[3],in1[3],node_eq[4],node_ge[4]);

assign eq = node_eq[4];
assign grt = node_ge[4]&(~eq);
endmodule

module cp_slice(eq_i,ge_i,in0,in1,eq,ge);
input eq_i,ge_i,in0,in1;
output eq,ge;
wire node1;
assign node1 = ~(in0^in1);
assign eq = eq_i&node1;
assign ge = (node1&ge_i)|(in0&(~in1));
endmodule

 Code testbench:

module testbench_minfinder();
reg rst,clk;
reg[3:0]
in0,in1,in2,in3,in4,in5,in6,in7,in8,in9,in10,in11,in12,in13,in1
4,in15;

Trang 11
wire[3:0] min1,min2;
wire[3:0] index_min1;
wire nflag;

min_finder MF
(rst,clk,in0,in1,in2,in3,in4,in5,in6,in7,in8,in9,in10,in11,in12
,in13,in14,in15,min1,min2,index_min1,nflag);

initial begin
rst = 0;
in0 = 1; in1 = 2; in2 = 9; in3 = 5; in4 = 7; in5 = 15;
in6 = 4; in7 = 8; in8 = 11; in9 = 12; in10 = 4; in11 = 13; in12
= 6; in13 = 9; in14 = 14; in15 = 5; rst = 1; #2; rst = 0; #100
in0 = 11; in1 = 0; in2 = 5; in3 = 5; in4 = 7; in5 = 5;
in6 = 4; in7 = 11; in8 = 11; in9 = 12; in10 = 4; in11 = 13;
in12 = 6; in13 = 9; in14 = 14; in15 = 9; rst = 1; #2; rst = 0;
#100
in0 = 11; in1 = 9; in2 = 9; in3 = 7; in4 = 7; in5 = 7;
in6 = 7; in7 = 11; in8 = 11; in9 = 12; in10 = 4; in11 = 13;
in12 = 2; in13 = 11; in14 = 10; in15 = 5; rst = 1; #2; rst = 0;
#100
$finish;
end
initial begin
forever begin
clk = 0; #1;
clk = 1; #1;
end
end
initial begin
$dumpfile("waveform.vcd");

Trang 12
$dumpvars(1);
end
endmodule

 Kết quả giải thuật:

I0 I1 I2 I3 I4 I5 I6 I7 I8 I9 I10 I11 I12 I13 I14 I15 Min1 Min2 Index_min1


1 2 9 5 7 15 4 8 11 12 4 13 6 9 14 5 1 2 0
11 0 5 5 7 5 4 11 11 12 4 13 6 9 14 9 0 4 1
11 9 9 7 7 7 7 11 11 12 4 13 2 11 10 5 2 4 12

 Mô phỏng dạng sóng:

Hình 1.1.3. Kết quả mô phỏng của giải thuật thứ nhất

Trang 13
 Đánh giá tài nguyên phần cứng:

Hình 1.1.4. Kết quả đánh giá phần cứng

Kết luận: Ở đây, ta thấy thiết kế sử dụng 344 logic elements (chiếm khoảng 2% số
logic elements của thiết bị), bao gồm: 344 hàm tổ hợp. Ngoài ra tổng số pins là 76 (chiếm
46% số pins của thiết bị).

Trang 14
1.1.3. Giải thuật thứ hai:
 Lưu đồ giải thuật:

Hình 1.1.5. Lưu đồ giải thuật thứ hai

Đầu tiên, ta gán giá trị port vào I[i] với i là vị trí của các port và gán vào smallest là giá
trị 15. Tiếp theo, ta bắt đầu vòng lập so sánh:

- Nếu I[i] < smallest và k == 0 thì giá trị smallest sẽ được gán bằng I[i], index sẽ
được gán bằng i và tiếp tục so sánh cho tới khi hết vòng lặp. Sau khi kết thúc
vòng lặp, ta sẽ gán min1 bằng smallest và index_min1 bằng index
- Nếu I[i] < smallest ,k khác 0 và min1< I[i] thì giá trị smallest sẽ được gán
bằng I[i] và tiếp tục so sánh cho tới khi hết vòng lặp. Sau khi kết thúc vòng lặp,
ta sẽ gán min2 bằng smallest.
Khi k = 2, giải thuật sẽ kết thúc.

 Code giải thuật hai:

Trang 15
module min_finder_2(in0, in1, in2, in3, in4, in5, in6, in7,
in8, in9, in10, in11, in12, in13, in14, in15, min1, min2,
index_min1);
input [3:0] in0, in1, in2, in3, in4, in5, in6, in7, in8, in9,
in10, in11, in12, in13, in14, in15;
output [3:0] min1, min2;
output [3:0] index_min1;

reg [3:0] I [15:0];


reg [3:0] min1, min2;
reg [3:0] index, index_min1;
reg [3:0] smallest;
integer i, k;

always @(*) begin


I[0] = in0;
I[1] = in1;
I[2] = in2;
I[3] = in3;
I[4] = in4;
I[5] = in5;
I[6] = in6;
I[7] = in7;
I[8] = in8;
I[9] = in9;
I[10] = in10;
I[11] = in11;
I[12] = in12;
I[13] = in13;
I[14] = in14;
I[15] = in15;

Trang 16
for (k=0; k<2; k = k+1) begin
smallest = 4'b1111;
for (i=0; i<16; i=i+1) begin
if ((I[i] < smallest) && (k == 0)) begin
smallest = I[i];
index = i;
end
else if ((I[i] < smallest) && (I[i] > min1))
begin
smallest = I[i];
end
end
if (k == 0) begin
min1 = smallest;
index_min1 = index;
end
else min2 = smallest;
end
end
endmodule

 Code testbench:

module testbench_minfinder_2();
reg [3:0] in0, in1, in2, in3, in4, in5, in6, in7, in8, in9,
in10, in11, in12, in13, in14, in15;
wire [3:0] min1, min2;
wire [3:0] index_min1;

Trang 17
min_finder_2 fm2(in0, in1, in2, in3, in4, in5, in6, in7, in8,
in9, in10, in11, in12, in13, in14, in15, min1, min2,
index_min1);

initial begin
in0 = 5; in1 = 4; in2 = 3; in3 = 8; in4 = 9; in5 = 10; in6
= 3; in7 = 0; in8 = 6; in9 = 12; in10 = 5; in11 = 12; in12 =
14; in13 = 9; in14 = 6; in15 = 13; #100;
in0 = 3; in1 = 7; in2 = 8; in3 = 2; in4 = 12; in5 = 2; in6
= 9; in7 = 4; in8 = 5; in9 = 11; in10 = 12; in11 = 12; in12 =
14; in13 = 9; in14 = 6; in15 = 1; #100;
end
always @(*) begin
#20
$display("min1 = %d", min1);
$display("min2 = %d", min2);
$display("index_min1 = %d", index_min1);
end
endmodule

 Kết quả giải thuật:


I0 I1 I2 I3 I4 I5 I6 I7 I8 I9 I10 I11 I12 I13 I14 I15 Min1 Min2 Index_min1
5 4 3 8 9 10 3 0 6 12 5 12 14 9 6 13 0 3 7
3 7 8 2 12 2 9 4 5 11 12 12 14 9 6 1 1 2 15

 Mô phỏng dạng sóng:

Trang 18
Hình 1.1.6. Kết quả mô phỏng dạng sóng

 Đánh giá tài nguyên phần cứng:

Hình 1.1.7. Kết quả đánh giá phần cứng

Trang 19
Kết luận: Ở đây, ta thấy thiết kế sử dụng 179 logic elements (chiếm chưa đến 1% số
logic elements của thiết bị), bao gồm: 167 hàm tổ hợp và 157 thanh ghi. Ngoài ra tổng số
pins là 79 (chiếm 47% số pins của thiết bị).

Trang 20
1.2. Bài 2:
1.2.1. Đề bài:
Tìm hiểu ít nhất 1 giải thuật và viết code Verilog tính gần đúng giá trị log2(x),
với x là số 16 bit không dấu.

 Sử dụng phần mềm mô phỏng kiểm tra chức năng hệ thống (chụp lại hình
kết quả mô phỏng). Đánh giá sai số giữa kết quả mô phỏng này với kết quả
dùng phần mềm Matlab.
 Đánh giá tài nguyên phần cứng khi thực thi trên FPGA Cyclone II
EP2C35F672C6.

1.2.2. Cơ sở lý thuyết :
Phép toán logarit được sử dụng rộng rãi trong xử lý tín hiệu số. Có nhiều ứng
dụng khoa học yêu cầu tính toán logarit.

Một phép toán logarit nhị phân có thể được xác định theo phương trình (1):

𝑦 = log 2 (𝑥) (1)

Đảo phương trình (1) ta được phương trình (2):

𝑥 = 2𝑦 (2)

y có thể được biểu diễn dưới dạng nhị phân như có thể thấy trong phương trình
(3):

𝒚 = ∑∞
𝑖=1 𝑦𝑖 2
−𝑖
= 𝑦1 2−1 + 𝑦2 2−2 + 𝑦3 2−3 + ⋯ (3)
với: 𝑦𝑖 = 0 hoặc 𝑦𝑖 = 1

Đưa phương trình (3) vào phương trình (2) ta được phương trình (4) như sau:

−1 + 𝑦 2−2 +𝑦 2−3 +⋯
𝑥 = 2𝑦1 2 2 3 (4)

Trang 21
Từ phương trình (3) và (4) có thể suy ra rằng giá trị lớn nhất của y là 1 (tổng của
một cấp tiến hình học với tỷ lệ chung 0,5 khi tất cả các bit của y là 1) và do đó giá trị lớn
nhất của x là 2.

Phương trình bình phương (4) cho phương trình (5) như có thể thấy dưới đây:

−1 +𝑦 2−2 +𝑦 2−3 +⋯
𝑥 2 = 2 𝑦1 2 𝑦22 3 3 (5)

Từ phương trình (5) cho biết giá trị của 𝑥 2 có thể được biểu thị trong 2 trường
hợp:

−1 −2 −3
𝑦 = 0; 𝑥 2 = 2 𝑦2 2 +𝑦32 +𝑦3 2 +⋯
{ 1 −1 −2 −3 (6)
𝑦1 = 1; 𝑥 2 = 2 × 2 𝑦2 2 +𝑦32 +𝑦32 +⋯

Theo phương trình (6) nếu giá trị 𝑥 2 > 2, thì bit thứ i của 𝑦𝑖 là 1 ở lần lặp thứ i
và giá trị của x sẽ chia cho 2, ngược lại, nếu 𝑥 2 ≤ 2, 𝑦𝑖 = 0.

Vì thuật toán nhị phân hoạt động cho 0 ≤ 𝑥 ≤ 1, nếu x lớn hơn 1, x sẽ được chia
tỷ lệ như có thể thấy bên dưới:

𝑥 = 2𝑘 × 𝑚, với 0 ≤ 𝑚 ≤ 1 hay 𝑙𝑜𝑔2 (𝑥 ) = 𝑘 + 𝑙𝑜𝑔2 (𝑚) (7)

(Ta có với mọi giá trị của x, 2𝑘 ≤ 𝑥 < 2𝑘+1 ⇔ 𝑘 ≤ log 2 𝑥 < 𝑘 + 1, nói cách
khác k chính là phần nguyên của kết quả ngõ ra của bài toán)

1.2.3. Giải thuật tính toán:


Từ các phương trình đã trình bày, ta sẽ xây dựng được lưu đồ giải thuật để tìm y
khi biết x như sau:

Trang 22
Hình 1.2.1 Lưu đồ giải thuật

1.2.4. Code mô phỏng:


 Code mô phỏng
module log2(clk,rst,in,out,flag,inf);
input[15:0] in;
input clk, rst;
output reg[15:0] out;
output reg flag, inf;

Trang 23
reg[15:0] sqr_x,temp;
reg[2:0] state;
reg[3:0] count;
wire[3:0] itg;
reg[11:0] frac;

parameter[2:0] INIT = 0, PRESQUARE = 1, SQUARE = 2,


CHECK_BIT = 3, DONE = 4;

log2_itg INTEGER_PART (in,itg);

always @(posedge clk) begin


if(rst) begin
state <= INIT;
inf <= 0;
flag <= 0;
sqr_x <= in;
end
else begin
case(state)
INIT: begin
if(!(|in[15:1])) begin
state <= DONE;
frac <= 0;
if(!in[0]) inf <= 1;
end
else if(!sqr_x[15]) begin
state <= INIT;
sqr_x <= sqr_x << 1;
end
else begin

Trang 24
count <= 12;
state <= PRESQUARE;
inf <= 0;
end
end
PRESQUARE: begin
if(|count == 0) state <= DONE;
else state <= SQUARE;
end
SQUARE: begin
{sqr_x,temp} <= sqr_x[15:0]*sqr_x[15:0];
state <= CHECK_BIT;
frac <= frac<<1;
end
CHECK_BIT: begin
casex(sqr_x[15:14])
2'b1x: begin
frac[0] <= 1;
end
2'b1: begin
frac[0] <= 0;
sqr_x <= {sqr_x[14:0],temp[15]};
end
default: begin
frac[0] <= 1'bz;
end
endcase
state <= PRESQUARE;
count <= count - 1;
end
DONE: begin

Trang 25
flag <= 1;
out <= {itg,frac};
end
default: state <= INIT;
endcase
end
end
endmodule

module log2_itg(in,out);
input[15:0] in;
output reg[3:0] out;

always @* begin
casex(in)
16'b1xxx_xxxx_xxxx_xxxx: out = 15;
16'b1xxx_xxxx_xxxx_xxx: out = 14;
16'b1xxx_xxxx_xxxx_xx: out = 13;
16'b1xxx_xxxx_xxxx_x: out = 12;
16'b1xxx_xxxx_xxxx: out = 11;
16'b1xxx_xxxx_xxx: out = 10;
16'b1xxx_xxxx_xx: out = 9;
16'b1xxx_xxxx_x: out = 8;
16'b1xxx_xxxx: out = 7;
16'b1xxx_xxx: out = 6;
16'b1xxx_xx: out = 5;
16'b1xxx_x: out = 4;
16'b1xxx: out = 3;
16'b1xx: out = 2;
16'b1x: out = 1;
16'b0x: out = 0;

Trang 26
default: out = 4'bx;
endcase
end
endmodule

 Code testbench

module testbench;
reg rst,clk;
reg[15:0] in;
wire[15:0] out;
wire flag,inf;
log2 LOG2 (clk,rst,in,out,flag,inf);
initial begin
rst = 0;
in = 7000; rst = 1; #2; rst = 0; #200;
in = 8436; rst = 1; #2; rst = 0; #200;
in = 1364; rst = 1; #2; rst = 0; #200;
in = 24320; rst = 1; #2; rst = 0; #200;
in = 0; rst = 1; #2; rst = 0; #200;
in = 1; rst = 1; #2; rst = 0; #200;
in = 512; rst = 1; #2; rst = 0; #200;
in = 4096; rst = 1; #2; rst = 0; #200;
in = 65535; rst = 1; #2; rst = 0; #200;

$finish;
end
initial begin
forever begin
clk = 0; #1;
clk = 1; #1;

Trang 27
end
end
initial begin
$dumpfile("waveform.vcd");
$dumpvars(1);
end
endmodule

1.2.5. Kết quả mô phỏng:

initial begin
rst = 0;
in = 7000; rst = 1; #2; rst = 0; #200;
in = 8436; rst = 1; #2; rst = 0; #200;
in = 1364; rst = 1; #2; rst = 0; #200;
in = 14320; rst = 1; #2; rst = 0; #200;
in = 0; rst = 1; #2; rst = 0; #200;
in = 1; rst = 1; #2; rst = 0; #200;
in = 512; rst = 1; #2; rst = 0; #200;
in = 4096; rst = 1; #2; rst = 0; #200;
in = 65535; rst = 1; #2; rst = 0; #200;

Trang 28
Hình 1.2.2. Kết quả mô phỏng dạng sóng 1

Hình 1.2.3. Kết quả mô phỏng dạng sóng 2

Trang 29
Hình 1.2.4. Kết quả mô phỏng dạng sóng 3

Hình 1.2.5. Kết quả khi thực hiện bằng Matlab

Nhận xét:

Kết quả mô phỏng có sự tương đồng với kết quả tính toán được, với sai số lớn nhất 𝟏𝟎−𝟒

Trang 30
1.2.6. Đánh giá tài nguyên phần cứng khi thực thi trên FPGA Cyclone
II EP2C35F672C6

Hình 1.2.5. Kết quả đánh giá tài nguyên phần cứng

Trang 31
1.3. Bài 3:
1.3.1. Đề bài:
Tìm hiểu ít nhất 1 giải thuật và viết code Verilog tính gần đúng giá trị biểu thức
√𝑥 2 + 𝑦 2 , với x và y là các số 16 bit không dấu.

1. Sử dụng phần mềm mô phỏng kiểm tra chức năng hệ thống (chụp lại màn hình
kết quả mô phỏng). Đánh giá sai số giữa kết quả mô phỏng này với kết quả dùng
phần mềm Matlab.
2. Đánh giá tài nguyên phần cứng khi thực thi trên FPGA Cyclone II
EP2C35F672C6.

1.3.2. Giải thuật tính căn tính toán từng chữ số (Digit-by-digit
calculation)
Đây là một phương pháp để tìm từng chữ số của căn bậc hai theo một chuỗi. Có
một số lợi thế như:

 Nó có thể dễ dàng cho tinh toán thủ công.


 Mỗi chữ số của gốc được tìm thấy đều đúng, sẽ không bị thay đổi sau này.
 Có thể sử dụng để kiểm tra một số nguyên đã cho có phải số bình phương
không.
− Nguyên tắc cơ bản:
Xét trường hợp tìm căn của một số z, là bình phương của hai số xy. Trong đó x là
chữ số hàng chục, y là chữ số hàng đơn vị: 𝑧 = (10𝑥 + 𝑦)2 = 100𝑥 2 + 20𝑥𝑦 +
𝑦2

Sử dụng thuật toán từng chữ số, đầu tiên xác định giá trị của x. x là chữ số lớn
nhất sao cho 𝑥 2 nhỏ hơn hoặc bằng z từ đó xóa hai chữ số ngoài cùng bên phải.

Lần lặp tiếp theo, ghép các chữ số, nhân x với 2 và đặt nó ở vị trí hàng chục và
tiếp tục tìm giá trị của y.

Vì đây là một trường hợp đơn giản căn bậc 2 là xy, thuật toán dừng lại ở đây.

Trang 32
− Hệ thập phân (Hệ cơ số 10)
Bắt đầu với cặp chữ số từ bên trái, thực hiện theo từng cặp

1. Bắt đầu từ bên trái, hạ chứ số ngoài cùng bên trái xuống chưa được sử dụng
(nếu các chữ số đã được dùng hãy viết “00”) và viết chúng vào bên phải phần
còn lại của bước trước (bước đầu không có phần dư). Đây là giá trị hiện tại
của c.
2. Tìm các số p, y và x, như sau:
Gọi p là phần căn tìm được cho đến nay, bỏ qua dấu thập phân. (bước đầu p
=0).
Xác định chữ số lớn nhất x sao cho 𝑥(20𝑝 + 𝑥 ) ≤ 𝑐. Ta có 𝑦 =
𝑥 (20𝑝 + 𝑥 )0.
Đặt chữ số x là chữ số tiếp theo của căn bậc. Do đó p mới sẽ là p cũ nhân
10 cộng x.
3. Trừ y với c để tạo thành phần dư mới.
4. Nếu phần dư bằng không và không còn chữ số nào để hạ thì thuật toán kết
thúc. Nếu chưa quay lại bước 1 tính toán lần nữa
Ví dụ tính căn 229.5225

 Step
2 29.52 25
1 02 𝑦 = 𝑥 ∗ 𝑥 ≤ 02 ⇒ 𝑥 = 1, y =1
01
01
2 01 29 𝑦 = (20 + 𝑥) ∗ 𝑥 ≤ 129 ⇒ 𝑥 = 5, y =125
01 25
00 04
3 04 52 𝑦 = (20 ∗ 15 + 𝑥) ∗ 𝑥 ≤ 425 ⇒ 𝑥 = 1, y =301
03 01
01 51

Trang 33
4 01 51 25 𝑦 = (20 ∗ 151 + 𝑥) ∗ 𝑥 ≤ 15125 ⇒ 𝑥 = 5, y =15125
01 51 25
00 00 00

Vậy căn của 229.5225 là 15.15

− Hệ số nhị phân hệ (Hệ cơ số 2)


Kề thừa thuật toán từng chứ số:
X : Giá trị đầu vào và giá trị muốn tính căn
A: Giá trị hiện tại đang tính toán
T: Kết quả phép thử dấu
Q: Căn bậc 2
Bắt đầu với cặp chữ số từ bên trái, thực hiện theo từng cặp 2 chữ số

1. Dịch trái X 2 bit sang vị trí của A. Gán T = A – {Q,01}


2. Gán T = A – {Q,01}. Dịch trái Q 1 bit
3. Kiếm tra T. Nếu T ≥ 0. Gán A = T và LSB của Q =1. Nếu T < 0, tiếp tục
thực hiện
4. Nếu phần dư bằng không và không còn chữ số nào để hạ thì thuật toán kết
thúc. Nếu chưa quay lại bước 1 tính toán lần nữa
Ví dụ tính căn 110.012 (6.2510)

Step A X T Q
00 00 00 01 10 01 00 00 00 000
1 00 00 01 10 01 00
00 00 00 001
00 00 00
2 00 00 10 01 00 00
11 11 01 010
3 00 10 01 00 00 00

Trang 34
00 00 00
101

Vậy căn của 110.012 (6.2510) là 10.12 (2.510)

1.3.3. Code thực hiện và kết quả mô phỏng


 Code thực hiện

module sqrt (a,b,clk,root);


input [15:0]a,b;
input clk;
output reg [23:0]root; // 16 bit truoc dau phay, 8 bit sau dau
phay
reg [31:0] x;
reg [31:0] q;
reg [33:0] ac;
reg [33:0] test_res;
wire [31:0] rad;
wire [31:0]a1,b1;
assign a1 = a*a;
assign b1 = b*b;
assign rad = a1 + b1;
integer i;
always @(posedge clk)
begin
q=0;
{ac, x} = {{32{1'b0}}, rad, 2'b0};
for (i =0; i<24; i= i+1)
begin
test_res = ac - {q,2'b01};
if (test_res[33] == 0)

Trang 35
begin
{ac, x} = {test_res[31:0], x, 2'b0};
q = {q[30:0], 1'b1};
end
else begin
{ac, x} = {ac[31:0], x, 2'b0};
q = q << 1;
end
end
root = q[23:0];
end
endmodule

 Code testbench

module testbench1;
parameter SF = 2.0**-8.0;// Q16.8
reg [15:0]a,b;
reg clk;
wire [23:0]root;
sqrt intB(a,b,clk,root);
initial clk = 1;
always #5 clk = ~clk;
initial
begin
$monitor("\t%d:\tsqrt(%d^2 +%d^2) = %b (%f)",
$time,a,b, root, $itor(root*SF));
end
initial begin
clk =5;

Trang 36
a= 16'd5;4
b= 16'd4;
#40 a= 16'd12;
b= 16'd31;
#40 a= 16'd400;
b= 16'd42;
#40 a= 16'd4000;
b= 16'd1500;
#40 a= 16'd3200;
b= 16'd1400;
#40 a= 16'd0;
b= 16'd0;
#40 a= 16'd3400;
b= 16'd32;
#40 a= 16'd512;
b= 16'd147;
#40 a= 16'd1000;
b= 16'd2000;
#120 $finish;
end
endmodule

 Kết quả mô phỏng

Trang 37
Hình 1.3.1. Kết quả mô phỏng dạng sóng

Trang 38
Hình 1.3.2. Kết quả trên phần mềm matlab

Nhận xét : Kết quả thu được trên ModelSim có kết quả nhỏ hơn khi dùng phần mềm
Matlab do đây là thuật toán tính căn từng chữ số, thiết kế chỉ lấy 8 bit sau dấu phẩy làm đồ
chính xác chưa cao. Cách khắc phục tăng số bit sau dấu phẩy để tăng độ chính xác.

1.3.4. Đánh giá tài nguyên phần cứng khi thực thi trên FPGA Cyclone

II EP2C35F672C6
Hình 1.3.3. Kết quả đánh giá tài nguyên phần cứng

Trang 39
1.4. Bài 4:
1.4.1. Giới thiệu:
1.4.1.1. Mục tiêu:
Cho 2 số M và N, mỗi số 8-bit không dấu. Thực hiện phép toán cộng: M +
N bằng 2 cách:

- Cách 1: cộng nối tiếp từng bit


- Cách 2: cộng song song (nhiều bit cùng lúc)

a. Viết code Verilog mô tả 2 cách trên. Sử dụng phần mềm mô phỏng kiểm
tra chức năng hệ thống (chụp lại hình kết quả mô phỏng).

b. So sánh tài nguyên phần cứng của 2 cách trên khi thực thi trên.

Trong bài này ta chủ yếu sử dụng bộ cộng toàn phần Fulladder.

Hình 1.4.1. Sơ đồ bộ cộng toàn phần (Full Adder)

1.4.1.2. Giới thiệu giải thuật cộng nối tiếp từng bit:
Ta sử dụng bộ cộng toàn phần Fulladder, sử dụng 32 bộ nối tiếp với nhau để
cộng.

Trang 40
Ban đầu ngõ vào Cin của bộ Fulladder đầu tiên, ta cho giá trị bằng 0 (1’d0),
sau đó ngõ ra Cout của nó sẽ là Cin của bộ Fulladder tiếp theo. Thực hiện lần lượt
cho 32 bộ cộng fulladder, ta sẽ ra kết quả sau khi cộng.

Hình 1.4.2. Sơ đồ tổng quan cộng 2 số nối tiếp

1.4.1.3. Giới thiệu giải thuật cộng song song bit:


Khi ta cộng song song nhiều bit (ví dụ là 4 bit) thì ta cần xét giá trị Cout theo
một kiểu khác, khi cộng 4 bit với nhau mà không bị tràn bit thì ta có thể xem

Cout mới bằng Cin.

Cộng song song nhiều bit ta cần thêm các module hỗ trợ sau:

Trang 41
- Module xét bit dư C:

Hình 1.4.3. Sơ đồ module xét bit dư

Ta xét lần lượt từng cặp bit của 2 ngõ vào với nhau và thực hiện phép
XOR, sau đó AND tất cả kết quả phép XOR lại. Nếu 2 ngõ vào cộng lại
mà bị tràn bit, thì ngõ ra của module này sẽ bằng 1 và ngược lại.
- Module mux 2 to 1:

Hình 1.4.4. Sơ đồ module mux 2 to 1

Trang 42
Khi ngõ vào sel=1 thì sẽ cho ngõ vào in1 ra ngõ ra out, sel=0 thì cho
ngõ vào in0 ra ngõ ra out.
- Module cộng 4-bit song song:

Hình 1.4.5. Sơ đồ module cộng 4-bit song song

Ta ghép 3 module Fulladder, xét bit dư và mux lại với nhau để tạo
thành module cộng 4-bit song song.
- Module bộ công 8-bit song song:

1.4.2. Mô phỏng kết quả - Đánh giá tài nguyên:


 Bộ cộng nối tiếp:
- Kết quả mô phỏng:

Hình 1.4.6. Kết quả mô phỏng dạng sóng bộ cộng nối tiếp 32 bit

Trang 43
- Kết quả tổng hợp phần cứng:

Hình 1.4.7. Mô tả phần cứng bộ cộng nối tiếp trên Cyclone IV GX

Trang 44
Hình 1.4.8. Thời gian thực hiện với bộ cộng nối tiếp trên Cyclone IV GX

 Bộ cộng song song:


- Kết quả mô phỏng:

Hình 1.4.9. Kết quả mô phỏng dạng sóng bộ cộng song song 32 bit

- Kết quả tổng hợp phần cứng:

Trang 45
Hình 1.4.10. Mô tả phần cứng bộ cộng song song trên Cyclone IV GX

Trang 46
Hình 1.4.11. Thời gian thực hiện với bộ cộng song song trên Cyclone IV GX

Nhận xét:

- Tổng số phần tử logic của bộ cộng nối tiếp 32 bit lớn hơn không nhiều so với
bộ cộng song song 32 bit (67 so với 51)
- Số pins của hai bộ cộng là bằng nhau.
- Thời gian thực hiện bằng bộ cộng nối tiếp là lớn hơn khi thực hiện bộ cộng
song song.

Trang 47
1.4.3. Code design – code testbench:
a. Code design:
 Bộ cộng nối tiếp:
module cong32(a,b,s,c);
input [31:0]a,b;
output [31:0]s;
output c;
wire [31:1] V;
fulladder
fa0(.S(s[0]),.Cout(V[1]),.A(a[0]),.B(b[0]),.Cin(1'd0))
;
fulladder
fa1(.S(s[1]),.Cout(V[2]),.A(a[1]),.B(b[1]),.Cin(V[1]))
;
fulladder
fa2(.S(s[2]),.Cout(V[3]),.A(a[2]),.B(b[2]),.Cin(V[2]))
;
fulladder
fa3(.S(s[3]),.Cout(V[4]),.A(a[3]),.B(b[3]),.Cin(V[3]))
;
fulladder
fa4(.S(s[4]),.Cout(V[5]),.A(a[4]),.B(b[4]),.Cin(V[4]))
;
fulladder
fa5(.S(s[5]),.Cout(V[6]),.A(a[5]),.B(b[5]),.Cin(V[5]))
;
fulladder
fa6(.S(s[6]),.Cout(V[7]),.A(a[6]),.B(b[6]),.Cin(V[6]))
;

Trang 48
fulladder
fa7(.S(s[7]),.Cout(V[8]),.A(a[7]),.B(b[7]),.Cin(V[7]))
;

fulladder
fa8(.S(s[8]),.Cout(V[9]),.A(a[8]),.B(b[8]),.Cin(V[8]))
;
fulladder
fa9(.S(s[9]),.Cout(V[10]),.A(a[9]),.B(b[9]),.Cin(V[9])
);
fulladder
fa10(.S(s[10]),.Cout(V[11]),.A(a[10]),.B(b[10]),.Cin(V
[10]));
fulladder
fa11(.S(s[11]),.Cout(V[12]),.A(a[11]),.B(b[11]),.Cin(V
[11]));
fulladder
fa12(.S(s[12]),.Cout(V[13]),.A(a[12]),.B(b[12]),.Cin(V
[12]));
fulladder
fa13(.S(s[13]),.Cout(V[14]),.A(a[13]),.B(b[13]),.Cin(V
[13]));
fulladder
fa14(.S(s[14]),.Cout(V[15]),.A(a[14]),.B(b[14]),.Cin(V
[14]));
fulladder
fa15(.S(s[15]),.Cout(V[16]),.A(a[15]),.B(b[15]),.Cin(V
[15]));

Trang 49
fulladder
fa16(.S(s[16]),.Cout(V[17]),.A(a[16]),.B(b[16]),.Cin(V
[16]));
fulladder
fa17(.S(s[17]),.Cout(V[18]),.A(a[17]),.B(b[17]),.Cin(V
[17]));
fulladder
fa18(.S(s[18]),.Cout(V[19]),.A(a[18]),.B(b[18]),.Cin(V
[18]));
fulladder
fa19(.S(s[19]),.Cout(V[20]),.A(a[19]),.B(b[19]),.Cin(V
[19]));
fulladder
fa20(.S(s[20]),.Cout(V[21]),.A(a[20]),.B(b[20]),.Cin(V
[20]));
fulladder
fa21(.S(s[21]),.Cout(V[22]),.A(a[21]),.B(b[21]),.Cin(V
[21]));
fulladder
fa22(.S(s[22]),.Cout(V[23]),.A(a[22]),.B(b[22]),.Cin(V
[22]));
fulladder
fa23(.S(s[23]),.Cout(V[24]),.A(a[23]),.B(b[23]),.Cin(V
[23]));

fulladder
fa24(.S(s[24]),.Cout(V[25]),.A(a[24]),.B(b[24]),.Cin(V
[24]));
fulladder
fa25(.S(s[25]),.Cout(V[26]),.A(a[25]),.B(b[25]),.Cin(V
[25]));

Trang 50
fulladder
fa26(.S(s[26]),.Cout(V[27]),.A(a[26]),.B(b[26]),.Cin(V
[26]));
fulladder
fa27(.S(s[27]),.Cout(V[28]),.A(a[27]),.B(b[27]),.Cin(V
[27]));
fulladder
fa28(.S(s[28]),.Cout(V[29]),.A(a[28]),.B(b[28]),.Cin(V
[28]));
fulladder
fa29(.S(s[29]),.Cout(V[30]),.A(a[29]),.B(b[29]),.Cin(V
[29]));
fulladder
fa30(.S(s[30]),.Cout(V[31]),.A(a[30]),.B(b[30]),.Cin(V
[30]));
fulladder
fa31(.S(s[31]),.Cout(c),.A(a[31]),.B(b[31]),.Cin(V[31]
));

endmodule

module BoCongNT32bit;
reg [31:0] A,B;
wire Cout;
wire [31:0] result;
cong32 uut(A,B,result,Cout);
initial
begin
#50
A = 32'd1073741824; // 2^30
B = 32'd536870912; // 2^29

Trang 51
#50
$finish;
end
endmodule

module fulladder(S,Cout,A,B,Cin);
input A,B,Cin;
output S,Cout;
assign S = A^B^Cin;
assign Cout = (A&B) | (Cin&(A^B));
endmodule

 Bộ cộng song song:

module conggt2(A, B, S, C);


input [31:0] A,B;
output C;
output [31:0] S;
wire V;
adder_4bit
csa1(.S(S[3:0]),.C(V),.A(A[3:0]),.B(B[3:0]),.Cin(1'd0)
);
adder_4bit
csa2(.S(S[7:4]),.C(V),.A(A[7:4]),.B(B[7:4]),.Cin(1'd0)
);
adder_4bit
csa3(.S(S[11:8]),.C(V),.A(A[11:8]),.B(B[11:8]),.Cin(1'
d0));
adder_4bit
csa4(.S(S[15:12]),.C(V),.A(A[15:12]),.B(B[15:12]),.Cin
(1'd0));

Trang 52
adder_4bit
csa5(.S(S[19:16]),.C(V),.A(A[19:16]),.B(B[19:16]),.Cin
(1'd0));
adder_4bit
csa6(.S(S[23:20]),.C(V),.A(A[23:20]),.B(B[23:20]),.Cin
(1'd0));
adder_4bit
csa7(.S(S[27:24]),.C(V),.A(A[27:24]),.B(B[27:24]),.Cin
(1'd0));
adder_4bit
csa8(.S(S[31:28]),.C(C),.A(A[31:28]),.B(B[31:28]),.Cin
(V));
endmodule

module adder_4bit(S, C, A, B, Cin);


input [3:0] A,B;
input Cin;
output [3:0] S;
output C;
wire C0;
wire xet;
adder4bit
cong4bit(.S(S),.C(C0),.A(A),.B(B),.Cin(Cin));
xetbitdu xetdu(A,B,xet);
mux2to1 m0(.in0(C0),.in1(Cin),.sel(xet),.out(C));
endmodule

module xetbitdu(A,B,xet);
input [3:0] A,B;
wire [3:0] C;
output xet;

Trang 53
assign C= A^B;//C[i]=A[i] xor B[i]
assign xet= &C; //C[0]&C[1]&C[2]&C[3]
endmodule
//--------------FA 4 bit---------------------//
module adder4bit(S, C, A, B, Cin);
input [3:0] A,B;
input Cin;
wire C1,C2,C3;
output [3:0] S;
output C;
fulladder
fa0(.S(S[0]),.C(C1),.A(A[0]),.B(B[0]),.Cin(Cin));
fulladder
fa1(.S(S[1]),.C(C2),.A(A[1]),.B(B[1]),.Cin(C1));
fulladder
fa2(.S(S[2]),.C(C3),.A(A[2]),.B(B[2]),.Cin(C2));
fulladder
fa3(.S(S[3]),.C(C),.A(A[3]),.B(B[3]),.Cin(C3));
endmodule
module fulladder (S, C, A, B, Cin);
input A, B,Cin;
output C, S;
assign S = A ^ B ^ Cin;
assign C = A & B | ( Cin & ( A ^ B));
endmodule
//---------------MUX 2--------------------//
module mux2to1( in0,in1,sel,out);
input in0,in1;
input sel;
output out;
assign out=(sel)?in1:in0;

Trang 54
endmodule

module BoCongSS32bit;
reg [31:0] A,B;
wire Cout;
wire [31:0] result;
conggt2 uut(A,B,result,Cout);

initial
begin
#50
A = 32'd1073741824; // 2^30
B = 32'd536870912; // 2^29
#50

$finish;
end
endmodule

b. Code Testbench
 Bộ cộng nối tiếp:
module t_cong;
reg [31:0]in1,in2;
wire [31:0]sum;
wire cout;
cong c32b_1(in1,in2,sum,cout);
initial begin
#0
in1 = 32'b0100_0000_0000_0000_0000_0000_0000_0000;
in2 = 32'b0010_0000_0000_0000_0000_0000_0000_0000;
#100;

Trang 55
end
endmodule

 Bộ cộng song song:

module t_conggt2;
reg [31:0]in1,in2;
wire [31:0]sum;
wire cout;
conggt2 c32b_1(in1,in2,sum,cout);
initial begin
#0
in1 = 32'b0100_0000_0000_0000_0000_0000_0000_0000;
in2 = 32'b0010_0000_0000_0000_0000_0000_0000_0000;
#100;
end
endmodule

Trang 56
1.5. Bài 5:
1.5.1. Đề bài:
Cho 2 số M và N, mỗi số 8 bit biểu diễn theo số có dấu bù 2. Viết code Verilog thực
hiện phép toán nhân: M * N bằng cách sử dụng giải thuật Modified Booth Multiplier.

1. Sử dụng phần mềm mô phỏng kiểm tra chức năng hệ thống (chụp lại hình kết quả
mô phỏng).

2. Đánh giá tài nguyên phần cứng khi thực thi trên FPGA Cyclone II
EP2C35F672C6.

1.5.2. Cơ sở lý thuyết:
Giải thuật nhân Booth sẽ so sánh 2 bit một lúc bằng cách dịch phải số hạng nhân để
tính toán, do đó số lần lặp lại đúng bằng với số bit của số hạng nhân. Để giảm thiểu một
nửa số lần lặp, thuật toán nhân Modified Booth ra đời, hay còn gọi là Radix-4.

Ý tưởng cơ bản là thay vì dịch phải và cộng mọi bit của số hạng nhân với 1 hoặc 0,
thì ta sẽ so sánh 3 bit một lúc với kỹ thuật chồng chéo. Việc nhóm các bit sẽ bắt đầu từ
LSB và khối đầu tiên chỉ sử dụng hai bit của số hạng nhân và giả định 0 cho bit thứ ba như
hình sau:

Hoạt động chức năng của bộ mã hóa Radix-4 bao gồm tám trạng thái khác nhau, và
trong mỗi trạng thái này, chúng ta đều có thể thu được kết quả của phép nhân của số bị
nhân với 0, 1 và 2. Điều đó được thể hiện trong bảng sau:

Trang 57
Multiplier Bits Block Recoded 1-bit pair 2 Bits Booth

i+1 i i–1 i+1 i Multiplier Value Partial Product

0 0 0 0 0 0 M0

0 0 1 0 1 1 M1

0 1 0 1 -1 1 M1

0 1 1 1 0 2 M2

1 0 0 -1 0 -2 M-2

1 0 1 -1 1 -1 M-1

1 1 0 0 -1 -1 M-1

1 1 1 0 0 0 M0

Trang 58
 Lưu đồ giải thuật:

Start

Q0

N-1  0

M: Multiplicand; N:
Mutiplier

000 QQ+0
N1N0N-1?
111
False
001 QQ+M
N1N0N-1?
010
False
011 QQ+
N1N0N-1?
2M
False

N1N0N-1? 100 QQ–


2M
False

101 QQ–M
N1N0N-1?
110

Arithmetic shift right Q, N,


N-1

Arithmetic shift right Q, N,


N-1

False
Count =

True

End
Hình 1.5.1. Lưu đồ giải thuật

Trang 59
 Giải thuật:

1. Khởi tạo giá trị N-1 = 0, i = n/2 (với n là số bit lớn nhất của số bị nhân và số
nhân).
2. Tính các giá trị M, 2M, -2M, -M với các giá trị âm sẽ là các giá trị bù 2.
3. Kiểm tra 3 bit N1N0N-1 để cộng giá trị tương ứng vào kết quả đầu ra Q.
 000 hoặc 111: Q = Q + 0.
 001 hoặc 010: Q = Q + M.
 011: Q = Q + 2M.
 100: Q = Q – 2M.
 101 hoặc 110: Q = Q – M.
4. Dịch phải các giá trị Q, [N, N-1] hai lần.
5. Giảm số lần lặp i = i – 1.
6. Kiểm tra i. Nếu i  0 thì quay lại và thực hiện bước 3.
7. In ra kết quả.

1.5.3. Code thực hiện và kết quả mô phỏng:


Code thực hiện:

module mul_control(m, n, p);

input [7:0] m, n;

output [14:0] p;

reg [8:0] md, m0, m1, m2, m3, m4;

reg [8:0] n0;

reg [14:0] p0, p1;

integer i, j;

always @(m or n)

begin

m0 = 9'd0; //0

Trang 60
m1 = {m[7], m}; //m

m2 = {m, 1'b0}; //2m

m3 = ~(m2) + 9'd1; //-2m

m4 = ~(m1) + 9'd1; //-m

n0 = {n, 1'b0};

p0 = 15'd0;

for (i = 0; i < 4; i = i + 1)

begin

case (n0[2:0])

3'b000, 3'b111: md = m0;

3'b001, 3'b010: md = m1;

3'b011: md = m2;

3'b100: md = m3;

3'b101, 3'b110: md = m4;

endcase

p1[8:0] = md;

p1[14:9]=(md[8])?6'b111111:6'b000000;

for (j = 0; j < i; j = j + 1)

begin

p1[14:2] = p1[12:0];

p1[1:0] = 2'b00;

end

p0 = p0 + p1;

n0[6:0] = n0[8:2];

Trang 61
n0[8:7] = 2'b00;

end

end

assign p = p0;

endmodule

 Code testbench:

module mul_test;

reg [7:0] m, n;

wire [14:0] p;

mul_control mul(m, n, p);

initial begin

m = 8'b10110111;

n = 8'b01011010;

#100

m = 8'b11110101;

n = 8'b00011011;

#100

m = 8'b10000001;

n = 8'b01111111;

#100

m = 8'b10000010;

n = 8'b00000000;

#100

Trang 62
m = 8'b11111111;

n = 8'b10000001;

#100

m = 8'b10011100;

n = 8'b11110000;

#100

m = 8'b00001111;

n = 8'b10101010;

#100

m = 8'b01010101;

n = 8'b00110011;

#100

m = 8'b11001100;

n = 8'b00101101;

#100

m = 8'b10010110;

n = 8'b11101100;

end

endmodule

 Kết quả mô phỏng:

Hình 1.5.2. Kết quả mô phỏng trên ModelSim

Trang 63
Nhận xét: Kết quả của thuật toán sau khi mô phỏng trên ModelSim đúng với tính
toán thực tế.

1.5.4. Kết quả đánh giá tài nguyên phần cứng khi thực thi trên FPGA
Cyclone IV EP4CGX15BF14C6:

Hình 1.5.3. Kết quả đánh giá tài nguyên phần cứng

Trang 64
2. Phần riêng nhóm 10:
2.1. Bài 1:
2.1.1. Đề bài:
Cho trước hệ thống có sơ đồ DFG như hình bên dưới. Thời gian tính toán của các
nút được cho bởi số trong dấu ngoặc () (ví dụ : (2) = 2 u.t.)

1.Tính giới hạn lặp 𝑇∞ bằng quan sát và giải thuật LPM (Sinh viên tự quy ước cách đánh
số thứ tự các phần tử delay).
2.Viết code Matlab kiểm tra lại kết quả thực hiện giải thuật LPM ở câu 1.
3.Chỉ ra (các) đường tới hạn và thời gian tính toán tới hạn Tcritical?
4.Tái định thì hệ thống trên sao cho đường tới hạn mới T’critical = 𝑇∞ (ở câu 1).
5.Viết code Matlab thực hiện giải thuật Bellman-Ford kiểm chứng lại giá trị tái định thì
các nút

Trang 65
2.1.2. Câu 1: Tính giới hạn lặp 𝑇∞ bằng quan sát và giải thuật LPM
(Sinh viên tự quy ước cách đánh số thứ tự các phần tử delay).
a. Phương pháp quan sát:
Vòng thứ Các nút trong vòng Giới hạn vòng (u.t.)
1 A-B-D-A (10+2+6)/3 = 6
2 A-B-C-D-A (10+2+4+6)/4 = 5.5
3 A-E-C-D-A (10+8+4+6)/4 = 7
4 B-D (2+6)/1 = 8
5 B-C-D (2+4+6)/2 = 6

Như vậy giới hạn lặp T = max(các giới hạn vòng) = 8 u.t.

b. Giải thuật LPM

Hình 2.1.1. Tách 3D thành 3 Delay

Xây dựng giản đồ delay Gd từ DFG của các vòng hồi tiếp tại các nút A, B, C, D, E

D1 D3: D1 – A – B – D – D3 = 18

D1 D4: D1 – A – B – D – D4 = 18

Trang 66
D1 D5: D1 – A – B – C – D5 = 16

D2  D1: 0

D3  D2: 0

D4  D3: D4 – B – D – D3 =8

D4  D4: D4 – B – D – D4 =8

D4  D5: D4 – B – C – D5 =6

D5  D3: D5 – D – D3 =6

D5  D4: D5 – D – D4 =6

 Ta có:

−1 −1 18 18 16
0 −1 −1 −1 −1
L(1) = −1 0 −1 −1 −1
−1 −1 8 8 6
[−1 −1 6 6 −1]

 Xây dựng các ma trận tiếp theo L(2) và L(3)

−1 18 26 26 24 18 26 34 34 32
−1 −1 18 18 16 −1 18 26 26 24
L(2) = 0 −1 −1 −1 −1 L(3) = −1 −1 18 18 16
−1 8 16 16 14 8 16 24 24 22
[−1 6 14 14 12 ] [ 6 14 22 22 20]

 Tính giới hạn lặp


8 16 12 18 18 18 24 20
T = max( , , , , , , , ) = 8 u.t.
1 2 2 3 3 3 3 3

Trang 67
2.1.3. Câu 2: Viết code Matlab kiểm tra lại kết quả thực hiện giải thuật
LPM ở câu 1.

% Nhập ma trận L1
disp('ma tran L1');
L1=[-1 -1 18 18 16;
0 -1 -1 -1 -1;
-1 0 -1 -1 -1;
-1 -1 8 8 6;
-1 -1 6 6 -1];
disp(L1)
% Chuyển -1 thành âm vô cùng -inf
for i=1:5
for j=1:5
if L1(i,j)==-1
L1(i,j)=-inf;
end
end
end

% Tính ma trận L2
for m=1:5
for i=1:5
for j=1:5
A(1,j)=L1(m,j)+L1(j,i);
end
L2(m,i)= max(A);
A=[0 0 0 0 0];
end

Trang 68
end
% Đưa -inf về -1
for i=1:5
for j=1:5
if L2(i,j)==-inf
L2(i,j)=-1;
end
end
end
disp('ma tran L2')
disp(L2)

% Tính ma trận L3
for m=1:5
for i=1:5
for j=1:5
A(1,j)=L1(m,j)+L2(j,i);
end
L3(m,i)= max(A);
A=[0 0 0 0 0];
end
end
% Đưa –inf về -1
for i=1:5
for j=1:5
if L3(i,j)==-inf
L3(i,j)=-1;
end

Trang 69
end
end
disp('ma tran L3')
disp(L3)

% tìm giới hạn lặp


for i=1:5
M(1,i)=L1(i,i)/1;
M(2,i)=L2(i,i)/2;
M(3,i)=L3(i,i)/3;
end
m=max(M);
T=max(m);
disp('gioi han lap T_inf =')
disp(T)

Trang 70
 Kết quả:

Hình 2.1.2. Kết quả thực hiện tính toán với Matlab các ma trận L(2), L(3)

 Nhận xét:

- Các kết quả thực hiện ở câu 1 đúng với kết quả kiểm tra lại ở câu 2 (bằng
Matlab)
- Như vậy kết quả tính giới hạn lặp ở câu 1 là chính xác

Trang 71
2.1.4. Câu 3: Chỉ ra (các) đường tới hạn và thời gian tính toán tới hạn
Tcritical?
Đường tới hạn đi qua các nút: A – E – C

Thời gian tính toán tới hạn Tcritical = 10 + 8 + 4 = 22 u.t.

2.1.5. Câu 4: Tái định thì hệ thống trên sao cho đường tới hạn mới
T’critical = 10 u.t.

Hình 2.1.3. Dùng 2 nhát cắt để thực hiện tái định thì

Trang 72
Hình 2.1.4. Chia các phía đã cắt thành 3 Group

Từ G1 G2

Ta có: min {𝐰(𝐞)} ≤ 𝑘 ≤ min {𝐰(𝐞)}


𝐺1→𝐺2 𝐺2→𝐺1

Mà : min {𝐰(𝐞)} = min {0,0} = 0


𝐺1→𝐺2

min {𝐰(𝐞)} = min {3} = 3


𝐺2→𝐺1

 0≤k≤3
 k = 1,2 hoặc 3
 Chọn k =1 (để tối thiểu số delay thêm vào)
Vậy mỗi cạnh từ G1 sang G2 phải thêm 1 delay và mỗi cạnh từ G2 sang
G1 phải bỏ đi 1 delay

Từ G2 G3

Ta có: min {𝐰(𝐞)} ≤ 𝑘 ≤ min {𝐰(𝐞)}


𝐺2→𝐺3 𝐺3→𝐺2

Trang 73
Mà : min {𝐰(𝐞)} = min {0,0} = 0
𝐺2→𝐺3

min {𝐰(𝐞)} = min {1} = 1


𝐺3→𝐺2

 0≤k≤
 Chọn k =1
Vậy mỗi cạnh từ G2 sang G3 phải thêm 1 delay và mỗi cạnh từ G3 sang
G2 phải bỏ đi 1 delay

Hình 2.1.5. Sơ đồ sau khi thực hiện tái định thì

 Các đường tới hạn và thời gian tính toán tới hạn Tcritical:
Đường 1: Đường tới hạn đi qua các nút: A có Tcritical = 10 u.t
Đường 2: Đường tới hạn đi qua các nút: C-D có Tcritical = 4 + 6 = 10 u.t

Trang 74
2.1.6. Câu 5: Viết code Matlab thực hiện giải thuật Bellman-Ford kiểm
chứng lại giá trị tái định thì các nút
Ta có :

Hình 2.1.6. Sơ đồ G’

 Dùng giải thuật Floyd-Warshall tìm đường đi ngắn nhất

R(1)(U, V)

A B C D E
A - -10 - - -10
B - - -2 -2 -
C - - - 46 -
D 144 44 - - -
E - - -8 - -
R(2)(U, V)

A B C D E
A - -10 -12 -12 -10
B 142 42 -2 -2 -

Trang 75
C 190 90 - 46 -
D 144 44 42 42 134
E - - -8 38 -

R(3)(U, V)

A B C D E
A 132 -10 -12 -12 -10
B 142 42 -2 -2 132
C 190 90 88 46 180
D 144 44 42 42 134
E 182 82 -8 38 -

R(4)(U, V) = S’(U,V)

A B C D E
A 132 -10 -12 -12 -10
B 142 42 -2 -2 132
C 190 90 88 46 180
D 144 44 42 42 134
E 182 82 -8 38 172

 Đoạn chương trình tính các ma trận W (U,V) và D(U,V)

S=[ 132 -10 -12 -12 -10;


142 42 -2 -2 132;
190 90 88 46 180;
144 44 42 42 134;

Trang 76
182 82 -8 38 172;
];
disp('ma tran S')
disp(S)
M=50;
for i=1:5
for j=1:5
W(i,j)=ceil((S(i,j)/M));
end
end
for i=1:5
W(i,i)=0;
end
disp('ma tran W')
disp(W)
t=[10 2 4 6 8];

for i=1:5
for j=1:5
D(i,j)=M*W(i,j)- S(i,j) +t(1,j);
end
end
for i=1:5
D(i,i)=t(1,i);
end
disp('ma tran D')
disp(D)

Trang 77
 Kết quả:

Hình 2.1.7. Kết quả thực hiện tính toán Matlab các ma trận W và D

 Dựa vào ma trận W và D, ta có các phương trình sau:

r(U) - r(V) ≤ W(U,V) – 1


r(U) - r(V) ≤ w(e)
(khi D(U,V) > 10 u.t.)

Trang 78
r(A)- r(B) ≤ -1
r(A)- r(C) ≤ -1
r(A)- r(D) ≤ -1
r(A)- r(E) ≤ -1
r(B)- r(A) ≤ 2
r(B)- r(E) ≤ 2
r(B)- r(C) ≤ 0 r(C)- r(A) ≤ 3
r(B)- r(D) ≤ 0 r(C)- r(B) ≤ 1
r(C)- r(D) ≤ 1 r(C)- r(E) ≤ 3
r(D)- r(B) ≤ 1 r(D)- r(A) ≤ 2
r(D)- r(C) ≤ 0
r(D)- r(E) ≤ 2
r(E)- r(A) ≤ 3
r(E)- r(B) ≤ 1
r(E)- r(C) ≤ -1
r(E)- r(D) ≤ 0
 Vẽ thêm nút F để thực hiện giải thuật Bellman-Ford:

Trang 79
Hình 2.1.8. Sơ đồ chi phí các đường giữa các nút

 Thành lập bảng chi phí các đường đi:

A B C D E
A - 2 3 2 3
B -1 - 1 1 1
C -1 0 - 0 -1
D -1 0 1 - 0
E -1 2 3 2 -

 Đoạn chương trình thực hiện giải thuật Bellman-Ford:

W=[ inf 2 3 2 3;
-1 inf 1 1 1;
-1 0 inf 0 -1;

Trang 80
-1 0 1 inf 0;
-1 2 3 2 inf;
]

r0=[0 0 0 0 0]

for i=1:5
for j=1:5

A(1,j)=r0(1,j)+ W(j,i);

if min(A)< r0(1,i)
r1(1,i)=min(A);
else
r1(1,i)=r0(1,i);
end

end
A=[0 0 0 0 0];

end
r1

for i=1:5
for j=1:5

A(1,j)=r1(1,j)+ W(j,i);

Trang 81
if min(A)< r0(1,i)
r2(1,i)=min(A);
else
r2(1,i)=r1(1,i);
end

end
A=[0 0 0 0 0];

end
r2
for i=1:5
for j=1:5

A(1,j)=r2(1,j)+ W(j,i);

if min(A)< r0(1,i)
r3(1,i)=min(A);
else
r3(1,i)=r2(1,i);
end

end
A=[0 0 0 0 0];
end
r3

Trang 82
 Kết quả:

Hình 2.1.9. Kết quả thực hiện tính toán bằng Matlab r(1)(V), r(2)(V), r(3)(V)

Với r0 tương ứng r(0)(V), r1 tương ứng r(1)(V), r2 tương ứng r(2)(V), r3 tương ứng r(3)(V)

Ta thấy r(2)(V) = r(3)(V) = (-2, 0, 0, 0, -1)

Trang 83
Ta thấy nút A và nút E đang sớm lần lượt là 2 và 1 chu kì xung clock, vậy cần thực hiện
tái định thì lại cho 2 nút trên.

Hình 2.1.10. Các nhát cắt theo giải thuật Bellman-Ford

Thực hiện tái định thì cho nút A, mỗi cạnh đi ra nút A thêm vào 2 Delay và mỗi cạnh đi
vào nút A bỏ đi 2 Delay. Ta được:

Hình 2.1.11. Tái định thì nút A

Tiếp tục, thực hiện tái định thì cho nút E, mỗi cạnh đi ra nút E thêm vào 1 Delay và mỗi
cạnh đi vào nút E bỏ đi 1 Delay. Ta được:

Trang 84
Hình 2.1.12. Tái định thì nút E

 Các đường tới hạn và thời gian tính toán tới hạn Tcritical:
Đường 1: Đường tới hạn đi qua các nút: A có Tcritical = 10 u.t

Nhận xét:

- Kết quả tái định thì ở câu 4 có khác so với kết quả dùng Bellman-Ford.

Hình 2.1.13. Tái định thì câu 4 (trái) và tái định thì dùng Bellman-Ford (phải)

- Số Delay ở hai trường hợp bằng nhau.


- Số đường tới hạn ở câu 4 là 2 đường so với 1 đường khi thực hiện giải thuật
Bellman-Ford (Bellman-Ford tối ưu hơn)

Trang 85
2.2. Bài 2:
Hãy trải (Unfold) hệ thống DFG bên dưới với hệ số trải J = 3.

Từ sơ đồ DFG gốc, các cạnh có phần tử delay là:

D 2D 3D 7D
A→B E→ D E→ B C→ E

Ta có bảng

i w (i+w)%J ( i + w ) / J

0 1 1 0

1 1 2 0

2 1 0 1

0 2 2 0

1 2 0 1

2 2 1 1

0 3 0 1

1 3 1 1

2 3 2 1

0 7 1 2

1 7 2 2

2 7 0 3

Trang 86
Hệ thống DFG sau khi trải ra với hệ số bằng J = 3

Hình 2.2.1.Hệ thống sau khi trải ra

Trang 87

You might also like