TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN ĐIỆN TỬ - VIỂN THÔNG
BÁO CÁO BÀI TẬP LỚN
Thiết kế tổng hợp hệ thống số
Đề tài: Bài tập thiết kế
Giảng viên : TS Võ Lê Cường
Họ và tên
MSSV
Đỗ Duy Khải
20142327
Nguyễn Hoài Sơn
20143827
1
Hà nội 11/2018
MỤC LỤC
PHÂN CHIA CÔNG VIỆC
- Sơn Khải: cả hai cùng làm báo cáo phần công việc của mình
2
- Sơn: các bài tập chương 3(FPGA), mô phỏng các mạch đếm và mạch cộng 2
và 4 bit(bài tập đầu kì)
- Khải: Các bài tập chương 4(FPGA) , mô phỏng các mạch so sánh (bài tập đầu
kì)
- Các bài tập ví dụ và mô phỏng trong tài liệu FPGA and HDL.
Chương 1:
Bài tập về sử dụng modelsim
1.1.Thiết kế mạch so sánh 2 bit
3
1.1.1 So sánh mô hình cấu trúc:
-
Yêu cầu : sử dụng mô hình cấu trúc để thiết kế mạch so sánh
Mục tiêu : sử dụng các công logic đơn giản :
Thiết kế ta vẽ bìa các nô cho 2 đầu vào
[1:0] A, [1:0]B
INPUT
A1
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
A0
0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1
B1
0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1
B0
0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1
A>B
0
0
0
0
1
0
0
0
1
1
0
0
1
1
1
0
OUTPUT
A= B
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
A
0
1
1
1
0
0
1
1
0
0
0
1
0
0
0
0
module Comp2bit
(
output gt, AltB, AeqB,
4
input [1:0]A, [1:0]B
);
wire [1:0]Ad, Bd;
not not1(Ad[0], A[0]);
not not2(Ad[1], A[1]);
not not3(Bd[0], B[0]);
not not4(Bd[1], B[1]);
//AgtB
and and1(t1, A[0], Bd[0], Bd[1]);
and and2(t2, A[1], Bd[1]);
and and3(t3, A[1], A[0], Bd[0]);
or or1(gt, t1, t2, t3);
//AltB
and and4(u1, Ad[1], Ad[0], B[0]);
and and5(u2, Ad[1], B[1]);
and and6(u3, Ad[0], B[1], B[0]);
or or2(AltB, u1, u2, u3);
//AeqB
xnor xnor1(k1, A[0], B[0]);
xnor xnor2(k2, A[1], B[1]);
and and7(AeqB, k1, k2);
1.1.2 Dùng mô hình data flow
module Comp2bit
(
output gt, AltB, AeqB,
input [1:0]A, [1:0]B
);
5
assign gt = (A>B) ?1:0;
assign AltB = (A
assign AeqB = (A==B) ?1:0;
endmodule
TestBench
`timescale 1ns/ 1ns
module tb_comp2bit;
reg [1:0]A;
reg [1:0]B;
wire gt, AltB, AeqB;
Comp2bit dut(gt, AltB, AeqB, A, B);
initial begin
A=0;
B=0;
#10;
end
initial begin
forever begin
#5 A[0]=!A[0];
end
end
initial begin
6
forever begin
#10 A[1]=!A[1];
end
end
initial begin
forever begin
#20 B=B+1;
end
end
endmodule
Mô Phỏng
1.2. Thiết kế mạch half add
-Yêu cầu : Thiết kế mạch tổ hợp cộng 2 bit đầu vào và không có nhớ.
+ Input: 2 đầu vào a,b
+ Output: Tổng S và giá trị nhớ C sinh ra từ phép tính a + b
-Thiết kế:
7
-DUT
Code
module half_add (X, Y, S, C);
input X, Y ;
output S, C ;
xor SUM (S, X, Y);
and CARRY (C, X, Y);
endmodule
Testbench
module tb_half_add();
reg X, Y;
wire S, C;
half_add dut( .S(S), .C(C), .X(X), .Y(Y));
initial begin
X=0;Y=0;
end
initial forever #5 X=~X;
initial forever #10 Y=~Y;
endmodule
Mô phỏng
8
1.3.Thiết kế mạch full add 1bit
-Yêu cầu : Thiết kế bộ cộng FA 1 bit
-Thiết kế:
-DUT
Code
module fulladd1 (sum, c_out, a, b, c_in);
output sum, c_out;
9
input a, b, c_in;
wire s1, c1, c2;
xor (s1, a, b);
and (c1, a, b);
xor (sum, s1, c_in);
and (c2, s1, c_in);
xor (c_out, c2, c1);
endmodule
Testbench
module tb_full_add_1bit();
reg a, b ,c_in;
wire sum, c_out;
fulladd1 dut( .sum(sum), .c_out(c_out), .a(a), .b(b), .c_in(c_in));
initial begin
a=0; b=0;c_in=0;
end
initial forever #5 a=~a;
initial forever #10 b=~b;
initial forever #20 c_in=~c_in;
endmodule
Mô phỏng
1.4.Thiết kế mạch full add 4bit
-Yêu cầu ,mục tiêu
10
-Thiết kế bằng tay
-DUT
Code
Testbench
Mô phỏng
1.5.Thiết kế mạch mux 2-1
-Yêu cầu : Thiết kế bộ mux 2-1
-Thiết kế :
S D
1
0 0
0 0
0 1
0 1
1 0
1 0
1 1
1 1
D
0
0
1
0
1
0
1
0
1
O
0
1
0
1
0
0
1
1
-DUT
Code
module fulladder_4bit(s,c4,a,b,c0);
input [3:0] a;
input [3:0] b;
input c0;
output [3:0] s;
output c4;
wire c1,c2,c3;
wire [4:0] s1;
full_adder_1_bit f0(s[0],c1,a[0],b[0],c0);
full_adder_1_bit f1(s[1],c2,a[1],b[1],c1);
11
full_adder_1_bit f2(s[2],c3,a[2],b[2],c2);
full_adder_1_bit f3(s[3],c4,a[3],b[3],c3);
//assign s1=a+b+c0;
//assign s=s1[3:0];
//assign c4=s1[4];
endmodule
Testbench
`timescale 1ns/1ns
module t_fulladder_4bit;
reg [3:0] a;
reg [3:0] b;
reg c0;
wire [3:0] s;
wire c4;
fulladder_4bit dut(s,c4,a,b,c0);
initial begin
a=4'b0000+1; b=4'b1111; c0=1'b1; #10;
a=4'b0000+1+1; b=4'b1111; c0=1'b1; #10;
a=4'b0000; b=4'b1111; c0=1'b1; #10;
a=4'b0001; b=4'b0011; c0=1'b0; #10;
a=4'b0010; b=4'b0001; c0=1'b1; #10;
a=4'b1000; b=4'b0011; c0=1'b0; #10;
a=4'b0110; b=4'b1111; c0=1'b1; #10;
a=4'b1001; b=4'b0011; c0=1'b0; #10;
a=4'b1010; b=4'b0101; c0=1'b1; #10;
a=4'b1000; b=4'b0001; c0=1'b0; #10;
end
endmodule
Mô phỏng
12
1.6.Thiết kế mạch mux 4-1
-Yêu cầu : Thiết kế bộ cộng 2 số 4 bit
-Thiết kế :Sử dụng 4 cổng add 1 bit
-DUT
Code
module mux_4to1(Y, S2,S1, A);
input S1,S2;
input [3:0] A;
output Y;
wire x1,x2;
mux_2to1 a1(x2,S1,A[0],A[1]);
mux_2to1 a2(x1,S1,A[2],A[3]);
mux_2to1 a3(Y,S2,x2,x1);
endmodule
Testbench
`timescale 1ns/1ns
module test_mux_4_1;
reg S1, S2;
reg [3:0] A;
13
wire Y;
// integer i = 0;
mux_4to1 dut(Y, S2, S1, A);
initial begin
S1 = 0;
S2 = 0;
A = 0;
#10;
end
initial begin
forever begin
#5 S1 = !S1;
end
end
initial begin
forever begin
#10 S2 = !S2;
end
end
initial begin
forever begin
#20 A = A+1;
end
end
endmodule
Mô phỏng
14
Chương 2: Các bài tập chương 3.
15
2.1Thiết kế mạch so sánh 1 bit 1eq_always
-
-
Yêu cầu , mục tiêu thiết kế: Viết lại mạch so sánh 1 bit dùng mô hình
always.
Thiết kế bằng tay: Đầu vào i0,i1, đầu ra eq
Code mô phỏng và file tesbench
Code:
module eqalway
(
input wire i0, i1,
output reg eq
);
reg p0, p1;
always @(i0, i1)
begin
p0 = ~i0 & ~i1;
p1 = i0 & i1;
eq = p0 | p1;
end
endmodule
Testbench
`timescale 1 ns / 1 ns
module tb_1eq_alway();
reg i0, i1;
wire eq;
eqalway dut(.eq(eq), .i0(i0), .i1(i1));//loi //
initial begin
i0=0; i1=0;
end
initial forever #5 i0= ~i0;
initial forever #10 i1= ~i1;
endmodule
-
Kết quả mô phỏng:
16
-
2.1.2Thiết kế mạch and_block_assign.
Yêu cầu :thiết kế mạch and
Thiết kế
-
DUT
Code
module and_block_assign
(
input wire a, b, c,
output reg y
);
always @*
begin
y = a;
y = y & b;
y = y & c;
end
endmodule
17
Testbench
-
module tb_and_block_assign();
reg a, b , c;
wire y;
and_block_assign dut( .y(y), .a(a), .b(b), .c(c));
initial begin
a=0; b=0; c=0;
end
initial forever #5 a = ~a;
initial forever #10 b = ~b;
initial forever #20 c = ~c;
endmodule
Kết quả mô phỏng
2.2.Thiết kế mạch and_cont_assign.
-
Yêu cầu và mục tiêu thiết kế:
Thiết kế bằng tay
DUT
Code
module and_cont_assign
(
input wire a, b, c,
output wire y
);
assign y = a;
18
-
assign y = y & b;
assign y = y & c;
endmodule
TestBench
module tb_and_cont_assign();
reg a, b , c;
wire y;
and_cont_assign dut( .y(y), .a(a), .b(b), .c(c));
initial begin
a=0; b=0; c=0;
end
initial forever #5 a = ~a;
initial forever #10 b = ~b;
initial forever #20 c = ~c;
endmodule
Kết quả mô phỏng
2.3.Thiết kế mạch prio_encoder_if.
-
-
Yêu cầu và mục tiêu thiết kế: Dùng 2 ví dụ đơn giản để chứng minh
sử dụng của câu lệnh if. Ví dụ đầu tiên là prio_encoder, có đầu vào là
4 bit riêng lẻ r input và r[4] là ưu tiên cao nhất. Đầu ra là mã nhị phân
Thiết kế bằng tay
19
-
Code mô phỏng và file testbench
Code
module prio_encoder_if
(
input wire [4:1] r,
output reg [2:0] y
);
always @*
if ( r[4] == 1'b1)
y = 3'b100;
else if (r[3] ==1'b1)
y = 3'b011;
else if (r[2] == 1'b1)
y = 3'bOlO;
else if (r[ll==l 'bl)
y = 3'b001;
else y = 3'bOOO;
endmodule
Testbench
module tb_prio_encoder_if();
reg [4:1] r,
[2:0] y ;
prio_encoder_if dut( .y(y), .r(r));
initial begin
a=0; b=0; c=0;
end
initial forever #5 a = ~a;
initial forever #10 b = ~b;
initial forever #20 c = ~c;
endmodule
-
Kết quả mô phỏng
2.4.Thiết kế mạch decoder_2_4_if
-
Yêu cầu và mục tiêu thiết kế: Là minh họa thứ 2 của câu lệnh if
Thiết kế :
20
-
DUT
Code
module decoder_2_4
(
input wire [1:0] a ,
input wire en ,
output reg [3:0] y
);
always @*
if ( en== 1'b0)
y = 4'b0000;
else if (a==2'b00)
y = 4'b0001;
else if (a==2'b01)
y = 4'b0010;
else if (a==2'b10)
y = 4'b0100;
else
y = 4'b1000 ;
endmodule
Testbench
`timescale 1ns/1ns
module tb_decoder_2_4;
21
reg [1:0] a;
reg en;
wire y;
decoder_2_4 dut(a,en,y);
initial begin
en=0;#20;
en=1;
end
initial begin
a=0;
forever #10 a=a+1;
end
endmodule
Kết quả mô phỏng
2.5.Thiết kế mạch decoder_2_4_case
-
Yêu cầu thiết kế: Dùng tương tự như prio_encoder if để minh họa
hoạt động của câu lệnh case. Có code chạy như trong giáo trình
Thiết kế bằng tay
Code
module decoder_2_4_case
(
22
input wire [1:0] a,
input wire en,
output reg [3:0] y
);
always @*
case ({en, a})
10 3'b000, 3'b001, 3'b010, 3'bOll: y = 4'bOOOO;
3'blOO: y = 4'bOOOl;
3'blOl: y = 4'bOOlO;
3'bllO: y = 4'bOlOO;
3'blll: y = 4'blOOO; // default can also be used IS endcase
endmodule
Testbench
Kết quả mô phỏng
2.6.Thiết kế mạch prio_encoder_case: (tương tự như trên)
-
Yêu cầu và mục tiêu thiết kế:
Thiết kế bằng tay:
-
DUT
Code
module prio_encoder_case
(
input wire [4: 1] r,
23
output reg [2:0] y
);
always @*
case (r)
4'b1000, 4'b1001, 4'b1010, 4'b1011,
4'b1100, 4'b1101, 4'b1110, 4'b1111:
y = 3'b100;
4'b0100, 4'b0101, 4'b0110, 4'b0111:
y = 3'b011;
4'b0010, 4'b0011:
y = 3'b010;
4'b0001:
y = 3'b001;
4'b0000:
y = 3'b000;
endcase
endmodule
Testbench
module tb_prio_encoder_case();
reg [4:1] r;
wire [2:0] y;
prio_encoder_case dut( .y(y), .r(r));
initial begin
r = 4'b0000;
end
initial forever #5 r = r +1;
24
endmodule
Mô phỏng
2.7.Thiết kế mạch prio_encoder_casez và casex
-
-
Yêu cầu và mục tiêu thiết kế:Tương tự như trường hợp của lệnh case
nhưng có những điểm khác là giá trị của z và ? trong mỗi biểu thức
được xử lí như là don’t care . Trong casex thì giá trị của z và x , ?
được xử lí như don’t care vì giá trị của z và x có thể xuất hiện trong
mô phỏng.
Thiết kế bằng tay
DUT
Code
module prio_encoder_casez
(
input wire [4:1] r,
output reg [2:0] y
);
always @*
casez (r)
4'b1???: y = 3'b100;
4'b01??: y = 3'b011;
4'b001?: y = 3'b010;
4'b0001: y = 3'b001;
25