Trường Đại học Bách Khoa
Đại học Quốc Gia Thành Phố Hồ Chí Minh
BÁO CÁO BÀI TẬP LỚN
Mơn: Xử lí tín hiệu số với FPGA
GVHD: Thầy Trịnh Vũ Đăng Nguyên
Thực hiện bởi: nhóm 4
Phạm Thanh Nhàn
Vũ Châu Duy Tùng
Đào Việt Hồng
Trần Nhân Tông
Nguyễn Ngọc Độ
TIEU LUAN MOI download : moi nhat
BÁO CÁO KẾT QUẢ LÀM VIỆC NHÓM
STT
1
2
3
4
5
TIEU LUAN MOI download : moi nhat
Bài 1:
1.1.
Đề bài:
TIEU LUAN MOI download : moi nhat
TIEU LUAN MOI download : moi nhat
1.2.
Lưu đồ giải thuật:
1.2.1. Giải thuật 1:
- Khai báo:
input [3:0] I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15;
output [3:0] min1, min2, index_min1; reg [63:0] arr;
reg [3:0] min1, min2, index_min1;
integer i;
- Mỗi khi có sự thay đổi ở tất cả các ngõ vào, ta có:
TIEU LUAN MOI download : moi nhat
- Đánh giá tài nguyên:
TIEU LUAN MOI download : moi nhat
- Kết quả mô phỏng:
TIEU LUAN MOI download : moi nhat
1.2.2. Giải thuật 2:
- Khai báo:
input [3:0] I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15;
output [3:0] min1, min2, index_min1; wire [3:0] index_min2;
wire [63:0] arr, new_arr;
assign arr = {I15, I14, I13, I12, I11, I10, I9, I8, I7, I6, I5, I4, I3, I2, I1, I0};
- Ta dùng module find_min_in_arr để tìm min1 và index_min1 trong arr
- Ta dùng module replace15_by_index để thay thế giá trị tại vị trí index_min1
thành 15, thu được chuỗi mới new_arr
- Ta dùng module find_min_in_arr để tìm min2 trong new_arr
1.2.2.1 .
Module find_min_in_arr:
- Khai báo:
input [63:0] arr;
wire [3:0] I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15;
output [3:0] min, index_min;
wire [3:0] min_val_a [7:0], id_out_a [7:0];
wire [3:0] min_val_b [3:0], id_out_b [3:0];
wire [3:0] min_val_c [1:0], id_out_c [1:0];
assign {I15, I14, I13, I12, I11, I10, I9, I8, I7, I6, I5, I4, I3, I2, I1, I0}
=
arr;
- Trong module này, ta tiến hành so sánh từng cặp giá trị để tìm min và id của giá
trị min đó, với id là số tự nhiên tương ứng với chỉ số của từng input, ví dụ: id của
I0 là 0, của I1 là 1, …, của I15 là 15.
- Có 16 input nên ta sẽ chia làm 4 round, round 1 có 16 input nên chia ra thành 8
cặp để so sánh, ngõ ra của round 1 được đưa vào round 2 và lúc này chỉ còn 4 cặp
để so sánh. Tương tự vậy đến round 4 ta chỉ còn 2 input tạo thành một cặp giá trị
để so sánh, ngõ ra của phép so sánh này cũng chính là ngõ ra của module.
- Module được sử dụng để so sánh cặp giá trị là find_min_index
TIEU LUAN MOI download : moi nhat
1.2.2.2.
Module find_min_index:
- Khai báo:
input [3:0] A, B, idA, idB;
output [3:0] min_val, id_out;
wire Oe, Og, Ol;
wire [2:0] result;
reg [3:0] min_val, id_out;
- Dùng module compare_4bit để so sánh A và B, giá trị trả về dưới dạng one
hot vector {Oe, Og, Ol} tương ứng với các trạng thái A=B, A>B và A
- Gán result = {Oe, Og, Ol}
+ result=3'b001,3'b100: min_val = A; id_out = idA;
+ result=3'b010: min_val = B; id_out = idB;
+ Các TH còn lại: min_val = 4'bx; id_out = 4'bx;
1.2.2.3.
Module compare_4bit:
- Khai báo:
input [3:0] A, B;
output Oe, Og, Ol;
wire [1:0] A0, A1, B0, B1;
wire [1:0] R0, R1;
- Phân tách mỗi ngõ vào A, B thành 2 phần {A1, A0} và
{B1, B0}: assign A0 = A[1:0];
assign A1 = A[3:2];
assign B0 = B[1:0];
assign B1 = B[3:2];
- Ứng với từng cặp (A1, B1), (A0, B0), ta đưa vào module compare_2bit thu được
2 output R1, R0
- Cặp giá trị R1, R0 được đưa vào ngõ vào của module compare_result để đưa
ngõ ra về dạng {Oe, Og, Ol}
1.2.2.4.
Module compare_2bit:
- Khai báo:
input [1:0] A, B;
TIEU LUAN MOI download : moi nhat
output [1:0] R;
- Phép toán dựa trên bảng chân trị và bìa K:
assign R[1] = (~A[0]&B[0])|(A[0]&~B[0])|(~A[1]&B[1])|(A[1]&~B[1]);
assign R[0]=(~A[1]&~A[0])|(~A[1]&B[0])|(~A[1]&B[1])|(B[1]&~A[0])|(B[1]&B[0]);
- Giải thích:
+
Khi A=B: R=1;
+
Khi A>B: R=2;
+
Khi A
- Bảng chân trị:
A[1]
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
1.2.2.5.
Module compare_result:
- Khai báo:
input [1:0] R0, R1;
output Oe, Og, Ol;
- Phép toán dựa trên bảng chân trị và bìa K:
assign Oe = ~R1[1]&R1[0]&~R0[1]&R0[0];
assign Og = (R1[1]&~R1[0])|(~R1[1]&R1[0]&R0[1]&~R0[0]);
assign Ol = (R1[1]&R1[0])|(R1[0]&R0[1]&R0[0]);
TIEU LUAN MOI download : moi nhat
- Giải thích:
+ Theo ý tưởng của module này, R1 là kết quả so sánh của cặp số 2 bit trọng số cao
của cặp giá trị 4 bit cần so sánh, R0 là kết quả so sánh của cặp số 2 bit trọng số thấp
+
Khi R1=0 hoặc R0=0 thì ngõ ra là vơ định
+
Khi R1=1 thì kết quả phép so sánh phụ thuộc vào R2
+
Khi R1=2 thì kết quả so sánh là lớn hơn
+
Khi R1=3 thì kết quả so sánh là nhỏ hơn
- Bảng chân trị:
R1[1]
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
R1[0]
0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1
1.2.2.6.
Module replace15_by_index:
- Khai báo:
input [63:0] arr_in;
output [63:0] arr_out;
input [3:0] index;
- Phép toán:
assign arr_out = arr_in | (15 << index*4);
- Giải thích:
+ Module này dùng để thay giá trị của số 4 bit (trong 1 chuỗi gồm 16 số 4 bit nối với nhau)
thành 15 dựa trên chỉ số vị trí index của nó trong chuỗi số.
+ Module này dùng như 1 phương pháp xoá đi giá trị nhỏ nhất trong một chuỗi gồm
nhiều số 4 bit liên tếp nhau.
TIEU LUAN MOI download : moi nhat
❖
Đánh giá tài nguyên và kết quả mô phỏng giải thuật 2:
TIEU LUAN MOI download : moi nhat
1.3.
Code Verilog:
- Giải thuật 1:
`timescale 1ns / 100ps
module min_finder_1(I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, min1, min2,
index_min1);
input [3:0] I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15;
output [3:0] min1, min2, index_min1;
reg [63:0] arr;
reg [3:0] min1, min2,
index_min1; integer i;
always@(I0 or I1 or I2 or I3 or I4 or I5 or I6 or I7 or I8 or I9 or I10 or I11 or I12 or I13
or I14 or I15)
begin
min1 = 15;
min2 = 15;
arr = {I15, I14, I13, I12, I11, I10, I9, I8, I7, I6, I5, I4, I3, I2, I1, I0};
for (i=0; i<16; i=i+1)
if (arr[i*4 +: 4] < min1)
begin
index_min1 = i;
min1 = arr[i*4 +: 4];
end
else if (arr[i*4 +: 4] < min2)
min2 = arr[i*4 +: 4];
end
endmodule
module test_bench_1(min1, min2, index_min1);
output [3:0] min1, min2, index_min1;
reg [3:0] I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15;
min_finder_1 test3(I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, min1,
min2, index_min1);
initial
begin
I0=2; I1=3; I2=1; I3=2; I4=5; I5=6; I6=9; I7=9; I8=9; I9=9; I10=9; I11=9;
I12=9; I13=9; I14=9; I15=9; #1
I0=1; I1=4; I2=2; I3=1; I4=2; I5=12; I6=9; I7=9; I8=9; I9=9; I10=9; I11=9;
I12=9; I13=9; I14=9; I15=9; #1
I0=5; I1=2; I2=10; I3=0; I4=4; I5=1; I6=9; I7=9; I8=9; I9=9; I10=9; I11=9;
I12=9; I13=9; I14=9; I15=9;
end
endmodule
TIEU LUAN MOI download : moi nhat
- Giải thuật 2:
`timescale 1ns / 100ps
module test_bench_2(min1, min2, index_min1);
output [3:0] min1, min2, index_min1;
reg [3:0] I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15;
min_finder_2 test4(I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, min1,
min2, index_min1);
initial
begin
I0=2; I1=3; I2=1; I3=2; I4=5; I5=6; I6=9; I7=9; I8=9; I9=9; I10=9; I11=9;
I12=9; I13=9; I14=9; I15=9; #1
I0=1; I1=4; I2=2; I3=1; I4=2; I5=12; I6=9; I7=9; I8=9; I9=9; I10=9; I11=9;
I12=9; I13=9; I14=9; I15=9; #1
I0=5; I1=2; I2=10; I3=0; I4=4; I5=1; I6=9; I7=9; I8=9; I9=9; I10=9; I11=9;
I12=9; I13=9; I14=9; I15=9;
end
endmodule
module min_finder_2(I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, min1, min2,
index_min1);
input [3:0] I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15;
output [3:0] min1, min2, index_min1;
wire [3:0] index_min2;
wire [63:0] arr, new_arr;
assign arr = {I15, I14, I13, I12, I11, I10, I9, I8, I7, I6, I5, I4, I3, I2, I1, I0};
find_min_in_arr fma1(arr, min1, index_min1);
replace15_by_index rbi(arr, index_min1, new_arr);
find_min_in_arr fma2(new_arr, min2, index_min2);
endmodule
module find_min_in_arr(arr, min, index_min);
input [63:0] arr;
wire [3:0] I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15;
output [3:0] min, index_min;
wire [3:0] min_val_a [7:0], id_out_a [7:0];
wire [3:0] min_val_b [3:0], id_out_b [3:0];
wire [3:0] min_val_c [1:0], id_out_c [1:0];
assign {I15, I14, I13, I12, I11, I10, I9, I8, I7, I6, I5, I4, I3, I2, I1, I0} = arr;
// round 1
find_min_index match_a0(I0, I1, 0, 1, min_val_a[0], id_out_a[0]);
find_min_index match_a1(I2, I3, 2, 3, min_val_a[1], id_out_a[1]);
find_min_index match_a2(I4, I5, 4, 5, min_val_a[2], id_out_a[2]);
TIEU LUAN MOI download : moi nhat
find_min_index match_a3(I6, I7, 6, 7, min_val_a[3], id_out_a[3]);
find_min_index match_a4(I8, I9, 8, 9, min_val_a[4], id_out_a[4]);
find_min_index match_a5(I10, I11, 10, 11, min_val_a[5], id_out_a[5]);
find_min_index match_a6(I12, I13, 12, 13, min_val_a[6], id_out_a[6]);
find_min_index match_a7(I14, I15, 14, 15, min_val_a[7], id_out_a[7]);
// round 2
find_min_index match_b0(min_val_a[0], min_val_a[1], id_out_a[0], id_out_a[1],
min_val_b[0], id_out_b[0]);
find_min_index match_b1(min_val_a[2], min_val_a[3], id_out_a[2], id_out_a[3],
min_val_b[1], id_out_b[1]);
find_min_index match_b2(min_val_a[4], min_val_a[5], id_out_a[4], id_out_a[5],
min_val_b[2], id_out_b[2]);
find_min_index match_b3(min_val_a[6], min_val_a[7], id_out_a[6],
id_out_a[7], min_val_b[3], id_out_b[3]);
// round 3
find_min_index match_c0(min_val_b[0], min_val_b[1], id_out_b[0],
id_out_b[1], min_val_c[0], id_out_c[0]);
find_min_index match_c1(min_val_b[2], min_val_b[3], id_out_b[2],
id_out_b[3], min_val_c[1], id_out_c[1]);
// round 4
find_min_index match_d(min_val_c[0], min_val_c[1], id_out_c[0], id_out_c[1], min,
index_min);
endmodule
module replace15_by_index(arr_in, index, arr_out);
input [63:0] arr_in;
output [63:0] arr_out;
input [3:0] index;
assign arr_out = arr_in | (15 << index*4);
endmodule
module find_min_index(A, B, idA, idB, min_val,
id_out); input [3:0] A, B, idA, idB;
output [3:0] min_val, id_out;
wire Oe, Og, Ol;
wire [2:0] result;
reg [3:0] min_val, id_out;
compare_4bit compare_4bit_1(A, B, Oe, Og, Ol);
assign result = {Ol, Og, Oe};
always @(*)
case (result)
3'b001,3'b100:
begin
TIEU LUAN MOI download : moi nhat
min_val = A;
id_out = idA;
end
3'b010:
begin
min_val = B;
id_out = idB;
end
default
begin
min_val = 4'bx;
id_out = 4'bx;
end
endcase
endmodule
module compare_4bit(A, B, Oe, Og, Ol);
input [3:0] A, B;
output Oe, Og, Ol;
wire [1:0] A0, A1, B0, B1;
wire [1:0] R0, R1;
assign A0 = A[1:0];
assign A1 = A[3:2];
assign B0 = B[1:0];
assign B1 = B[3:2];
compare_2bit compare1(A1, B1, R1);
compare_2bit compare0(A0, B0, R0);
compare_result cr(R1, R0, Oe, Og, Ol);
endmodule
module compare_result(R1, R0, Oe, Og, Ol);
input [1:0] R0, R1;
output Oe, Og, Ol;
assign Oe = ~R1[1]&R1[0]&~R0[1]&R0[0];
assign Og = (R1[1]&~R1[0])|(~R1[1]&R1[0]&R0[1]&~R0[0]);
assign Ol = (R1[1]&R1[0])|(R1[0]&R0[1]&R0[0]);
endmodule
module compare_2bit(A, B, R);
input [1:0] A, B;
output [1:0] R;
assign R[1] = (~A[0]&B[0])|(A[0]&~B[0])|(~A[1]&B[1])|(A[1]&~B[1]);
assign R[0] = (~A[1]&~A[0])|(~A[1]&B[0])|(~A[1]&B[1])|(B[1]&~A[0])|
(B[1]&B[0]); endmodule
TIEU LUAN MOI download : moi nhat
Câu 2:
Tính giá trị log2( ), với
là số 16 bit không dấu
Giả sử log2( ) = , …, Vậy ta có thể quy q trình tính log2( ) về 2 phần : tính phần
nguyên (integer) k (4 bit) và phần phân số (fractional part) (12 bit).
( ) = log2
log2
Với phần nguyên ta áp dụng tính chất số nhị phân n bit có 2 giá trị từ 0 đến 2 − 1, ta
có thể tím ra phần ngun với ngun tắc của bộ priority encoder 16 to 4
Code:
module log2_itg(in1,out1);
input [15:0]in1;
output reg[3:0] out1;
always@(in1 or out1)
begin
if(in1[15]==1'b1) out1=4'b1111;
else if(in1[14]==1'b1) out1=4'b1110;
else if(in1[13]==1'b1) out1=4'b1101;
else if(in1[12]==1'b1) out1=4'b1100;
else if(in1[11]==1'b1) out1=4'b1011;
else if(in1[10]==1'b1) out1=4'b1010;
else if(in1[9]==1'b1) out1=4'b1001;
else if(in1[8]==1'b1) out1=4'b1000;
else if(in1[7]==1'b1) out1=4'b0111;
else if(in1[6]==1'b1) out1=4'b0110;
else if(in1[5]==1'b1) out1=4'b0101;
else if(in1[4]==1'b1) out1=4'b0100;
else if(in1[3]==1'b1) out1=4'b0011;
else if(in1[2]==1'b1) out1=4'b0010;
TIEU LUAN MOI download : moi nhat
else if(in1[1]==1'b1) out1=4'b0001;
else if(in1[0]==1'b1) out1=4'b0000;
else
out1=4'bzzzz;
end
endmodule
Với phần phân số: Đặt
Giả sử log2 = →
=
2
,1≤ <2
=2,0≤ <1
Y có thể biểu diễn dưới dạng nhị phân:
=∑
12
−
× 2 =1 × 2
=1
−1
−2
+2 × 2
+3 × 2
→
→ =2
2
−3
+ ⋯, trong đó yi = 1 hoặc 0
= 2 1×2
1
−1
+ 2×2
−1
× 2 2×2
−2
+ 3×2
−2
+ 3×2
−3
+⋯
−3
+ 4×2
+⋯
Nếu:{
1
=1→ 2=2×2 2×2
1
Sau đó ta chia cho 2 và kiểm tra bit tiếp theo
2
Khi viết code ta sẽ biến( ) thành (
tương tự với
2
( )
2
Giải thuật:
2
so sánh v
TIEU LUAN MOI download : moi nhat
Bắt đầu
k
x/2^k
i>=0?
No
Kết thúc
YES
X=x*x
Y(i)=0
i=i-1
No
X>=2?
YES
Y(i)=1
x=x>>1
i=i-1
Code:
module log_2(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,temp;
wire [31:0] sqr1;
reg[2:0] state;
reg[3:0] count;
wire[3:0] cout1;
wire[3:0] itg;
TIEU LUAN MOI download : moi nhat