Mạch so sánh 4 bit dùng verilog

 Thực hành lập trình ứng dụng trên máy tính, biên dịch chương trình, nạp chương trình vào FPGA và sử dụng KIT DE2 để kiểm chứng.  Điều khiển thiết bị ngoại vi bằng các port của FPGA

 Mô tả mạch tổ hợp cơ bản dùng ngôn ngữ veilog HDL

Yêu cầu:

 Nắm vững cách viết chương trình dùng ngôn ngữ Verilog HDL  Nắm vững cách kết nối máy tính với KIT DE

 Sử dụng thành thục phần mền Quatus để viết chương trình, biên dịch chương trình, nạp chương trình vào FPGA  Nắm vững cấu trúc phần cứng của công tắc, nút nhấn, led đơn trên KIT DE

 Sinh viên làm theo các bước hướng dẫn trong các bài thực hành

Nội dung:

I. Thiết bị và vật dụng sử dụng:

  • Máy vi tính đã cài đặt phần mềm Quatus và driver USB blaster
  • KIT DE2, sử dụng chip CycloneII EP2C35F672C
  • Cáp USB blaster kết nối KIT DE2 và máy tính
  • DC adapter 12V/2A cấp nguồn cho KIT DE

II. Lý Thuyết

  1. Mạch cộng toàn phần và mạch cộng bán phần
  1. Khái niệm mạch cộng Mạch cộng là một loại mạch được sử dụng để cộng hai số nhị phân. Có hai loại bộ cộng:
  • Cộng toàn phần
  • Cộng bán phần
  1. Cộng bán phần

Mạch có khả năng thực hiện các phép cộng đơn giản với sự trợ giúp của các cổng logic.

Trước tiên cùng tìm hiểu cộng 1 bit

0 + 0 = 0

0 + 1 = 1

1 + 0 = 1

1 + 1 = 10

Đây là những tổ hợp 1 bit. Tuy nhiên có 1 kết quả của phép cộng 1 + 1 là 10. Mặc dù vấn

đề này có thể được giải quyết với sự trợ giúp của Cổng EXOR, nhưng nếu chúng ta quan

tâm đến đầu ra thì kết quả tổng phải được viết lại dưới dạng đầu ra 2 bit.

Do đó các phương trình trên có thể được viết là:

0 + 0 = 00

0 + 1 = 01

1 + 0 = 01

1 + 1 = 10

Từ bảng giá trị ta có được sơ đồ logic

Hình 6: Sơ đồ mạch logic HA Để đơn giản sơ đồ trên thì người ta đã thiết kế một sơ đồ đơn giản hơn được sử dụng để thể

hiện hoạt động của mạch.

Và dưới đây là sơ đồ đơn giản của bộ cộng đầy đủ 1 bit

Hình 6: mạch cộng FA một bit Với sơ đồ này, chúng ta có thẻ thực hiện cộng các bit cao hơn ví dụ như cộng 2 số 4 bit

chúng ta sẽ ghép nối nối tiếp 4 bộ cộng 1 bit gồm 4 tầng.

Hình 6 : mạch cộng nhị phân 4 bit

  1. Mạch nhân:

Ví dụ: mạch nhân 2 số 4 bit

Y 4 X 4 Y 3 X 3 Y 2 X 2 Y 1 X 1 Số bị nhânSố nhân

P 44 P 34 P 43 P 24 P 33 P 42 P 14 P 23 P 32 P 41 P 13 P 22 P 31 P 12 P 21 P 11 Tích từng phần

S 8 S 7 S 6 S 5 S 4 S 3 S 2 S 1 Kết quả

Việc thực hiện bài toán nhân có thể xem như gồm hai bước:

  • Tính các tích từng phần: thực hiện bởi các cổng AND
  • Tính tổng của các tích từng phần.

Hình 6 : Ký hiệu Mạch cộng toàn phần

Hình 6 : Mạch cộng toàn phần 4 bit

Hướng dẫn thực hiện:

Gán chân:

a=SW[3:0]

b=SW[7:4]; LEDG=s

B1: Xác định số ngõ vào, ngõ ra

Mạch có 4 ngõ vào cho số nhị phân 4 bit thứ nhất a tương ứng với các switch từ 0

tới 3, 4 ngõ vào cho số nhị phân 4 bit thứ hai b tương ứng với các switch từ 4 tới 7, 4

ngõ ra s tương ứng với các led green (LEDG) từ 0 tới 3 và bit nhớ c(out) tương ứng

với các led green 4.

B2: Các module trong chương trình:

Chương trình gồm 1 module chính cong4bit(SW, LEDG) và 1 module phụ

fa(co,s,a,b,ci). Trong module chính, khai báo các ngõ vào, ngõ ra và thực hiện gọi

module phụ 4 lần. Module phụ thực hiện mạch cộng toàn phần 1 bit theo sơ đồ như

hình 2 trong đề bài.

B3: Viết chương trình dùng ngôn ngữ Verilog

module cong4bit(SW, LEDG); input [7:0]SW; output [4:0]LEDG; wire [3:0]a,b; wire [4:0]s; wire n1; assign a=SW[3:0]; assign b=SW[7:4]; assign LEDG=s; fa (n1,s[0],a[0],b[0],1'b0); fa (n2,s[1],a[1],b[1],n1); fa (n3,s[2],a[2],b[2],n2); fa (s[4],s[3],a[3],b[3],n3); endmodule

module fa(co,s,a,b,ci); input a,b,ci; output co,s;

-Gán chân, biên dịch và nạp xuống chip FPGA.

-Kiểm tra mạch và thử các giá trị ngõ vào A, B, Cin.

module add(SW,LEDG,HEX6,HEX4,HEX1,HEX0); output [6:0]HEX0,HEX1,HEX4,HEX6; input [8:0]SW; output [7:0]LEDG; wire [3:0]a,b,a1,b1; wire [4:0]s,u; wire n1,n2,n3; assign a = SW[3:0]; assign b = SW[7:4]; kiemtra (LEDG[7],a1,a); kiemtra (LEDG[6],b1,b); fa (n1,s[0],a1[0],b1[0],1'b0); fa (n2,s[1],a1[1],b1[1],n1); fa (n3,s[2],a1[2],b1[2],n2); fa (s[4],s[3],a1[3],b1[3],n3); assign u = {4'b0000,{SW[8]}} + s; bcd (HEX4,a1); bcd (HEX6,b1); bcd1 (HEX0,HEX1,u); endmodule

module kiemtra (b,a1,a); input [3:0]a; output reg[3:0]a1; output reg b; always@(a) begin case(a) 4'b0000: a1=4'b0000; 4'b0001: a1=4'b0001; 4'b0010: a1=4'b0010; 4'b0011: a1=4'b0011; 4'b0100: a1=4'b0100; 4'b0101: a1=4'b0101; 4'b0110: a1=4'b0110; 4'b0111: a1=4'b0111; 4'b1000: a1=4'b1000; 4'b1001: a1=4'b1001; default: begin

a1=4'b0000; b = 1'b1; end endcase end endmodule

module bcd1 (a,b,c); input [4:0]c; output reg [6:0]a,b; always@(c) begin case(c) 5'b00000: begin a=7'b1000000;// b=7'b1000000;// end 5'b00001: begin a=7'b1111001;// b=7'b1000000;// end 5'b00010: begin a=7'b0100100;// b=7'b1000000;// end 5'b00011: begin a=7'b0110000;// b=7'b1000000;// end 5'b00100: begin a=7'b0011001;// b=7'b1000000;// end 5'b00101: begin a=7'b0010010;// b=7'b1000000;// end 5'b00110: begin a=7'b0000010;// b=7'b1000000;// end 5'b00111: begin a=7'b1111000;//

a=7'b0000000;// b=7'b1111001;// end 5'b10011: begin a=7'b0010000;// b=7'b1111001;// end endcase end endmodule

module bcd (b,a); input [3:0]a; output reg[6:0]b; always@(a) begin case(a) 4'b0000: b=7'b1000000;// 4'b0001: b=7'b1111001;// 4'b0010: b=7'b0100100;// 4'b0011: b=7'b0110000;// 4'b0100: b=7'b0011001;// 4'b0101: b=7'b0010010;// 4'b0110: b=7'b0000010;// 4'b0111: b=7'b1111000;// 4'b1000: b=7'b0000000;// 4'b1001: b=7'b0010000;// endcase end endmodule

module fa (co,s,a,b,ci); input a,b,ci; output co,s; wire n1,n2,n3,n4; xor (n1,a,b); xor (s,ci,n1); not (n2,n1); and (n3,n2,b); and (n4,ci,n1); or (co,n3,n4); endmodule

Bài tập 3: Thực hiện mạch cộng 2 số BCD 2 chữ số A1A0, B1B0. Tổng là 1 số BCD 3 chữ số S2S1S0. Thực hiện theo các bước sau:

-Sử dụng các SW15-8, SW7-0 để thực hiện cung cấp các giá trị cho 2 ngõ vào A1A0, B1B0. Các giá trị A1A0 hiển thị trên LED 7 đoạn HEX7 và HEX6, B1B0 hiển thị trên LED 7 đoạn HEX5 và HEX4, giá trị tổng S2S1S0 hiển thị trên LED 7 đoạn HEX2,

HEX1 và HEX0.

-Gán chân, biên dịch và nạp xuống chip FPGA.

-Kiểm tra hoạt động của mạch.

Bài tập 4: Thực hiện mạch cộng 2 số BCD 2 chữ số A1A0, B1B0 như bài 3 nhưng sử

dụng đoạn code sau:

1 T0 = A0 + B 0 2 if(T 0 > 9) then 3 Z0 = 10; 4 c1 = 1; 5 else 6 Z0 = 0; 7 c1 = 0; 8 end if 9 S0 = T 0 − Z 0 10 T1 = A1 + B1 + c 1 11 if (T 1 > 9) then 12 Z1 = 10; 13 c2 = 1; 14 else 15 Z1 = 0; 16 c2 = 0; 17 end if 18 S1 = T 1 − Z 1 19 S2 = c 2

Tại các dòng 1, 9, 10, 18 là các mạch cộng, các dòng 2-8, 11-17 là mạch multiplexer. CÁc

dòng lệnh kiểm tra điều kiện T0>9 và T1>9 là mạch so sánh, lưu ý có thể sử dụng mạch

cộng thay cho mạch trừ ở dòng 9 và 18

-Tạo 1 project mới, sử dụng các SW, LED như trong bài 3.

Hình 6: nhân 2 số nhị phân 4 bit

Thiết kế mạch nhân 2 số nhị phân 4 bit như hình 5, thực hiện theo các bước sau:

-Tạo 1 project mới -Sử dụng các SW11-8 để thực hiện cung cấp các giá trị cho số A, các SW3-0 để thực hiện cung cấp các giá trị cho số B. Các giá trị hexa của A và B hiển thị trên các LED 7 đoạn HEX6 và HEX4. Kết quả P = A x B hiển thị trên HEX1 và HEX0. -Gán chân, biên dịch, nạp xuống KIT và kiểm tra kết quả.

module machnhan (SW, HEX7, HEX6, HEX5, HEX4, HEX3, HEX2, HEX1, HEX0); input [15:0] SW; output [0:6] HEX7, HEX6, HEX5, HEX4, HEX3, HEX2, HEX1, HEX0;

wire [3:0] A, B; wire [7:0] P; wire [3:1] C_b1; wire [5:2] PP1; wire [3:1] C_b2; wire [6:3] PP2; wire [3:1] C_b3;

assign A = SW[11:8]; assign B = SW[3:0]; assign P[0] = A[0] & B[0];

// module fa (a, b, ci, s, co); fa b3_a0 (PP2[3], A[0] & B[3], 1'b0, P[3], C_b3[1]); fa b3_a1 (PP2[4], A[1] & B[3], C_b3[1], P[4], C_b3[2]); fa b3_a2 (PP2[5], A[2] & B[3], C_b3[2], P[5], C_b3[3]); fa b3_a3 (PP2[6], A[3] & B[3], C_b3[3], P[6], P[7]);