Język HDL - VERLOG Hardware Description Language (Syntetyzowalna warstwa języka) RUS RUS
Język VERLOG w praktyce RUS RUS
VERLOG Specyfikacja układów kombinacyjnych RUS RUS
Operator warunkowy Conditional_expression? rue_ expression : false_ expression A = (B < C)? (D + 5) : (D + 2) module mux2to1 (w0, w1, s, f); input w0, w1, s; output f; assign f = s? w1 : w0; // przypisanie ciągłe Rys 6.27. Multiplekser 2-do-1 opisany operatorem warunkowym. RUS 5 4
Operator warunkowy module mux2to1 (w0, w1, s, f); input w0, w1, s; output f; reg f; always @(w0 or w1 or s) f = s? w1 : w0; // instrukcja proceduralna Rys 6.28. Multiplekser 2-do-1 inny opis z użyciem operatora warunkowego RUS 5 5
Operator warunkowy module mux4to1 (w0, w1, w2, w3, S, f); input w0, w1, w2, w3; input [1:0] S; output f; assign f = S[1]? (S[0]? w3 : w2) : (S[0]? w1 : w0); Rys 6.29. Multiplekser 4-do-1 z użyciem operatora warunkowego RUS 5 6
nstrukcja F-ELSE if (wyrażenie1) begin dyrektywa; // wielokrotna dyrektywa - w bloku begin-end end else if (wyrażenie2) // else if i else są opcjonalne begin dyrektywa; end else begin dyrektywa; end Rys. A.8. Budowa instrukcji if-else RUS 5 7
nstrukcja F-ELSE module mux2to1 (w0, w1, s, f); input w0, w1, s; output f; reg f; always @(w0 or w1 or s) if (s==0) f = w0; else f = w1; Rys. 6.30. Multiplekser 2-do-1 przy użyciu instrukcji if-else. RUS 5 8
nstrukcja F-ELSE module mux4to1 (w0, w1, w2, w3, S, f); input w0, w1, w2, w3; input [1:0] S; output f; reg f; always @(w0 or w1 or w2 or w3 or S) if (S == 2'b00) f = w0; else if (S == 2'b01) f = w1; else if (S == 2'b10) f = w2; else if (S == 2'b11) f = w3; Rys. 6.31. Multiplekser 4-do-1 przy użyciu instrukcji if-else. RUS 5 9
nstrukcja F-ELSE module mux4to1 (, S, f); input [0:3] ; input [1:0] S; output f; reg f; always @( or S) if (S == 0) f = [0]; else if (S == 1) f = [1]; else if (S == 2) f = [2]; else if (S == 3) f = [3]; Rys. 6.32. Alternatywna specyfikacja multipleksera 4-do-1 przy użyciu instrukcji if-else. RUS 5 10
nstrukcja F-ELSE s 0 s 1 w 0 w 3 w 4 w 7 w 8 s 2 s 3 M[0] M[1] M[2] M[3] f w 11 w 12 w 15 Rys. 6.32. Schemat multipleksera 16-do-1 RUS 5 11
nstrukcja F-ELSE module mux16to1 (, S16, f); input [0:15] ; input [3:0] S16; output f; wire [0:3] M; // module mux4to1 w tym samym pliku! mux4to1 Mux1 ([0:3], S16[1:0], M[0]); mux4to1 Mux2 ([4:7], S16[1:0], M[1]); mux4to1 Mux3 ([8:11], S16[1:0], M[2]); mux4to1 Mux4 ([12:15], S16[1:0], M[3]); mux4to1 Mux5 (M[0:3], S16[3:2], f); Rys. 6.32. Hierachiczna specyfikacja multipleksera 16-do-1 RUS 5 12
nstrukcja F-ELSE Szczególny przypadek instrukcji if-else: amięć niejawna (implied) istota opisu układów sekwencyjnych always @(w0 or w1 or s) begin if (s = = 1) f = w1; // jeśli dla s = 0 f nie jest określona end to zapamiętana zostaje ostatnia wartość RUS 5 13
nstrukcja CASE case (wyrażenie) // wyrażenie sterujące alternatywa1: begin dyrektywa; end alternatywa2: begin dyrektywa; end [default : begin dyrektywa; end] endcase Rys. A.10. Budowa instrukcji case RUS 5 14
nstrukcja CASE module mux4to1 (, S, f); input [0:3] ; input [1:0] S; output f; reg f; always @( or S) case (S) 0: f = [0]; 1: f = [1]; 2: f = [2]; 3: f = [3]; endcase Rys. 6.31. Multiplekser 4-do-1 opisany przy użyciu instrukcji case. RUS 5 15
nstrukcja CASE En w 1 w 0 y 0 y 1 y 2 y 3 1 1 1 1 0 0 0 1 1 x 0 1 0 1 x 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 w 0 En y 0 w 1 y 1 y 2 y 3 (a) ablica prawdy (b) Symbol graficzny Rys. 6.16. Dekoder 2-do-4. RUS 5 16
module dec2to4 (, Y, En); input [1:0] ; input En; output [0:3] Y; reg [0:3] Y; nstrukcja CASE always @( or En) case ({En, }) 3'b100: Y = 4'b1000; 3'b101: Y = 4'b0100; 3'b110: Y = 4'b0010; 3'b111: Y = 4'b0001; default: Y = 4'b0000; // dla En = 0 wartość domyślna Y = 4'b0000 endcase Rys. 6.35. Opis dekodera 2-do-4 (rys. 6.16) przy użyciu instrukcji case. RUS 5 17
nstrukcja CASE module dec2to4 (, Y, En); input [1:0] ; input En; output [0:3] Y; reg [0:3] Y; always @( or En) begin if (En == 0) Y = 4'b0000; else case () 0: Y = 4'b1000; 1: Y = 4'b0100; 2: Y = 4'b0010; 3: Y = 4'b0001; endcase end Rys. 6.3. Alternatywny opis dekodera 2-do-4 przy użyciu instrukcji case. RUS 5 18
nstrukcja CASE w 0 w 0 y 0 y 0 w 1 w 1 y 1 y 1 M[0] y 2 En y 3 y 2 y 3 w 2 w 3 En w 0 y 0 w 1 y 1 y 2 En y 3 M[1] M[2] w 0 w 1 y 1 y 2 En y 3 w 0 y 0 y 0 w 1 y 1 y 2 En y 3 y 4 y 5 y 6 y 7 y 8 y 9 y 10 y 11 Rys. 6.18. Dekoder 4-to-16 M[3] w 0 y 0 w 1 y 1 y 2 En y 3 y 12 y 13 y 14 y 15 RUS 5 19
module dec4to16 (, Y, En); input [3:0] ; input En; output [0:15] Y; wire [0:3] M; nstrukcja CASE dec2to4 Dec1 ([3:2], M[0:3], En); dec2to4 Dec2 ([1:0], Y[0:3], M[0]); dec2to4 Dec3 ([1:0], Y[4:7], M[1]); dec2to4 Dec4 ([1:0], Y[8:11], M[2]); dec2to4 Dec5 ([1:0], Y[12:15], M[3]); Rys. 6.37. Hierachiczna specyfikacja dekodera 4-na-16 RUS 5 20
nstrukcja CASE module seg7 (bcd, leds); input [3:0] bcd; output [1:7] leds; reg [1:7] leds; Rys. 6.18. Dekoder kodu BCD na 7-segmentowy always @(bcd) case (bcd) //abcdefg 0: leds = 7'b1111110; 1: leds = 7'b0110000; 2: leds = 7'b1101101; 3: leds = 7'b1111001; 4: leds = 7'b0110011; 5: leds = 7'b1011011; 6: leds = 7'b1011111; 7: leds = 7'b1110000; 8: leds = 7'b1111111; 9: leds = 7'b1111011; default: leds = 7'bx; endcase RUS 5 21
nstrukcja CASE // ALU 74381 module alu(s, A, B, F); input [2:0] s; input [3:0] A, B; output [3:0] F; reg [3:0] F; Rys. 6.39. Specyfikacja jednostki ALU 74381 always @(s or A or B) case (s) 0: F = 4'b0000; 1: F = B - A; 2: F = A - B; 3: F = A + B; 4: F = A ^ B; 5: F = A B; 6: F = A & B; 7: F = 4'b1111; endcase RUS 5 22
nstrukcja Casex traktuje wszystkie wartości z i x jako don t cares module priority (, Y, z); input [3:0] ; output [1:0] Y; output z; reg [1:0] Y; reg z; Rys. 6. 41. Specyfikacja kodera priorytetu always @() begin z = 1; // oznacza niezerowe wejście [i] casex() 4'b1xxx: Y = 3; 4'b01xx: Y = 2; 4'b001x: Y = 1; 4'b0001: Y = 0; default: begin z = 0; Y = 2'bx; end endcase end RUS 5 23
nstrukcje pętli w Verilogu: for, while, repeat i forever nstrukcja pętli for for (początkowy_ indeks; końcowy_indeks; inkrementacja) begin end dyrektywa; // oddzielenie begin-end gdy jest kilka dyrektyw nstrukcja pętli for nie określa zmian podczas kolejnych iteracji pętli, jak w językach programowania, ale może definiować różne podukłady np. kolejne stopnie n-bitowego sumatora RUS 5 24
nstrukcje pętli FOR module dec2to4 (, Y, En); input [1:0] ; input En; output [0:3] Y; reg [0:3] Y; integer k; always @( or En) for (k = 0; k <= 3; k = k+1) if (( == k) && (En == 1)) Y[k] = 1; else Y[k] = 0; Rys. 6. 42. Specyfikacja dekodera 2-na-4 przy użyciu pętli for RUS 5 25
nstrukcje pętli FOR module priority (, Y, z); input [3:0] ; output [1:0] Y; output z; reg [1:0] Y; reg z; integer k; always @() begin Y = 2'bx; z = 0; for (k = 0; k < 4; k = k+1) if ([k]) // badanie warunku od pozycji najmniej znaczącej begin Y = k; // kolejna iteracja zwiększa priorytet! z = 1; end end Rys. 6. 43. Specyfikacja kodera priorytetu przy użyciu pętli for RUS 5 26
Operatory w VERLOGu Operatory bitowe ektory: A[2:0], B[2:0], C[2:0] Skalary: f, w Operator uzupełnienia _ C = A c 2 = a 2, c 1 = a 1, c 0 = a 0 a i, c i - bity wektorów A i C RUS 5 27
Operatory w VERLOGu Operatory bitowe ektory: A[2:0], B[2:0], C[2:0] Skalary: f, w Operator & -AND na bitach C = A & B c 2 = a 2 b 2, c 1 = a 1 b 1, c 0 = a 0 b 0 RUS 5 28
Operatory w VERLOGu Operatory bitowe ektory: A[2:0], B[2:0], C[2:0] Skalary: f, w Operator -OR na bitach C = A B c 2 = a 2 + b 2, c 1 = a 1 + b 1, c 0 = a 0 + b 0 RUS 5 29
Operatory w VERLOGu Kategoria rzykłady Liczba bitów = długość Bitowe ~A, +A, A L(A) A & B, A B, A ~ ^ B, A ^ ~ B MAX (L(A), L(B)) Logiczne!A, A && B, A B 1 bit Redukcji &A, ~&A, A, ~ A, ^ ~ A, ~ ^ A 1 bit Relacyjne A = = B, A!= B, A > B, A < B 1 bit A >= B, A <= B A = = = B, A!= = B Arytmetyczne A + B, A B, A * B, A / B MAX (L(A), L(B)) A % B rzesunięcia A << B, A >> B L(A) Konkatenacji {A,, B} L(A) +... + L(B) Replikacji {B{A}} B * L(A) arunku A? B : C MAX (L(B), L(C)) RUS 5 30
Operatory w VERLOGu module compare (A, B, AeqB, AgtB, AltB); input [3:0] A, B; output AeqB, AgtB, AltB; reg AeqB, AgtB, AltB; always @(A or B) begin AeqB = 0; AgtB = 0; AltB = 0; if (A == B) // operator relacyjny AeqB = 1; else if (A > B) // operator relacyjny AgtB = 1; else AltB = 1; end Rys. 6. 43. Specyfikacja 4-bitowego komparatora RUS 5 31
VERLOG elementy pamięciowe module D_latch (D, Clk, Q); input D, Clk; output Q; reg Q; always @(D or Clk) if (Clk) //zależność od wartości Q = D; //podtrzymanie stanu Rys. 7.35. Opis przerzutnika typu D-latch RUS 5 32
VERLOG elementy pamięciowe module flipflop (D, Clock, Q); input D, Clock; output Q; reg Q; always @(posedge Clock) //zależność od zmiany! Q = D; // przypisanie tylko w tej chwili Rys. 7.36. Opis przerzutnika typu D-flip-flop, synchronizowanego dodatnim zboczem RUS 5 33
rzypisania typu blocking i non-blocking module example7_3 (D, Clock, Q1, Q2); input D, Clock; output Q1, Q2; reg Q1, Q2; always @(posedge Clock) begin Q1 = D; // przypisania blocking (=) są wykonywane Q2 = Q1; // sekwencyjnie end Endmodule Rys. 7.37. Niepoprawny opis łańcucha przerzutników RUS 5 34
rzypisania typu blocking i non-blocking D D Q Q 1 Clock Q D Q Q 2 Q Rys. 7.38. lustracja do przykładu z rys. 7.37 RUS 5 35
VERLOG elementy pamięciowe module example7_4 (D, Clock, Q1, Q2); input D, Clock; output Q1, Q2; reg Q1, Q2; always @(posedge Clock) begin Q1 <= D; // przypisanie non-blocking (<=) Q2 <= Q1; // równoczesne (współbieżne) end Rys. 7.39. oprawny opis łańcucha przerzutników RUS 5 36
VERLOG elementy pamięciowe module example7_5 (x1, x2, x3, Clock, f, g); input x1, x2, x3, Clock; output f, g; reg f, g; always @(posedge Clock) begin f = x1 & x2; g = f x3; end Rys. 7.41. rzykład użycia przypisania typu blocking RUS 5 37
VERLOG elementy pamięciowe x 3 x 1 D Q g x 2 Q D Q f Clock Q Rys. 7.42. Schemat układu z rys. 7.41 RUS 5 38
VERLOG elementy pamięciowe module example7_6 (x1, x2, x3, Clock, f, g); input x1, x2, x3, Clock; output f, g; reg f, g; always @(posedge Clock) begin f <= x1 & x2; // kolejność przypisań nie ma znaczenia! g <= f x3; end Rys. 7.43. rzykład - użycie przypisania typu non-blocking zamiast blocking zmienia realizowaną funkcję! RUS 5 39
VERLOG elementy pamięciowe x 3 D Q g Q x 1 x 2 D Q f Clock Q Rys. 7.44. Schemat układ z rys.7.43 RUS 5 40
VERLOG elementy pamięciowe module flipflop (D, Clock, Resetn, Q); input D, Clock, Resetn; output Q; reg Q; always @(negedge Resetn or posedge Clock) if (!Resetn) Q <= 0; else Q <= D; Rys. 7.45. Opis przerzutnika D-flip-flop z asynchronicznym resetem RUS 5 41
VERLOG elementy pamięciowe module flipflop (D, Clock, Resetn, Q); input D, Clock, Resetn; output Q; reg Q; always @(posedge Clock) if (!Resetn) Q <= 0; else Q <= D; Rys. 7.46. Opis przerzutnika D-flip-flop z synchronicznym resetem RUS 5 42
VERLOG rejestry i liczniki module regn (D, Clock, Resetn, Q); parameter n = 16; input [n-1:0] D; input Clock, Resetn; output [n-1:0] Q; reg [n-1:0] Q; // n - niezależnych przerzutników always @(negedge Resetn or posedge Clock) if (!Resetn) Q <= 0; else Q <= D; Rys. 7.51. Opis n-bitowego rejestru z asynchronicznym resetem RUS 5 43
VERLOG rejestry i liczniki module muxdff (D0, D1, Sel, Clock, Q); input D0, D1, Sel, Clock; output Q; reg Q; always @(posedge Clock) if (!Sel) Q <= D0; else Q <= D1; Rys. 7.52. Opis przerzutnika D flip-flop z multiplekserem 2-do-1 na wejściu D RUS 5 44
VERLOG rejestry i liczniki module shift4 (R, L, w, Clock, Q); input [3:0] R; input L, w, Clock; output [3:0] Q; wire [3:0] Q; muxdff Stage3 (w, R[3], L, Clock, Q[3]); muxdff Stage2 (Q[3], R[2], L, Clock, Q[2]); muxdff Stage1 (Q[2], R[1], L, Clock, Q[1]); muxdff Stage0 (Q[1], R[0], L, Clock, Q[0]); Rys. 7.53. Opis hierarchiczny 4-bitowego rejestru przesuwającego z wykorzystaniem muxdff RUS 5 45
VERLOG rejestry i liczniki module shift4 (R, L, w, Clock, Q); input [3:0] R; input L, w, Clock; output [3:0] Q; reg [3:0] Q; always @(posedge Clock) if (L) Q <= R; else begin Q[0] <= Q[1]; Q[1] <= Q[2]; Q[2] <= Q[3]; Q[3] <= w; end Rys. 7.54. Alternatywny opis 4-bitowego rejestru z przypisaniem non-blocking RUS 5 46
VERLOG rejestry i liczniki module shiftn (R, L, w, Clock, Q); parameter n = 16; input [n-1:0] R; input L, w, Clock; output [n-1:0] Q; reg [n-1:0] Q; integer k; always @(posedge Clock) if (L) Q <= R; else begin for (k = 0; k < n-1; k = k+1) Q[k] <= Q[k+1]; Q[n-1] <= w; end Rys. 7.55. Opis n-bitowego rejestru przesuwającego z pętlą for RUS 5 47
VERLOG rejestry i liczniki module upcount (Resetn, Clock, E, Q); input Resetn, Clock, E; output [3:0] Q; reg [3:0] Q; always @(negedge Resetn or posedge Clock) if (!Resetn) Q <= 0; else if (E) Q <= Q + 1; Rys. 7.56. Opis 4-bitowego licznika zliczającego w górę RUS 5 48
VERLOG rejestry i liczniki module upcount (R, Resetn, Clock, E, L, Q); input [3:0] R; input Resetn, Clock, E, L; output [3:0] Q; reg [3:0] Q; always @(negedge Resetn or posedge Clock) if (!Resetn) Q <= 0; else if (L) Q <= R; else if (E) Q <= Q + 1; Rys. 7.57. Opis 4-bitowego licznika zliczającego w górę z wpisem równoległym RUS 5 49
VERLOG rejestry i liczniki module downcount (R, Clock, E, L, Q); parameter n = 8; input [n-1:0] R; input Clock, L, E; output [n-1:0] Q; reg [n-1:0] Q; always @(posedge Clock) if (L) Q <= R; else if (E) Q <= Q - 1; Rys. 7.58. Opis 4-bitowego licznika zliczającego w dół z wpisem równoległym RUS 5 50
VERLOG rejestry i liczniki module updowncount (R, Clock, L, E, up_down, Q); parameter n = 8; input [n-1:0] R; input Clock, L, E, up_down; output [n-1:0] Q; reg [n-1:0] Q; integer direction; always @(posedge Clock) begin if (up_down) direction = 1; else direction = - -1; if (L) Rys. 7.59. Opis n-bitowego licznika Q <= R; zliczającego w górę/dół else if (E) Q <= Q + direction; end RUS 5 51