Tóm tắt bài giảng Verilog

I. Giới thiệu
Verilog HDL là một trong hai ngôn ngữ mô phỏng phần cứng thông
dụng nhất, được dùng trong thiết kế IC, ngôn ngữ kia là VHDL. HDL cho
phép mô phỏng các thiết kế dễ dàng, sửa chữa lỗi, hoặc thực nghiệm bằng
những cấu trúc khác nhau. Các thiết kế được mô tả trong HDL là những kỹ
thuật độc lập, dễ thiết kế, dễ tháo gỡ, và thường dễ đọc hơn ở dạng biểu đồ,
đặc biệt là ở các mạch điện lớn 
pdf 16 trang thamphan 29/12/2022 2620
Bạn đang xem tài liệu "Tóm tắt bài giảng Verilog", để tải tài liệu gốc về máy hãy click vào nút Download ở trên.

File đính kèm:

  • pdftom_tat_bai_giang_verilog.pdf

Nội dung text: Tóm tắt bài giảng Verilog

  1. TÓM TẮT BÀI GIẢNG VERILOG 1. Khoảng trắng Khoảng trắng ngăn những từ và có thể chứa khoảng cách, khoảng CHƯƠNG I - TỔNG QUAN dài, dòng mới và dạng đường dẫn. Do đó, một lệnh có thể đưa ra nhiều I. Giới thiệu dòng phức tạp hơn mà không có những đặc tính đặc biệt. Verilog HDL là một trong hai ngôn ngữ mô phỏng phần cứng thông 2. Chú giải dụng nhất, được dùng trong thiết kế IC, ngôn ngữ kia là VHDL. HDL cho Những chú giải có thể chỉ định bằng hai cách: (giống trong C/C++). phép mô phỏng các thiết kế dễ dàng, sửa chữa lỗi, hoặc thực nghiệm bằng Chú giải được viết sau hai dấu gạch xiên (//). Được viết trên cùng những cấu trúc khác nhau. Các thiết kế được mô tả trong HDL là những kỹ một dòng. thuật độc lập, dễ thiết kế, dễ tháo gỡ, và thường dễ đọc hơn ở dạng biểu đồ, Được viết giữa /* */, khi viết nhiều dòng chú giải. đặc biệt là ở các mạch điện lớn. Verilog thường được dùng để mô tả thiết kế ở bốn dạng: 3. Chữ số Thuật toán (một số lệnh giống ngôn ngữ C như: if, case, for,while ). Lưu trữ số được định nghĩa như là một con số của các bit, giá trị có Chuyển đổi thanh ghi (kết nối bằng các biểu thức Boolean). thể là: số nhị phân, bát phân, thập phân, hoặc thập lục phân. Các cổng kết nối( cổng: OR, AND, NOT ). Ví dụ: 3’b001, 5’d30 = 5’b11110, Chuyển mạch (BJT, MOSFET) 16’h5ED4 = 16’d24276 = 16’b0101111011010100 Ngôn ngữ này cũng chỉ rõ cách thức kết nối, điều khiển vào/ra trong mô phỏng. 4. Từ định danh Cấu trúc chương trình dùng ngôn ngữ Verilog Từ định danh do người dùng quy định cho biến số, tên hàm, tên môđun, tên khối và tên trường hợp. Từ định danh bắt đầu bằng một mẫu tự // Khai báo module hoặc đường gạch dưới ’_’ ( không bắt đầu bằng một con số hoặc $ ) và kể Module tên chương trình (tên biến I/O); // tên chương trình cả mọi chữ số của mẫu tự, những con số và đường gạch dưới, từ định danh trùng tên file.v. trong Verilog phân biệt dạng chữ. Input [msb:lsb] biến; 5. Cú pháp Output [msb:lsb] biến; Kí hiệu cho phép: Reg [msb:lsb] biến reg; ABDCE abcdef 1234567890_$ Wire [msb: lsb] biến wire; Không cho phép: các kí hiệu khác -, &, #, @ // Khai báo khối always, hoặc khối initial. 6. Toán tử các lệnh Toán tử là một, hai, hoặc ba kí tự dùng để thực hiện các toán hạng trên biến. Endmodule Các toán tử bao gồm >, +, &, !=. 7. Từ khóaVerilog Có nhiều từ mã có ý nghĩa đặc biệt trong Verilog. Ví dụ: assign, .II. Ý nghĩa các thuật ngữ trong VERILOG case, while, wire, reg, and, or, nand, và module. Chúng không được dùng Các tập tin văn bản nguồn Verilog bao gồm những biểu hiện thuộc như từ định danh. Từ khóa Verilog cũng bao gồm cả chỉ dẫn chương trình tính từ vựng sau đây: biên dịch và System Task (hệ thống soạn thảo) và các hàm.
  2. VI. Supply 0, Supply1 Chương III - CÁC CỔNG CƠ BẢN TRONG VERILOG Xác định chổ đường dẫn lên mức logic 0 ( đất), logic 1( nguồn) theo Các cổng logic cơ sở là một bộ phận của ngôn ngữ Verilog. Có hai thứ tự định sẵn. đặc tính được chỉ rõ là: drive_strenght và delay. VII. Time Drive_strenght chỉ sức bền của cổng. Độ bền đầu ra là sự kết nối một Time là một lượng 64 bit mà được sử dụng cùng với $time, hệ thống chiều đến nguồn, kế đó tạo nên sự kết nối trong suốt trans dẫn, kết thúc là thao tác chứa lượng thời gian mô phỏng. Time không được hỗ trợ tổng hợp tổng trở kéo lên hoặc xuống. Drive_strenght thường không được chỉ rõ, và và thế chỉ được dùng trong mục đích mô phỏng. trong trường hợp này độ bền mặc định là strong1 và strong0 . 1. Cú pháp: Delay: nếu delay không được chỉ rõ, thì khi đó cổng không có trì hoãn Time biến time; truyền tải; nếu có hai delay được chỉ định, thì trước tiên là miêu tả trì hoãn 2. Ví dụ: lên, thứ hai là trì hoãn xuống. Nếu chỉ có một delay được chỉ định, thì khi Time c; đó trì hoãn lên xuống là như nhau. Delay được bỏ qua trong tổng hợp. c = $time; // c = thời gian mô phỏng dòng điện. Phương pháp của sự trì hoãn chỉ định này là một trường hợp đặc biệt của VIII. Parameter (Tham số) “Parameterized Modules”. Các tham số cho các cổng cơ sở phải được định Một Parameter xác định 1 hằng số mà được đặt khi bạn cho ví dụ cụ nghĩa trước như delay. thể là một module. Các này cho phép ta có thể sửa chữa. I. Các cổng cơ bản 1. Cú pháp: Các cổng cơ bản có một đầu ra, và có một hoặc nhiều đầu vào. Parameter par_1= giá trị, par_2= giá trị, ; Trong các cổng, cú pháp cụ thể biểu diễn bên dưới, các từ khoá của các Parameter [giới hạn] par_3 = giá tr?; cổng: and, or, nand, nor. 2. Ví dụ: 1. Cú pháp Parameter add = 2b’00, sub = 3b’111; GATE (drive_strength)#(delays) Parameter n = 4; Tên từ khóa cổng _tên (output, input_1, input_2, , input_N); Parameter [3:0] par_2 = 4b’1010; Delay: #( lên, xuống) hoặc #lên_và_xuống hoặc #( lên_và_xuống) 2. Ví dụ reg [n-1:0] harry; /* một thanh ghi 4 bít mà độ rộng được đặt bởi And c1 (o, a, b, c. d); // có 4 đầu vào cổng And gọi là c1 tham số n ở trên */. c2 (p, f, g); // và 2 đầu vào cổng and gọi là c2 Or #(4,3) ig ( o, b, c); // cổng Or được gọi là ig, rise time = 4, fall time = 3 always @(x) Xor #(5) xor1 (a, b, c); // sau 5 đơn và thời gian thì a = b xor c y = {{(add - sub) {x}}} II. Cổng buf, not if (x) begin Các cổng này thực thi đệm và đảo theo theo thứ tự định sẳn. Chúng state = par_2[1]; có một đầu vào, hai hay nhiều đầu ra. Cú pháp cụ thể biểu diễn xem ở bên else dưới; từ khoá buf, not. state =par_2[2]; 1. Cú pháp end. Tên từ khóa cổng _tên (output_1, output_2, , output_N, input); 2. Ví dụ Not #(5) not_1( a,c); // sau 5 đơn và thời gian thì a = đảo c Buf c1 (o, p, q, r, in); // bộ đệm 5 đầu ra và 2 đầu ra c2 (p, f, g);
  3. 1. Toán tử Toán tử Tên > (dịch phải). [ ] Chọn bit, chọn phần 2. Ví dụ: ( ) Phần trong ngoặc đơn assign c = a > Dịch trái, phải. Wire [1:0] a, b; Wire [2:0] x; , >= Dấu so sánh. Biến Reg và wire được lấy bằng Wire [3:0] y, Z; những số dương. Assign x = {1’b0, a}; // x[2] = 0, x[1] = a[1], x[0] = a[0]. = =, != Bằng và không bằng trong toán tử logic. Assign y = {a, b}; // y[3]= a[1], y[2] = a[0], y[1] = b[1], y[0] = b[0]. & Bit_wire AND, and tất cả các bit với nhau. ^, ~^ Bit_wire XOR, Bit_wire XNOR. VIII. Toán tử thứ bản | Bit_wire OR. Tạo ra nhiều bản sao của một mục chọn. &&, || Toán tử logic AND, OR. 1. Toán tử: ?: x = ( điều kiện ) T:F {n{ mục chọn }} n nhóm thứ bản trong một mục chọn. 2. Ví dụ: Wire [1:0] a, b; Wire [3:0] x; Assign x = {2{1’b0},a}; // x= {0, 0, a}. IX. Toán tử điều kiện Giống như C/C++. Chúng định giá một trong hai biểu thức cơ bản trong một điều kiện. Nó sẽ tổng hợp thành bộ đa cộng (MUX). 1. Toán tử : (điều kiện)? kết quả khi điều kiện đúng : kết quả khi điều kiện sai. 2. Ví dụ: assign a = (g) ? x : y; Assign a = ( inc = =2) ? a+1: a-1; X. Thứ tự toán tử Những toán tử trong mức giống nhau định giá từ trái sang phải
  4. Chương VII - MODULES 2. Ví dụ: I. Khai báo modules: Wire [ 1:0 ] a = 2’b 01; Một module là bản thiết kế chủ yếu tồn tại trong Verilog. Dòng đầu Assign b = c &d; tiên của khai báo module chỉ rõ danh sách tên và port (các đối số). Các Assign d = x | y; dòng kế tiếp chỉ rõ dạng I/O (input/output, hoặc inout) và chiều rộng của III. Module instantiations: mỗi port. Mặc định độ rộng port là 1 bit. Sau đó, các biến port phải được Các khai báo module phải theo mẫu từ các đối tượng thực tế khai báo wire, wand, , reg (mặc định là wire). Các đầu vào là dạng wire (instantiation). Các module đơn bên trong các module khác, và mỗi dẫn khi dữ liệu được chốt bên ngoài module. Các đầu ra là dạng reg nếu các chứng tạo một đối tượng độc nhất từ khuôn mẫu. Ngoại trừ đó là module t/hiệu của chúng được chứa trong khối always hoặc initial. mức trên là những dẫn chứng từ chính chúng. 1. Cú pháp: Các port của module ví dụ phải thỏa những định nghĩa trong khuôn Module tên module (danh sách port); mẫu. Đây là mặt lý thuyết: bằng tên, sử dụng dấu chấm(.) ”.tên port khuôn Input [msb:lsb] danh sách port đầu vào; mẫu (tên của wire kết nối đến port)”. Bằng và trí, đặt những port ở những Output [msb:lsb] danh sách port đầu ra; và trí giống nhau trong danh sách port của cả khuôn mẫu lẫn instance. Inout [ msb:lsb ] danh sách port vào_ ra; 1. Cú pháp: các lệnh Tên instance1 (danh sách kết nối port ); endmodule Tên instance2(danh sách kết nối port); 2. Ví dụ: Module add_sub(add, in1, in2, out); 2. Ví dụ: Wire, reg, và tham số: // định nghĩa module Input[7:0 ] in1, in2; module and4(a,b,c); Wire in1, in2; input [3:0]a,b; Output [7:0] out; output [3:0]c; Reg out; assign c = a&b; các lệnh khác endmodule Endmodule // module instantiations II. Chỉ định liên tiếp: wire [3:0] in1, in2; Các chỉ định liên tiếp được dùng để gán một giá trị lên trên một wire wire [3:0] o1, o2; trong một module; bên ngoài khối always hoặc khối initial. Các chỉ định // đặt và trí liên tiếp được thực hiện với một lệnh gán (assign) rõ ràng hoặc bằng sự chỉ and4 C1(in1, in2,o1); định một giá trị đến một wire trong lúc khai báo. Lưu ý, các lệnh chỉ định // tên liên tiếp thì tồn tại và được chạy liên tục trong suốt quá trình mô phỏng. and4 C2(.c(o2), .a(in1), .b(in2)); Thứ tự các lệnh gán không quan trọng. Mọi thayđổi bên phảicủa bất cứđầuvàosẽ lập tức thayđổi bên trái của cácđầura. 1. Cú pháp: Wire biến wire = giá tr?; Assign biến wire = biểu thức;
  5. 1. Cú pháp: Begin For (biến đếm = giá trị 1; biến đếm / >= giá trị 2; các lệnh biến đếm = biến đếm +/- giá tr?) end begin VIII. Case lệnh Lệnh case cho phép lựa chọn trường hợp. Các lệng trong khối default thực end thi khi không có trường hợp lựa chọn so sánh giống nhau. Nếu không có sự 2. Ví dụ: so sánh, bao gồm cả default, là đúng, sự tổng hợp sẽ tạo ra chốt không For (j = 0; j<=7; j = j+1) mong muốn. Begin 1. Cú pháp: c[j] = a[j] & b[j]; Case (biểu thức) d[j] = a[j] | b[j]; Case 1: end Begin VI. Vòng lặp while các lệnh Vòng lặp while thực hiện nhiều lần một lệnh hoặc khối lệnh cho đến khi end biểu thức trong lệnh while định giá là sai. Case 2: 1. Cú pháp: Begin While (biểu thức) các lệnh Begin end các lệnh Case 3: end Begin 2. Ví dụ: các lệnh While (!overflow) end @(posedge clk); a = a +1; default: end begin VII. Khối lệnh if else if else các lệnh Thực hiện một lệnh hoặc một khối lệnh phụ thuộc vào kết quả của end biểu thức theo sau mệnh đề if. endcase Cú pháp 2. Ví dụ: If (biểu thức) Case (alu_clk) Begin 2’b00: aluout = a + b; các lệnh 2’b01: aluout = a - b; end 2’b10: aluout = a & b; else if (biểu thức) default: Begin aluout = 1’bx; các lệnh endcase end else
  6. 2. Ví dụ: {func, opr2, opr1}= decode_add (intruction); Module simple_processor (instruction, outp); if (func= =1) Input [31:0] instruction; outp = opr1+ opr2; Output [7:0] outp; else Reg [7:0] outp;// có thể được gán trong khối always. outp = opr1 – opr2; Reg func; end Reg [7:0] opr1, opr2; endmodule Function[16:0] decode add(instr) Input [31:0] instr; Chương XI Reg add_func; CHỨC NĂNG LINH KIỆN Reg [7:0] opcode, opr1, opr2; Chốt dữ liệu (latches): được suy nếu một biến, một trong các bit Begin không được gán trong các nhánh của một lệnh if. Chốt dữ liệu cũng được Opcode = instr[31:24]; suy ra từ lệnh case nếu một biến được gán chỉ trong một vài nhánh. Opr1 = instr[7:0]; Cú pháp: Case (opcode) If else if else và case. 8’b 10001000: I. Thanh ghi Edge_triggered, flip_flop, bộ đếm: begin Một thanh ghi (flip_flop) được suy luận bằng việc dùng xung kích add_func = 1; cạnh lên hoặc xuống trong danh sách sự kiện của lệnh khối always. opr2 = instr[15:8]; Cú pháp: end Always @(posedge clk or posedge reset1 or nesedge reset2) 8’b 10001001: Begin begin If (reset1) begin add_func = 0; Các chỉ định reset opr2 = instr[15:8]; end end else if (reset2) begin 8’b 10001010: begin Các chỉ định reset add_func = 1; End opr2 = 8’b 00000001; Else begin end Các chỉ định reset default: begin End add_func = 0; opr2 = 8’b00000001; II. Bộ đa cộng: end Được suy ra bởi việc gán một biến mà giá trị mỗi biến khác nhau endcase trong mỗi nhánh của lệnh if hoặc case. Có thể tránh các chỉ định và mọi decode_add = add_func, opr2, opr1 ; nhánh có thể tồn tại bằng việc sử dụng ngoài những nhánh mặc định. Chú ý end rằng chốt sẽ được tạo ra nếu một biến không được gán cho các điều kiện endfunction nhánh có thể tồn tại. always @(intruction) begin
  7. output [3:0]sum_out; wire en; input [3:0]ina, inb; output carry_out; always @(w or en) input carry_in; begin wire carry_out, carry_in; if(en==1'b1) wire[3:0] sum_out, ina, inb; begin assign case(w) { carry_out, sum_out } = ina + inb + carry_in; 2'b00: y<=4'b1000; 2'b01: y<=4'b0100; Endmodule 2'b10: y<=4'b0010; default:y<=4'b0001; b. Mô phỏng endcase end else y<= 4'b0000; end endmodule b. Mô phỏng 3. Ví dụ 3: a. Chương trình giải mã 2 sang 4 module dec2to4 (w, en, y); input [1:0] w; input en; output[3:0] y; wire[1:0]w; reg[3:0]y;
  8. 7. Ví dụ 7: wire [3:0] bcd; a. Chương trình giảm từ 9 xuống 0, hiển thì ra led 7 đoạn reg [7:0] led; module bcd (clock, rst, s1, led, digit1); input clock, s1, rst; always @(bcd) output [7:0] led; output digit1; begin case(bcd) reg [7:0] led; 4'b0000: led = 8'b00000011; reg [3:0] bcd; 4'b0001: led = 8'b10011111; wire digit1; 4'b0010: led = 8'b00100101; assign digit1 = 1'b1; 4'b0011: led = 8'b00001101; 4'b0100: led = 8'b10011001; always @(posedge clock ) 4'b0101: led = 8'b01001001; begin 4'b0110: led = 8'b01000001; if (rst == 1'b1) bcd <= 4'b1001; 4'b0111: led = 8'b00011111; else if (s1 == 1'b1) bcd <= bcd - 1'b1; 4'b1000: led = 8'b00000001; if (bcd == 4'b0) bcd <= 4'b1001; 4'b1001: led = 8'b00001001; end default: led = 8'b00000000; always @(posedge clock) endcase begin case(bcd) end 4'b0000: led = 8'b11111100; 4'b0001: led = 8'b01100000; endmodule 4'b0010: led = 8'b11011010; 4'b0011: led = 8'b11110010; b. Mô phỏng 4'b0100: led = 8'b01100110; 4'b0101: led = 8'b10110110; 4'b0110: led = 8'b10111110; 4'b0111: led = 8'b11100000; 4'b1000: led = 8'b11111110; 4'b1001: led = 8'b11100110; default: led = 8'b11111111; endcase end endmodule