Trong bài viết này chúng ta sẽ viết từng module nhỏ trong verilog và ghép chúng lại theo yêu cầu của bài toán nhé!. Vào thẳng ví dụ luôn thôi.
Cho bài toán: Cho 4 module con: dịch trái/phải (Shift left/right), chia 10 (div 10), nhân (Multiple), Công/Trừ (Add/Sub) (các module có đầu vào và ra đều là số nguyên). Mỗi module sẽ sử dụng một lượng tài nguyên nhất định (Resource) và có độ trễ T như hình dưới. Hãy thiết kết một module lớn sử dụng 4 module con dưới đây để thực hiện phép toán M = 7.5*A + 5*B + 4.5*C, biết rằng module lớn sử dụng tối đa tài nguyên Resource = 100 và độ trễ tối đa Tmax = 30.
Thoạt nhìn ta thấy M sử dụng 3 phép nhân, 2 phép cộng nên T = 3*7 + 2*5 = 31 > Tmax. Nhìn kỹ ta lại thấy, càng thực hiện tách M ra thì T càng tăng => Tmin của M là 31. "Hay đề sai nhỉ???".
Đề không sai nhé, ta có thể thực hiện 3 phép nhân song song cùng lúc chỉ mất T = 7. Tiếp theo, đầu vào của các module chỉ là số nguyên mà 7.5, 4.5 có nguyên đâu?. Ta tiến hành:
Chỉ mất Resource = 85 và T = 20.
Code thôi mọi người ơi!
module multiple(num1, num2, result);
input[7:0] num1, num2;
output[15:0] result;
assign result = num1 * num2;
endmodule;
module add_sub(num1, num2, s, result);
input[15:0] num1, num2;
input s;
output[15:0] result;
assign result = s ? num1 + num2 : num1 - num2;
endmodule
module shift(num, shift, s, result);
input [15:0] num;
input [2:0] shift;
input s;
output [15:0] result;
assign result = s ? num << shift : num >> shift;
endmodule
module calculator(A, B, C, M);
input[7:0] A, B, C;
output[15:0] M;
wire[15:0] a, b, c, d, N;
multiple m1(.num1(8'd15), .num2(A), .result(a));
multiple m2(.num1(8'd10), .num2(B), .result(b));
multiple m3(.num1(8'd9), .num2(C), .result(c));
add_sub a1(.num1(a), .num2(b), .s(1'b1), .result(d));
add_sub a2(.num1(c), .num2(d), .s(1'b1), .result(N));
shift s1(.num(N), .shift(3'b001), .s(1'b0), .result(M));
endmodule
module tb_calculator;
reg[7:0] A, B, C;
wire[15:0] M;
calculator c(.A(A), .B(B), .C(C), .M(M));
initial begin
A = 8'd2;
B = 8'd3;
C = 8'd4;
$monitor("A = %d, B = %d, C = %d, M = %d", A, B, C, M);
end
endmodule
Bài hay phết nhỉ mọi người! Hẹn gặp lại mọi người ở bài viết khác nhé!