Języki Opisu Sprzętu Prowadzący: dr inż. Andrzej Skoczeń Współrzędne: D-10 222, tel. w. 28-72, e-mail: skoczen@fis.agh.edu.pl Wprowadzenie do Veriloga Przypisania proceduralne (c. d.) Wykład 4 2017 8 listopad 2017 Operatory w Verilogu Logika iteracyjna a automat skończony Struktura automatu skończonego (FSM) Przykład ręcznego projektowania automatu skończonego: detektor sekwencji 101 Metody kodowania w Verilogu automatu skończonego a wyniki z syntezy http://www.fis.agh.edu.pl/~skoczen/hdl AGH WFiIS Informatyka Stosowana Języki Opisu Sprzętu 1
reg x, y,z; initial begin x = #5 1'b0; //x otrzymuje wartość 0 w chwili 5 y = #3 1'b1; //y otrzymuje wartość 1 w chwili 8 z = #6 1'b0; //z otrzymuje wartość 0 w chwili 14 end x y z Incisive, Cadence AGH, WFiIS, HDL 2
reg x, y,z; initial begin x <= #5 1'b0; //x otrzymuje wartość 0 w chwili 5 y <= #3 1'b1; //y otrzymuje wartość 1 w chwili 3 z <= #6 1'b0; //z otrzymuje wartość 0 w chwili 6 end x y z Incisive, Cadence AGH, WFiIS, HDL 3
reg a, b,c, d; initial begin a <= #5 1'b0; //a otrzymuje wartość 0 w chwili 5 b = #3 1'b1; //b otrzymuje wartość 1 w chwili 3 c <= #6 1'b0; //c otrzymuje wartość 0 w chwili 9 d = #7 1'b0; //d otrzymuje wartość 0 w chwili 10 end a b c d Incisive, Cadence AGH, WFiIS, HDL 4
reg a, b,c, d; initial begin a = #5 1'b0; //a otrzymuje wartość 0 w chwili 5 b <= #3 1'b1; //b otrzymuje wartość 1 w chwili 8 c = #6 1'b0; //c otrzymuje wartość 0 w chwili 11 d <= #7 1'b0; //d otrzymuje wartość 0 w chwili 18 end a b c d Incisive, Cadence AGH, WFiIS, HDL 5
Nieblokujące przypisanie proceduralne (c.d.) Stosowane są jako metoda modelowania równoczesnego transferu danych kilkoma różnymi drogami zachodzącego w momencie wystąpienia pewnego zdarzenia. always @ (posedge clock) begin reg1 <= #1 in1; reg2 <= @(negedge clock) in2 ^ in3; reg3 <= #1 reg1; //stara wartość reg1 end Przy każdym narastającym zboczu zegara zachodzi następująca sekwencja zdarzeń: Odczytane zostają wartości zmiennych in1, in2, in3, reg1 występujących po stronie prawej przypisań. Wyrażenia występujące z prawej strony są obliczane, a ich wyniki zapamiętywane w tymczasowych zmiennych symulatora. Operacje wpisania uzyskanych wyników do strony lewej są umieszczane w kolejce wykonania pod czasami określonymi w instrukcjach. Tzn. zapis zmiennych reg1 i reg3 jest zaplanowany na chwilę czasu 1 po narastającym zboczu zegara, a zapis zmiennej reg2 odbędzie się w chwili wystąpienia opadającego zbocza zegara. Operacje przypisania są wykonywane w przewidzianym czasie. Faktyczna kolejność przestaje być istotna gdyż przypisywane wartości są już obliczone i czekają. W ten sposób wiadomo, że w reg3 znajdzie się stara wartość reg1 nawet jeśli przypisanie do reg1 nastąpi wcześniej. AGH, WFiIS, HDL 6
Nieblokujące przypisanie proceduralne (c.d.) Dwa równoczesne bloki always z przypisaniami sekwencyjnymi always @(posedge clock) a = b; always @(posedge clock) b = a; Występuje hazard. Nie wiemy, która z operacji zostanie wykonana wcześniej. Zawartości rejestrów nie zostaną wymienione, ale w obydwu znajdzie się ta sama wartość tzn. początkowa wartość a lub b, zależnie od konkretnej implementacji Veriloga. AGH, WFiIS, HDL 7
Nieblokujące przypisanie proceduralne (c.d.) Dwa równoczesne bloki always z przypisaniami równoczesnymi always @(posedge clock) a <= b; always @(posedge clock) b <= a; Zawartości zmiennych a i b zostaną zamienione na każdym narastającym zboczu zegara, gdyż operacje są wykonywane z pośredniczeniem przez zmienne tymczasowe. To samo można osiągnąć inaczej, ale dłużej przy użyciu zmiennych tymczasowych. AGH, WFiIS, HDL 8
Nieblokujące przypisanie proceduralne (c.d.) Stosowanie przypisań nie blokujących wyklucza potrzebę używania zmiennych tymczasowych. always @(posedge clock) begin temp_a = a; temp_b = b; a = temp_b; b = temp_a; end Stosowanie przypisań równoczesnych jest rekomendowane gdyż zabezpiecza przed powstaniem hazardu tzn. rezultat nie zależy od kolejności wykonania operacji. Z drugiej strony przypisania równoczesne mogą spowodować spowolnienie symulacji i większe zużycie pamięci. AGH, WFiIS, HDL 9
Przypisania z opóźnieniami Pięć przypadków: always @* #d a = b; LHS Blocking Left Hand Side always @* a = #d b; RHS Blocking Right Hand Side always @* #d a <= b; LHS Nonblocking Left Hand Side always @* a <= #d b; RHS Nonblocking Right Hand Side assign #d a = b; Continuous AGH, WFiIS, HDL 10
Blocking assignment delay models module adder_lhs_b (input [3:0] a, b, input ci, output reg co, output reg [3:0] sum); always @* #12 {co, sum} = a + b + ci; LHS Blocking Assignment endmodule ISim, Xilinx WARNING:Xst:916 - adder_lhs_b.v" line 8: Delay is ignored for synthesis. Symulacja po syntezie będzie zupełnie odmienna. #12 a b ci sum co ISim, Xilinx Model błędny! Nie istnieje odpowiedni sprzęt. Opóźnienie #12 jest obliczane od pierwszej zmiany na wejściach, a wynik jest obliczany w oparciu o bieżące wartości sygnałów. AGH, WFiIS, HDL 11
LHS Blocking Assignment Rekomendacje do modelowania: Nie stawiaj opóźnień z lewej strony przypisania blokującego w modelach układów kombinacyjnych. To jest zły styl kodowania. Rekomendacje do modułów testujących: Używanie opóźnień z lewej strony przypisania blokującego w modułach testujących jest właściwe. To jest poprawny sposób modelowania odstępów czasowych pomiędzy kolejnymi zdarzeniami wymuszeń na wejściach testowanego modułu. AGH, WFiIS, HDL 12
Blocking assignment delay models RHS Blocking Assignment module adder_rhs_b (input [3:0] a, b, input ci, output reg co, output reg [3:0] sum); endmodule always @* {co, sum} = #12 a + b + ci; #12 a b ci sum co Model błędny! Nie istnieje odpowiedni sprzęt. Opóźnienie #12 jest obliczane od pierwszej zmiany na wejściach, a wynik jest obliczany w oparciu o stare wartości sygnałów. ISim, Xilinx AGH, WFiIS, HDL 13
RHS Blocking Assignment Rekomendacje do modelowania: Nie stawiaj opóźnień z prawej strony przypisania blokującego w modelach układów kombinacyjnych. To jest zły styl kodowania. Rekomendacje do modułów testujących: Nie stawiaj opóźnień z prawej strony przypisania blokującego w modułach testujących. Ogólna rekomendacja: Używanie opóźnień z prawej strony przypisania blokującego jest zarówno mylące jak i w złym stylu. Należy unikać! AGH, WFiIS, HDL 14
Nonblocking assignment delay models module adder_lhs_nb (input [3:0] a, b, input ci, output reg co, output reg [3:0] sum); endmodule always @* #12 {co, sum} <= a + b + ci; LHS Nonblocking Assignment #12 a b ci sum co Model błędny! Nie istnieje odpowiedni sprzęt. ISim, Xilinx Opóźnienie #12 jest obliczane od pierwszej zmiany na wejściach, a wynik jest obliczany w oparciu o bieżące wartości sygnałów. AGH, WFiIS, HDL 15
LHS Nonblocking Assignment Rekomendacje do modelowania: Nie stawiaj opóźnień z lewej strony przypisania nieblokującego w modelach układów kombinacyjnych. To jest zły styl kodowania. Rekomendacje do modułów testujących: Przypisania nieblokujące są mniej efektywne niż przypisania blokujące. Dlatego generalnie odradza się stosowania opóźnień po lewej stronie przypisań nieblokujących zarówno w modelach jak i modułów testujących. AGH, WFiIS, HDL 16
Nonblocking assignment delay models module adder_rhs_nb (input [3:0] a, b, input ci, output reg co, output reg [3:0] sum); endmodule always @* {co, sum} <= #12 a + b + ci; RHS Nonblocking Assignment #12 a b ci sum co Poprawne modelowanie logiki transportowej ISim, Xilinx AGH, WFiIS, HDL 17
RHS Nonblocking Assignment Rekomendacje do modelowania: Używaj opóźnień z prawej strony przypisania nieblokującego do modelowania cyfrowej linii opóźniającej. To jest dobry styl kodowania. Rekomendacje do modułów testujących: Ten styl jest często stosowany w modułach testujących kiedy wymuszenie musi być zaplanowane na przyszłych krawędziach zegara lub po ustalonym opóźnieniu, nie blokując przydziału kolejnych zdarzeń wymuszających w tym samym bloku proceduralnym. Ogólna rekomendacja: Stosuj opóźnienia z prawej strony przypisania nieblokującego tylko przy modelowaniu propagacji sygnałów wyjściowych o zachowaniu transportowym. Ten styl kodowania będzie dokładnie modelował linie opóźniające i logikę kombinacyjną z czysto transportowymi opóźnieniami. Jednak ten styl powoduje spowolnienie symulacji. AGH, WFiIS, HDL 18
Continuous assignment delay models module adder_lhs_cont (input [3:0] a, b, input ci, output reg co, output reg [3:0] sum); endmodule assign #12 {co, sum} = a + b + ci; LHS Continuous Assignment #12 a b ci sum co Poprawne modelowanie logiki inercyjnej ISim, Xilinx AGH, WFiIS, HDL 19
LHS Continuous Assignment Rekomendacje do modelowania: Używaj z prawej strony przypisania ciągłych z opóźnieniami do modelowania prostej logiki kombinacyjnej. To jest dobry styl kodowania do poprawnego modelowania logiki kombinacyjnej z opóźnieniem inercyjnym. Rekomendacje do modułów testujących: Ciągłe przypisania mogą być używane w dowolnym miejscu w modułach testujących, aby sterować wartościami wymuszeń na portach wejściowych i dwukierunkowych portach instancji modułów testowanych. Ogólna rekomendacja: Do modelowania złożonej logiki kombinacyjnej z użyciem konstrukcji typu casecasez-casex lub if-else należy zawsze używać bloków always bez opóźnień. Wyjścia z takich bloków mogą być następnie skierowane do przypisania ciągłych w celu zastosowania opóźnień do takich modeli. Taki styl kodowania poprawnie modeluje złożoną logikę kombinacyjną z opóźnieniem inercyjnym. AGH, WFiIS, HDL 20
Zestawienie rekomendacji stosowania przypisań z opóźnieniami RTL TB blocking LHS error correct blocking RHS error avoid nonblocking LHS error avoid nonblocking RHS transport correct continuous LHS inertial correct AGH, WFiIS, HDL 21
module blk (input clk, d, output reg [1:0] r); always @(posedge clk) begin r[0] = d; r[1] = r[0]; end endmodule Na każdym zboczu narastającym zegara wartość z wejścia d zostanie przypisana do obu bitów rejestru r. Jeśli d=1 b1 to początkowo niezainicjowany rejestr r=2 bxx zmieni wartość na r=2 b11. module NONblk (input clk, d, output reg [1:0] r); always @(posedge clk) begin r[0] <= d; r[1] <= r[0]; end endmodule Na każdym zboczu narastającym zegara wartości wejścia d i mniejznaczącego bitu rejestru r zostaną zapamiętane w zmiennych tymczasowych, a następnie przypisane. Jeśli d=1 b1 to początkowo niezainicjowany rejestr r=2 bxx na pierwszym narastającym zboczu zegara zmieni wartość na r=2 bx1., a na drugim na r=2 b11. AGH, WFiIS, HDL 22
module blk (input clk, d, output reg [1:0] r); always @(posedge clk) begin r[0] = d; r[1] = r[0]; end endmodule Incisive, Cadence r clk d Wynik syntezy: Encounter RTL Compiler, Cadence AGH, WFiIS, HDL 23
module NONblk (input clk, d, output reg [1:0] r); always @(posedge clk) begin r[0] <= d; r[1] <= r[0]; end endmodule r Incisive, Cadence r[1] r[0] clk Wynik syntezy: d AGH, WFiIS, HDL Encounter RTL Compiler, Cadence 24
Reguły stosowania przypisań blokujących i nieblokujących Podstawowe zasady syntezowalności kodu Zawsze używaj przypisań blokujących (=) w blokach always przeznaczonych do tworzenia układów kombinacyjnych, Zawsze używaj przypisań nieblokujących (<=) w blokach always przeznaczonych do tworzenia układów sekwencyjnych, Nie mieszaj obu typów przypisań w jednym bloku always, Nie wykonuj przypisań do tej samej zmiennej w dwóch różnych blokach always. AGH, WFiIS, HDL 25
Modelowanie za pomocą bloku always Modelowanie układów sekwencyjnych Na liście wrażliwości znajduje się aktywne zbocze sygnału zegarowego i ewentualnie aktywne zbocze asynchronicznego sygnału kasowania: always @(posedge clk, posedge rst) Zatrzaski Są sekwencyjne gdyż trudno nie przyznać, że są to elementy pamięciowe Są kombinacyjne, gdyż powstają przy błędnym modelowaniu układów kombinacyjnych Modelowanie układów kombinacyjnych Na liście wrażliwości znajdują się zmiany wartości wszystkich sygnałów występujących po stronie prawej przypisań w tym bloku: always @* AGH, WFiIS, HDL 26
Operatory arytmetyczne Operatory dwuargumentowe: (**) potęgowanie, (*) mnożenie, (/) dzielenie, (+) dodawanie, (-) odejmowanie, (%) modulo. Jeśli jakikolwiek bit argumentów ma wartość nieokreśloną x to cały wynik jest nieokreślony. Operatory jednoargumentowe (+) i (-) określają znak argumentu. reg [3:0] A, B; integer D, E; //A = 4 b0011; B = 4 b0100; D = 6; E = 4; A + B //wynik 4 b0111 D/E //wynik 1; obcina czesc ułamkową A * B //wynik 4 b1100 B A //wynik 4b 0001 Wynikiem operacji będzie real jeśli jeden z argumentów jest real. Jeśli obydwa argumenty są bez znaku to wynik także jest bez znaku. data flow level AGH, WFiIS, HDL 27
Operatory logiczne data flow level Operatory dwuargumentowe: ( ) logiczne-lub, (&&) logiczne-i. Operatory jednoargumentowe: (!) logiczne-nie. Wynikiem zawsze jest wartość jednobitowa: 0 fałsz, 1 prawda lub x nieokreślony. Wynik różny od zera jest traktowany jak prawda. //A = 3; B = 0; A && B //daje falsz A B //daje prawda!a //daje falsz!b //daje prawda //A = 2 b0x; B = 2 b10; A && B //daje x AGH, WFiIS, HDL 28
Operatory relacyjne data flow level (>) większy, (<) mniejszy, (>=) większy-lub-równy, (>=) mniejszy-lub-równy. Jeśli argument jest x lub z to wynik jest x. //A = 4; B = 3; X = 4 b1010; Y = 4 b1101; Z = 4 b1xxx; A <= B A > B Y >= X Y < Z //wynik 0-falsz //wynik 1-prawda //wynik 1-prawda //wynik x AGH, WFiIS, HDL 29
Operatory równości Operatory dwuargumentowe: (==) równość, (!=) nierówność oraz wersje z uwzględnieniem x i z (===) i (!==). Wynikiem zawsze jest wartość jednobitowa: 0 fałsz, 1 prawda, a wartość x nieokreślony może się pojawić tylko w przypadkach (==) i (!=). //A = 4; B = 3; //X = 4 b1010; Y = 4 b1101; //Z = 4 b1xxz; M = 4 b1xxz; N = 4 b1xxx; A == B A!= B X == Z Z === M Z === N M!== N //daje falsz //daje prawda //daje x //daje prawda //daje falsz //daje prawda data flow level Używać oszczędnie w zastosowaniu do syntezy: reg a; if (a == 1 b1)... ; //jest równoważne if(a)... ; AGH, WFiIS, HDL 30
Operatory bitowe Operatory dwuargumentowe: ( ) bitowe-lub, (&) bitowe-i, (^) bitowe-xor, (~^ lub ^~) bitowe-xnor. data flow level Operatory jednoargumentowe: (~) bitowe-nie. Jeśli argumenty są różnych rozmiarów to krótszy uzupełniany jest zerami z przodu. & 0 1 x 0 0 0 0 1 0 1 x x 0 x x 0 1 x 0 0 1 x 1 1 1 1 x x 1 x ^ 0 1 x 0 0 1 x 1 1 0 x x x x x ^~ 0 1 x 0 1 0 x 1 0 1 x x x x x //X = 4 b1010; Y = 4 b1101; z jest traktowane jak x. //Z = 4 b10x1; ~X //daje 4 b0101 X & Y //daje 4 b1000 X Y //daje 4 b1111 a X Y daje 1 b1 X ^ Y //bitowy xor daje 4 b0111 X ~^ Y //bitowy xnor daje 4 b1000 X & Z //daje 4 b10x0 ~ 0 1 1 0 x x AGH, WFiIS, HDL 31
Operatory redukcyjne Operatory jednoargumentowe : ( ) or, (&) and, (^) xor, (~ ) nor, (~&) nand, (~^ lub ^~) xnor. data flow level //X = 4 b1010; &X //1 & 0 & 1 & 0 daje 1 b0 X //1 0 1 0 daje 1 b1 ^X //1 ^ 0 ^ 1 ^ 0 daje 1 b0 AGH, WFiIS, HDL 32
Operatory przesunięć Operatory dwuargumentowe: (>>) w prawo, (<<) w lewo. data flow level działają na wektorach, przesuwają określoną w drugim argumencie ilość bitów, powstające miejsce zapełniają zawsze zerami (nie ma zawijania). //X = 4 b1100; Y = X >> 1; //daje 4 b0110 Y = X << 1; //daje 4 b1000 Y = X << 2; //daje 4 b0000 AGH, WFiIS, HDL 33
Operator dołączania Operatory wieloargumentowy: ({}) łączenie. Działa na argumentach o znanym rozmiarze. data flow level //A=1 b1, B=2 b00, C=2 b10, D=3 b110 reg [3:0] Y0; reg [10:0] Y1; reg [2:0] Y2; Y0 = {B,C}; //daje 4 b0010 Y1 = {A,B,C,D,3 b001}; //daje 11 b10010110001 Y2 = {A,B[0],C[1]}; //daje 3 b101 AGH, WFiIS, HDL 34
Operator powtarzania data flow level Polega na wielokrotnym łączeniu tyle razy ile określono w stałej replikacji {stala_repli{arg}} reg A; reg [1:0] B, C; reg [2:0] D; //A=1 b1; B=2 b00; C=2 b10; reg [3:0] Y0; reg [7:0] Y1; reg [9:0] Y2; Y0 = { 4{A} }; //daje 4 b1111 Y1 = { 4{A}, 2{B} }; //daje 8 b11110000 Y2 = { 4{A}, 2{B}, C}; //daje 10 b1111000010 AGH, WFiIS, HDL 35
Operator warunkowy Zastępuje instrukcję if, Dostarcza konstrukcji multipleksera 2 do 1: data flow level warunek? wyraz_prawda : wyraz_falsz //bufor trójstanowy trzy-bitowego wire [2:0] addr_bus, adrr_out; assign addr_bus = driver_enable? adrr_out : 3 bz; //2-do-1 mux assign out = control? in1 : in2; //zagniezdzanie assign out = (A==3)? (control?x:y) : (control?m:n); AGH, WFiIS, HDL 36
Charakteryzuje się: Układ synchroniczny jednym sygnałem zegarowym (master clock) i jednym sygnałem ustawiania/kasowania (master set/reset), które sterują wszystkimi elementami sekwencyjnymi w projekcie. Za najbardziej bezpieczne podejście w dziedzinie zapewnienia właściwych relacji czasowych w układzie scalonym uważa się metodologię układu synchronicznego. Podejście w pełni synchroniczne może wydłużać wstępną fazę projektu (up-front design time). Jednak osiągamy znaczną oszczędność w czasie weryfikacji. Całkowicie synchroniczny projekt może używać więcej zasobów ale: Układ będzie bardziej stabilny, Krótszy będzie czas debugowania, Skuteczna będzie statyczna analiza czasowa, Łatwość przeniesienia na inną technologię. AGH, WFiIS, HDL 37
Reguły projektu synchronicznego Wszystkie przerzutniki w ścieżce danych powinny być bezpośrednio połączone do jednego wspólnego globalnego bufora zegara, Wszystkie przerzutniki powinny być wyzwalane na tym samym zboczu zegara, Nie mogą istnieć przerzutniki taktowane sygnałem innym niż zegar, Jeśli potrzeba więcej niż jeden zegar i dane wędrują pomiędzy domenami różnych zegarów, to muszą być resynchronizowane za pomocą kilku przerzutników gdy przechodzą z jednej domeny do drugiej. always @(posedge nie_zegar) AGH, WFiIS, HDL 38
Detektor sekwencji 0101 x[3:0] z[3:0] 1/0 1/0 0/0 0/0 A B C D 0/0 1/0 0/0 1/1 AGH, WFiIS, HDL 39
Wejścia Wyjścia ps x ns z A 0 B 0 A 1 A 0 B 0 B 0 B 1 C 0 C 0 D 0 C 1 A 0 D 0 B 0 D 1 C 1 Detektor sekwencji 0101 Wejścia Wyjścia ps0,ps1 x ns0,ns1 z 0,0 0 0,1 0 0,0 1 0,0 0 0,1 0 0,1 0 0,1 1 1,0 0 1,0 0 1,1 0 1,0 1 0,0 0 1,1 0 0,1 0 1,1 1 1,0 1 1/0 0/0 0/0 A B C D 0/0 1/0 1/1 1/0 0/0 ns1 = x ps0,ps1 x 00 01 11 10 0 1 1 1 1 1 0 0 0 0 ps0,ps1 x 00 01 11 10 0 0 0 0 1 1 0 1 1 0 ns0 = ps1 x + ps0 ps1 x z = ps0 ps1 x ps0,ps1 x 00 01 11 10 0 0 0 0 0 1 0 0 1 0 AGH, WFiIS, HDL 40
Logika iteracyjna ns0 = ps1 x + ps0 ps1 x ns1 = x z = ps0 ps1 x nst[1] ps0 ps1 x[1] ns0 ns1 nst[2] z[1] AGH, WFiIS, HDL 41
Logika iteracyjna x[0] x[1] x[2] x[n-1] ps0 nst[0] ns0 nst[1] ps0 ns0 nst[2] ps0 ns0 ps0 nst[n-1] ns0 nst[n] ps1 ns1 ps1 ns1 ps1 ns1 ps1 ns1 z[0] z[1] z[2] z[n-1] AGH, WFiIS, HDL 42
Logika iteracyjna module celastanu(input x, input [1:0] pst, output reg z, output reg [1:0] nst); module seqdet_iter #(parameter N=6) (input [N-1:0] x, output [N-1:0] z); //N - rozmiar detektora localparam A=2'b00, B=2'b01, C=2'b10, D=2'b11; wire [1:0] nst [N:0]; genvar i; assign nst[0] = A; localparam A=2'b00, B=2'b01, C=2'b10, D=2'b11; always @* //okreslenie nastepnego stanu case(pst) A: nst = x?a:b; B: nst = x?c:b; C: nst = x?a:d; D: nst = x?c:b; endcase always @* //okreslenie wyjscia case(pst) A: z = x?1'b0:1'b0; B: z = x?1'b0:1'b0; C: z = x?1'b0:1'b0; D: z = x?1'b1:1'b0; endcase endmodule generate for(i=1; i<=n; i=i+1) begin: det0101 celastanu statecell (x[i-1], nst[i-1], z[i-1], nst[i]); end endgenerate endmodule AGH, WFiIS, HDL 43
Idea automatu skończonego x[0] x[1] x[2] x[n-1] ps0 nst[0] ns0 nst[1] ps0 ns0 nst[2] ps0 ns0 ps0 nst[n-1] ns0 nst[n] ps1 ns1 ps1 ns1 ps1 ns1 ps1 ns1 z[0] z[1] z[2] z[n-1] Przejście do automatu skończonego x[i] ps0 ps1 ns0 ns1 nst[i] Rejestr stanu z[i] AGH, WFiIS, HDL 44
X 1 X 2 X m Z 1 Z 2 Z n Uogólniony model automatu Q 1 + Q 1 Mealy ego Q 1 Uklad kombinacyjny Q 2 + Q 2 X=[X 1, X 2,... X m ] wektor wejść Z=[Z 1, Z 2,... Z n ] wektor wyjść S=[Q 1, Q 2,... Q k ] wektor stanu S + =[Q 1+, Q 2+,... Q k+ ] wektor stanu następnego Q 2 Q k Q k + Q k Z = λ(s,x) S + = δ(s,x) funkcja wyjść funkcja stanu clk AGH, WFiIS, HDL 45
Uogólniony model automatu Moore a Q + Q 1 1 Z = λ(s) S + = δ(s,x) funkcja wyjść funkcja stanu X 1 X 2 X m Q 1 Uklad Kombinacyjny stanu następnego Q 2 (wejścia rejetrus stanu) Q 2 + Q 2 Układ kombiancyjny wyjść Z 1 Z 2 Z n Q k Q k + Q k clk AGH, WFiIS, HDL 46
Detektor sekwencji - przykład Projekt detektora sekwencji 101. Jest to układ, który analizuje ciąg zer i jedynek przychodzący na wejście X i generujący wyjście Z=1, gdy wykryta zostanie określona sekwencja. X clk rst US Specyfikacja: Sygnał wejściowy X może się zmieniać tylko pomiędzy aktywnymi zboczami zegara, Każda sekwencja 101 pojawiająca się w strumieniu bitowym X powoduje pojawienie się 1 na wyjściu Z w momencie ostatniej jedynki, Układ nie jest resetowany w momencie pojawienia się 1 na wyjściu. Przykładowwe działanie układu: X= 0 0 1 1 0 1 1 0 0 1 0 1 0 1 0 0 Z= 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 time 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AGH, WFiIS, HDL 47 Z 1
Detektor sekwencji - przykład Konstrukcja grafu stanów dla automatu Mealy ego. Zaczynamy od stanu resetu układu oznaczonego przez S 0. Jeśli w tym stanie strumień wejściowy X podaje: 0 to układ pozostaje w tym stanie gdyż nie rozpoczęła się poszukiwana sekwencja, 1 to stan układu musi ulec zmianie do S 1 aby zapamiętać, że pierwszy element poszukiwanej sekwencji został wykryty. X=0/Z=0 S 0 X=1/Z=0 S 1 AGH, WFiIS, HDL 48
Detektor sekwencji - przykład Analizujemy zachowanie układu w stanie S 1. Jeśli w tym stanie strumień wejściowy X podaje: 1 to układ pozostaje w tym stanie gdyż nowo otrzymana jedynka ponownie rozpoczyna poszukiwaną sekwencja, 0 to stan układu musi ulec zmianie do S 2 aby zapamiętać, że pierwsze dwa elementy poszukiwanej sekwencji zostały wykryte. 0/0 S 0 1/0 S 1 1/0 S 2 0/0 AGH, WFiIS, HDL 49
Detektor sekwencji - przykład Analizujemy zachowanie układu w stanie S 2. Jeśli w tym stanie strumień wejściowy X podaje: 1 to poszukiwana sekwencja została ukończona i wyjściowa jedynka ma być wygenerowana. Jaki jednak jest stan następny? Nowy stan czy S 1 czy S 0? S 0 jest wykluczone, gdyż układ nie podlega resetowaniu po rozpoznaniu sekwencji. Oznacza to, że ostatnia jedynka w sekwencji jest równocześnie pierwszą w kolejnej sekwencji. Dlatego stanem następnym musi być S 1. 0 to stan układu powinien być wykasowany do S 0 gdyż jest to drugie zero i sekwencja 00 nie należy do poszukiwanej sekwencji. 0/0 S 0 1/0 0/0 1/1 S 1 1/0 S 2 0/0 AGH, WFiIS, HDL 50
Detektor sekwencji - przykład 0/0 S 0 1/0 0/0 1/1 S 1 1/0 S 2 0/0 Tabela stanów: Stan obecny Stan następny Obecne wyjście Z Nazwa Symbol X=0 X=1 X=0 X=1 Start S 0 S 0 S 1 0 0 Kończące 1 S 1 S 2 S 1 0 0 Kończące 10 S 2 S 0 S 1 0 1 AGH, WFiIS, HDL 51
Detektor sekwencji - przykład Tabela stanów: Stan obecny Stan następny Obecne wyjście Z Nazwa Symbol X=0 X=1 X=0 X=1 Start S 0 S 0 S 1 0 0 Kończące 1 S 1 S 2 S 1 0 0 Kończące 10 S 2 S 0 S 1 0 1 Stany kodujemy za pomocą dwóch przerzutników A i B. Tabela przejść: Stan obecny Stan następny A n+1 B n+1 Obecne wyjście Z Nazwa A n B n X=0 X=1 X=0 X=1 Start 00 00 01 0 0 Kończące 1 01 10 01 0 0 Kończące 10 10 00 01 0 1 AGH, WFiIS, HDL 52
Detektor sekwencji - przykład Tabelę przejść rozpisujemy na tabele Karnougha: Stan obecny Stan następny A n+1 B n+1 Obecne wyjście Z Nazwa A n B n X=0 X=1 X=0 X=1 Start 00 00 01 0 0 Kończące 1 01 10 01 0 0 Kończące 10 10 00 01 0 1 Nie potrzebny 11 xx xx x x AB X 0 1 00 0 0 01 1 0 11 x x 10 0 0 AB X 0 1 00 0 1 01 0 1 11 x x 10 0 1 AB X 0 1 00 0 0 01 0 0 11 x x 10 0 1 A n+1 = X B B n+1 = X Z = XA AGH, WFiIS, HDL 53
Detektor sekwencji - przykład Na podstawie tabel Karnaugha - ręcznie Układ Mealy ego i przebiegi czasowe w nim Incisive, Cadence clk rst X Z state Wyjście zmienia się asynchronicznie w stosunku do sygnału zegarowego AGH, WFiIS, HDL 54
Detektor sekwencji - przykład Konstrukcja grafu stanów dla automatu Moore a. Zaczynamy od stanu resetu układu oznaczonego przez S 0. Jeśli w tym stanie strumień wejściowy X podaje: 0 to układ pozostaje w tym stanie gdyż nie rozpoczęła się poszukiwana sekwencja, 1 to stan układu musi ulec zmianie do S 1 aby zapamiętać, że pierwszy element poszukiwanej sekwencji został wykryty. X=0 S 0 Z=0 X=1 S 1 Z=0 AGH, WFiIS, HDL 55
Detektor sekwencji - przykład Analizujemy zachowanie układu w stanie S 1. Jeśli w tym stanie strumień wejściowy X podaje: 1 to układ pozostaje w tym stanie gdyż nowo otrzymana jedynka ponownie rozpoczyna poszukiwaną sekwencję, 0 to stan układu musi ulec zmianie do S 2 aby zapamiętać, że pierwsze dwa elementy poszukiwanej sekwencji zostały wykryte. 0 1 S 0 Z=0 1 S 1 Z=0 0 S 2 Z=0 AGH, WFiIS, HDL 56
Detektor sekwencji - przykład Analizujemy zachowanie układu w stanie S 2. Jeśli w tym stanie strumień wejściowy X podaje: 1 to układ musi przejść do nowego stanu S 3 (nie może powrócić do S 1 ) gdyż nowo otrzymana jedynka kończy poszukiwaną sekwencję i sygnał wyjściowy musi ulec zmianie, 0 to układu wymaga wykasowania gdyż sekwencja 100 jest błędna. 0 1 S 0 Z=0 1 S 1 Z=0 0 0 S 3 Z=1 1 S 2 Z=0 AGH, WFiIS, HDL 57
Detektor sekwencji - przykład Analizujemy zachowanie układu w stanie S 3. Jeśli w tym stanie strumień wejściowy X podaje: 1 to układ musi powrócić do S 1 gdyż nowo otrzymana jedynka rozpoczyna ponownie poszukiwaną sekwencję, 0 to układ powinien wrócić do S 2 gdyż sekwencja 1010 powinna znów dać Z=1 po kolejnej jedynce na wejściu. 0 1 S 0 Z=0 1 S 1 Z=0 1 0 0 S 3 Z=1 0 1 S 2 Z=0 AGH, WFiIS, HDL 58
Detektor sekwencji - przykład 0 1 S 0 Z=0 1 S 1 Z=0 1 0 Tabela stanów: Stan obecny S 3 Z=1 0 S 2 Z=0 Stan następny Obecne wyjście Z Nazwa Symbol X=0 X=1 X=1 Start S 0 S 0 S 1 0 Kończące 1 S 1 S 2 S 1 0 Kończące 10 S 2 S 0 S 3 0 Kończące 101 S 3 S 2 S 1 1 1 0 AGH, WFiIS, HDL 59
Detektor sekwencji - przykład Tabela stanów: Stan obecny Stan następny Obecne wyjście Z Nazwa Symbol X=0 X=1 X=1 Start S 0 S 0 S 1 0 Kończące 1 S 1 S 2 S 1 0 Kończące 10 S 2 S 0 S 3 0 Kończące 101 S 3 S 2 S 1 1 Tabela przejść: Stan obecny Stany kodujemy za pomocą dwóch przerzutników A i B. Stan następny A n+1 B n+1 Obecne wyjście Z Nazwa A n B n X=0 X=1 X=1 Start 00 00 01 0 Kończące 1 01 10 01 0 Kończące 10 10 00 11 0 Kończące 101 11 10 01 1 AGH, WFiIS, HDL 60
Detektor sekwencji - przykład Stan obecny Stan następny A n+1 B n+1 Obecne wyjście Z Nazwa A n B n X=0 X=1 X=1 Start 00 00 01 0 Kończące 1 01 10 01 0 Kończące 10 10 00 11 0 Kończące 101 11 10 01 1 AB X 0 1 AB X 0 1 A B 0 1 00 0 0 00 0 1 0 0 0 01 1 0 01 0 1 1 0 1 11 1 0 10 0 1 11 0 1 10 0 1 Z = AB A n+1 = X B + XAB B n+1 = X AGH, WFiIS, HDL 61
Detektor sekwencji - przykład Na podstawie tabel Karnaugha - ręcznie Układ Moore a i przebiegi czasowe w nim Incisive, Cadence clk rst X Z state Wyjście zmienia się synchronicznie względem sygnału zegarowego AGH, WFiIS, HDL 62
Detektor sekwencji - przykład Układ Mealy ego Porównanie przebiegów czasowych Incisive, Cadence clk rst X Z state Układ Moore a clk rst X Z state Wyjście zmienia się asynchronicznie w stosunku do sygnału zegarowego Incisive, Cadence Wyjście zmienia sie synchronicznie względem sygnału zegarowego AGH, WFiIS, HDL 63
Detektor sekwencji - przykład Układ Mealy ego Porównanie wyników automatycznej syntezy za pomocą programu RTL Compiler Encounter RTL Compiler, Cadence Układ Moore a Encounter RTL Compiler, Cadence AGH, WFiIS, HDL 64
Metody kodowania automatu Dwa typy opisu automatu skończonego FSM w HDL: Implicite stany nie są deklarowane wyraźnie, Explicite wyraźnie zadeklarowane stany automatu. Metody opisu typu explicite w Verilogu: Metoda jedno procesowa, Metoda dwu procesowa, Metoda trój procesowa, Metoda z funkcją. Uwagi: Stosowanie assign w miejsce always do opisu bloków kombinacyjnych, zwłaszcza dla określenia funkcji wyjść może być wygodne. Wyjście rejestrowane może być potrzebne w przypadku automatów Mealy ego. Prezentowane schematy pochodzą z syntezy za pomocą RTL Compiler (Cadence) AGH, WFiIS, HDL 65
Opis bez wyraźnej deklaracji stanów module sum_3data_implicite #(parameter n=8) (input clk, input [n-1:0] data, output reg [n-1:0] total); always begin @(posedge clk) total <= data; @(posedge clk) total <= total + data; @(posedge clk) total <= total + data; end endmodule niesyntezowalne Bardzo zły styl kodowania! Konstrukcja @(posedge clk) jest konstrukcją typu sterowania czasem i jako taka nie jest syntezowalna. AGH, WFiIS, HDL 66
Opis z wyraźną deklaracją stanów module sum_3data_explicite #(parameter n=8) (input clk, rst, input [n-1:0] data, output reg [n-1:0] total); reg [1:0] state; localparam A=2'b00, B=2'b01, C=2'b10; Deklaracja stanów automatu always @(posedge clk, negedge rst) if (~rst) state <= A; else case (state) A: begin total <= data; state <= B; end B: begin total <= total + data; state <= C; end C: begin total <= total + data; state <= A; end endcase endmodule AGH, WFiIS, HDL 67
Metoda jedno procesowa module seqdet_fsm1a (input clk, rst, x, output reg z); localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state; always @(posedge clk, negedge rst) if(~rst) begin state <= A; z <= 1 b0; end else case(state) A: state <= x?a:b; B: state <= x?c:b; C: begin state <= A; z <= x; end endcase endmodule Encounter RTL Compiler, Cadence Jest to styl rozrzutny pod względem użytych zasobów sprzętowych, gdyż każdy sygnał wyjściowy jest syntezowany za pomocą przerzutnika. Oznacza to także, że wyjścia są dostarczane dopiero na następnym zboczu zegara po tym jak wyliczył je automat. AGH, WFiIS, HDL 68
Metoda dwu procesowa module seqdet_fsm1a (input clk, rst, x, output reg z); localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state, nst; always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= nst; Styl rekomendowany! always @* begin nst = A; z = 1'b0; case(state) A: nst = x?a:b; B: nst = x?c:b; C: begin nst = A; z = x; end endcase end endmodule Encounter RTL Compiler, Cadence AGH, WFiIS, HDL 69
Metoda trój procesowa module seqdet_fsm1a (input clk, rst, x, output reg z); localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state, nst; always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= nst; always @* begin nst = A; case(state) A: nst = x?a:b; B: nst = x?c:b; C: nst = A; endcase end always @* begin z = 1'b0; case(state) A: z = 1'b0; B: z = 1'b0; C: z = x; endcase end endmodule AGH, WFiIS, HDL Encounter RTL Compiler, Cadence Przy dużej ilości wyjść warto je oddzielić w postaci osobnego bloku kombinacyjnego. Nie wpływa to na wynik syntezy. 70
Stosowanie assign module seqdet_fsm1a (input clk, rst, x, output z); localparam A=2'b00, B=2'b01, C=2'b10; Encounter RTL Compiler, Cadence reg [1:0] state, nst; always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= nst; Blok kombinacyjny można też zapisać za pomocą przypisania ciągłego. always @* begin nst = A; case(state) A: nst = x?a:b; B: nst = x?c:b; C: nst = A; endcase end assign z = (state == C) & x; endmodule AGH, WFiIS, HDL 71
Rejestrowane wyjścia Encounter RTL Compiler, Cadence module seqdet_fsm1a (input clk, rst, x, output reg z); localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state, nst; always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= nst; always @* begin nst = A; case(state) A: nst = x?a:b; B: nst = x?c:b; C: nst = A; endcase end AGH, WFiIS, HDL always @ posedge clk, negedge rst) if(~rst) z <= 1'b0; else begin case(state) A: z <= 1'b0; B: z <= 1'b0; C: z <= x; endcase end endmodule 72
Wnioskowane będą zatrzaski dla zmiennej nst gdyż brak określenia wartości domyślnych dla tej zmiennej. module seqdet_fsm1a (input clk, rst, x, output z); Metoda z funkcją Inny sposób uniknięcia zatrzasków to umieszczenie bloku logiki wewnątrz funkcji. module seqdet_fsm1a (input clk, rst, x, output z); localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state; localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state, nst; always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= nst; always @* begin case(state) A: nst = x?a:b; B: nst = x?c:b; C: nst = A; endcase end assign z = (state == C) & x; endmodule always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= fsmnextstate(state, x); function [1:0] fsmnextstate (input [1:0] pst, input x); reg [1:0] nst; begin case(pst) A: nst = x?a:b; B: nst = x?c:b; C: nst = A; endcase fsmnextstate = nst; end endfunction assign z = (state == C) & x; endmodule AGH, WFiIS, HDL 73
module seqdet_fsm1a (input clk, rst, x, output z); localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state, nst; always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= nst; Encounter RTL Compiler, Cadence Wnioskowanie zatrzasków always @* begin case(state) A: nst = x?a:b; B: nst = x?c:b; C: nst = A; endcase end assign z = (state == C) & x; endmodule AGH, WFiIS, HDL 74
module seqdet_fsm1a (input clk, rst, x, output z); localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state, nst; always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= nst; Encounter RTL Compiler, Cadence Unikanie wnioskowania zatrzasków poprzez wartość domyślną always @* begin nst = A; case(state) A: nst = x?a:b; B: nst = x?c:b; C: nst = A; endcase end assign z = (state == C) & x; endmodule AGH, WFiIS, HDL 75
Unikanie wnioskowania zatrzasków poprzez zastosowanie funkcji Encounter RTL Compiler, Cadence module seqdet_fsm1a (input clk, rst, x, output z); localparam A=2'b00, B=2'b01, C=2'b10; reg [1:0] state; always @(posedge clk, negedge rst) if(~rst) state <= A; else state <= fsmnextstate(state, x); function [1:0] fsmnextstate (input [1:0] pst, input x); reg [1:0] nst; begin case(pst) A: nst = x?a:b; B: nst = x?c:b; C: nst = A; endcase fsmnextstate = nst; end endfunction assign z = (state == C) & x; endmodule AGH, WFiIS, HDL 76
wejście X Model automatu w Verilog-u Układ kombinacyjny funkcji stanu następnego always @* case(stan) S0: nast_stan =...; S1:...;... Sn:...; endcase localparam S0=,..., Sn= ; reg [m:0] stan, next_stan; Rejestr stanu always @(posedge clk, negedge rst) if(~rst) stan <= S0; else stan <= nast_stan; stan stan X Układ kombinacyjny funkcji wyjść always @* case(stan) S0: Z =...; S1:...... Sn:...; endcase wyjście Z AGH, WFiIS, HDL 77