Tải bản đầy đủ (.pdf) (52 trang)

(Tiểu luận) báo cáo xử lý tín hiệu số với fpga bài tập lớn 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

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 (2.3 MB, 52 trang )

ĐẠ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 Hà Nhất Phương

1813622

Nguyễn Bùi Thanh Sơn

1813849

Nguyễn Minh Thành

1814021

Trần Văn Thành


1814035

Võ Hồng Thịnh

1810552

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

h


Danh sách thành viên:
STT

Họ và Tên

MSSV

Email

1

Nguyễn Hà Nhất Phương

1813622



2


Nguyễn Bùi Thanh Sơn

1813849



3

Nguyễn Minh Thành

1814021



4

Trần Văn Thành

1814035



5

Võ Hoàng Thịnh

1810552




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

Họ và Tên

Nhiệm vụ cụ thể

1

Nguyễn Hà Nhất Phương

Phần chung: Bài 1

2

Nguyễn Bùi Thanh Sơn

Phần chung: Bài 5

3

Nguyễn Minh Thành

Phần chung: Bài 4

4

Trần Văn Thành

Phần chung: Bài 3


5

Võ Hồng Thịnh

Phần chung: Bài 2

Phần bài tập riêng cả nhóm làm chung qua các buổi google meet.

Đại học Bách khoa TPHCM

Trang 1

h


MỤC LỤC
NỘI DUNG ................................................................................................................................ 4
1

Phần chung cho tất cả các nhóm ...................................................................................... 4
1.1

Bài 1 ............................................................................................................................. 4

1.1.1

Đề bài .................................................................................................................... 4

1.1.2


Giải thuật thứ nhất ................................................................................................ 5

1.1.3

Giải thuật thứ hai ................................................................................................ 10

1.2

Bài 2 ........................................................................................................................... 16

1.2.1

Đề bài .................................................................................................................. 16

1.2.2

Cơ sở lý thuyết .................................................................................................... 16

1.2.3

Giải thuật tính tốn ............................................................................................. 18

1.2.4

Code mơ phỏng................................................................................................... 19

1.2.5

Kết quả mơ phỏng .............................................................................................. 21


1.2.6

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

EP2C35F672C6. ............................................................................................................... 23
1.3

Bài 3 ........................................................................................................................... 24

1.3.1

Đề bài .................................................................................................................. 24

1.3.2

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

1.3.3

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

1.3.4

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

EP2C35F672C6. ............................................................................................................... 30
1.4

Bài 4 ........................................................................................................................... 31


1.4.1

Đề bài .................................................................................................................. 31

1.4.2

Cơ sở lý thuyết .................................................................................................... 31

1.4.3

Chi tiết thiết kế ................................................................................................... 32

1.4.4

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

1.4.5

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

EP2C35F672C6 ................................................................................................................ 38
Đại học Bách khoa TPHCM

Trang 2

h


1.5


Bài 5 ........................................................................................................................... 40

1.5.1

Đề bài .................................................................................................................. 40

1.5.2

Cơ sở lý thuyết .................................................................................................... 40

1.5.3

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

1.5.4

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

EP2C35F672C6 ................................................................................................................ 45
2

Phần riêng cho từng nhóm ............................................................................................. 46

Đại học Bách khoa TPHCM

Trang 3

h



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. Bộ min_finder

Lưu ý:


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



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 kiểm
tra chức năng hệ thống (chụp lại hình kết quả mơ phỏng).
3. Đánh giá tài ngun phần cứng khi thực thi 2 giải thuật đề xuất trên FPGA Cyclone II
EP2C35F672C6.

Đại học Bách khoa TPHCM

Trang 4

h


1.1.2

Giải thuật thứ nhất

Hình 1.2. Sơ đồ giải thuật thứ nhất bộ min_finder

Đầ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 đó.
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.

Đại học Bách khoa TPHCM

Trang 5

h




Code thực hiện:

module
min_finder(rst,clk,in0,in1,in2,in3,in4,in5,in6,in7,in8,in9,min1,min2,index_
min1,nflag);
localparam n = 10;
input rst,clk;
input[3:0] in0,in1,in2,in3,in4,in5,in6,in7,in8,in9;
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,temp;
reg[7:0] reg_min1;
reg[3:0] reg_min2;
wire cp1,cp2,flag_0;

reg[3:0] count;
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};
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;
reg_in6 = reg_in7;
reg_in7 = reg_in8;
reg_in8 = reg_in9;
reg_in9 = temp;
end

end
always @(posedge clk) begin
if(rst) begin
count = 4'b1001;
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

Đại học Bách khoa TPHCM

Trang 6

h


always @(negedge clk) begin
if (rst) begin
reg_min1 = {4'b0000,in0};
reg_min2 = in1;
end
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 in1input[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;
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;
reg rst,clk;
reg[3:0] in0,in1,in2,in3,in4,in5,in6,in7,in8,in9;

Đại học Bách khoa TPHCM

Trang 7

h


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,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; 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; 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; rst = 7; #2; rst = 0; #100
$finish;
end
initial begin
forever begin
clk = 0; #1;
clk = 1; #1;
end
end
initial begin
$dumpfile("waveform.vcd");
$dumpvars(1);
end
endmodule



Mơ phỏng dạng sóng:


Ở đây em sử dụng website EDA Playground (tool Icarus Verilog 0.9.7) để mơ phỏng dạng
sóng.

Hình 1.3. Mơ phỏng dạng sóng giải thuật thứ nhất cho bộ min_finder

Đại học Bách khoa TPHCM

Trang 8

h


Hình 1.4. Mơ phỏng dạng sóng giải thuật thứ nhất cho bộ min_finder



Đánh giá phần cứng:

Hình 1.5. Đánh giá phần cứng giải thuật thứ nhất cho bộ min_finder

Ở đây, ta thấy thiết kế sử dụng 122 logic elements (chiếm chưa đến 1% số logic elements
của thiết bị), bao gồm: 109 hàm tổ hợp và 101 thanh ghi. Ngoài ra tổng số pins là 55 (chiếm
12% số pins của thiết bị).

Đại học Bách khoa TPHCM

Trang 9

h



1.1.3

Giải thuật thứ hai

Hình 1.6. Sơ đồ giải thuật thứ hai bộ min_finder

Đầu tiên, ta lần lượt so sánh min_1 và giá trị min_2 với giá trị của các port từ 1 đến 9. Khi
đó sẽ có 2 trường hợp xảy ra:
Thứ nhất, min_1 lớn hơn giá trị của port thứ i. Khi đó, ta thay min_1 bởi giá trị của port thứ
i và thay min_2 bởi min_1.
Đại học Bách khoa TPHCM

Trang 10

h


Thứ hai, min_1 bé hơn giá trị của port thứ 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ữ ngun min_2.
Sau đó, với giá trị đã có của min_1, ta tìm từ port 0 đến port 9 sao cho giá trị của port đó
bằng min_1, thì số thứ tự của port đầu tiên tìm được chính là index_min1.


Code thực hiện:

module
min_finder(rst,clk,in0,in1,in2,in3,in4,in5,in6,in7,in8,in9,min1,min2,index_
min1,nflag);

localparam n = 10;
input rst,clk;
input[3:0] in0,in1,in2,in3,in4,in5,in6,in7,in8,in9;
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,temp;
reg[7:0] reg_min1;
reg[3:0] reg_min2;
wire cp1,cp2,flag_0;
reg[3:0] count;
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};
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;
reg_in6 = reg_in7;
reg_in7 = reg_in8;
reg_in8 = reg_in9;
reg_in9 = temp;
end
end
always @(posedge clk) begin
if(rst) begin
count = 4'b1001;

Đại học Bách khoa TPHCM

Trang 11

h


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
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

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;
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;

Đại học Bách khoa TPHCM

Trang 12

h


assign node1 = ~(in0^in1);
assign eq = eq_i&node1;

assign ge = (node1&ge_i)|(in0&(~in1));
endmodule



Code testbench:

module testbench;
reg rst,clk;
reg[3:0] in0,in1,in2,in3,in4,in5,in6,in7,in8,in9;
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,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; 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; 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; rst = 7; #2; rst = 0; #100
$finish;
end
initial begin
forever begin
clk = 0; #1;
clk = 1; #1;

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



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

Ở đây em sử dụng website EDA Playground (tool Icarus Verilog 0.9.7) để mơ phỏng dạng
sóng.

Đại học Bách khoa TPHCM

Trang 13

h


Hình 1.7. Mơ phỏng dạng sóng giải thuật thứ hai cho bộ min_finder

Hình 1.8. Mơ phỏng dạng sóng giải thuật thứ hai cho bộ min_finder



Đánh giá phần cứng:


Hình 1.9. Đánh giá phần cứng giải thuật thứ hai cho bộ min_finder

Đại học Bách khoa TPHCM

Trang 14

h


Ở đây, ta thấy thiết kế sử dụng 122 logic elements (chiếm chưa đến 1% số logic elements
của thiết bị), bao gồm: 109 hàm tổ hợp và 101 thanh ghi. Ngoài ra tổng số pins là 55 (chiếm
12% số pins của thiết bị). Từ đó, ta nhận thấy rằng phần cứng sử dụng của hai thiết kế là khá
tương đương nhau.

Đại học Bách khoa TPHCM

Trang 15

h


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 u cầu tính tốn logarit.
Một phép tố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 2−2 + 𝑦3 2−3 + ⋯ (3)
𝑖=1 𝑦𝑖 2
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𝑦1 2

Đại học Bách khoa TPHCM

+ 𝑦2 2−2 +𝑦3 2−3 +⋯

(4)

Trang 16

h


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 +⋯
3
3

𝑥 2 = 2𝑦1 2 𝑦22

(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

𝑦1 = 0; 𝑥 2 = 2 𝑦2 2 +𝑦3 2 +𝑦3 2 +⋯
{
(6)
−1
−2
−3
𝑦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)

Đại học Bách khoa TPHCM

Trang 17

h


1.2.3

Giải thuật tính tốn

Từ các phương trình đã trình bày ở mục 1.2.2, ta sẽ xây dựng được lưu đồ giải thuật

để tìm y khi biết x như sau:

Đại học Bách khoa TPHCM

Trang 18

h


1.2.4


Code mô phỏng

Code thực hiện

module log2(clk,rst,in,out,flag,inf);
input[15:0] in;
input clk, rst;
output reg[15:0] out;
output reg flag, inf;
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
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

Đại học Bách khoa TPHCM

Trang 19

h


default: begin
frac[0] <= 1'bz;
end
endcase
state <= PRESQUARE;
count <= count - 1;
end
DONE: begin
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;
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 = 9000; rst = 1; #2; rst = 0; #200;
in = 6557; rst = 1; #2; rst = 0; #200;
in = 1278; rst = 1; #2; rst = 0; #200;
in = 25698; 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 = 2048; rst = 1; #2; rst = 0; #200;
in = 65535; rst = 1; #2; rst = 0; #200;

Đại học Bách khoa TPHCM

Trang 20

h


$finish;
end

initial begin
forever begin
clk = 0; #1;
clk = 1; #1;
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 = 9000; rst = 1; #2; rst = 0; #200;
in = 6557; rst = 1; #2; rst = 0; #200;
in = 1278; rst = 1; #2; rst = 0; #200;
in = 25698; 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 = 2048; rst = 1; #2; rst = 0; #200;
in = 65535; rst = 1; #2; rst = 0; #200;
Lần lượt thay đổi giá trị in (x) để thu được giá trị out (y). 4 bit đầu tiên của out (y) là phần
nguyên, 12 bit cuối là phần thập phân.


Đại học Bách khoa TPHCM

Trang 21

h


Hình 1.10 kết quả mơ phỏng của dạng sóng bằng code Verilog

Hình 1.11 Kết quả tính tốn được trên Matlab
Nhận xét:
Kết quả mơ phỏng có sự tương đồng với kết quả tính tốn được, với sai số lớn nhất 𝟏𝟎−𝟒

Đại học Bách khoa TPHCM

Trang 22

h


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.12 Đánh giá tài nguyên phần cứng của module log2

Đại học Bách khoa TPHCM

Trang 23


h


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 tố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 tố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.

− Ngun 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ố ngồ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.
− 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.

Đại học Bách khoa TPHCM

Trang 24

h



×