Automate
Automatul este un circuit secvențial, utilizat pentru a programa o secvență de operații. Un automat este definit de următoarele elemente:
- o mulțime de valori de intrare (care în cazul circuitelor sunt porturi de intrare);
- o mulțime de valori de ieșire (care în cazul circuitelor sunt porturi de ieșire);
- o mulțime de stări, care alternează în timp și din care doar una este activă la un moment dat (care în cazul circuitelor este memorată într-un registru intern);
- o funcție de tranziție a stărilor, care calculează starea următoare a automatului în funcție de starea curentă și valorile intrărilor (care în cazul circuitelor este un modul combinațional);
- o funcție de tranziție a ieșirilor care calculează următoarea valoare a ieșirilor, în funcție de starea curentă (în cazul automatelor de tip Moore), sau în funcție de starea curentă și valorile intrărilor (în cazul automatelor de tip Mealy) (care în cazul circuitelor este un modul combinațional).
La fiecare front de ceas, automatul face tranziția la starea următoare, calculată de către circuitul logic combinațional.
Observație: Numărul total de stări disponibil unui automat este dat de numărul de biți ai registrului de stare.
Observație: Există moduri de codificare a stărilor care să permită tranziția sigură în cazul intrărilor asincrone. Din fericire, programele de sinteză moderne detectează automat aceste cazuri și recodifică stările corespunzător.
Interfața unui automat
Interfața unui automat este compusă din următoarele porturi:
- semnalul de ceas, ca intrare;
- semnalul de reset, ca intrare;
- un număr oarecare de intrări, cu diferite funcții;
- un număr oarecare de ieșiri, cu diferite funcții;
Implementarea unui automat
Partea de implementare a unui automat este compusă din definiția unui registru de stare pe un număr suficient de biți pentru a putea codifica numărul de stări dorite, și definiția tranzițiilor stărilor și ieșirilor, implementate cu ajutorul unui bloc always secvențial și un sub-bloc case.
Observație: Dacă automatul ajunge într-o stare nedefinită, atunci tranziția următoare este într-o stare defintă ca stare de eroare, sau în starea inițială, după caz. Stările nedefinite sunt cele care în blocul case sunt tratate de condiția default.
Exemplu
Se dă ca exemplu automatul descris de diagrama din figura următoare, unde ieșirea este chiar codul stării:
Codul care descrie automatul este următorul:
`define STAREA_0 3'b000
`define STAREA_1 3'b001
`define STAREA_2 3'b010
`define STAREA_3 3'b011
`define STAREA_4 3'b100
module TestFSM(
output [2:0] out,
input [3:0] in0,
input in1,
input clock,
input reset
);
reg [2:0] state;
always@(posedge clock) begin
if(reset) begin
state <= `STAREA_0;
end else begin
case(state)
`STAREA_0: begin
if(in0 == 4'd12) begin
state <= `STAREA_1;
end else begin
state <= `STAREA_4;
end
end
`STAREA_1: begin
if(in1) begin
state <= `STAREA_0;
end else begin
state <= `STAREA_2;
end
end
`STAREA_2: begin
if(in1) begin
state <= `STAREA_0;
end else if(in0 == 4'd10) begin
state <= `STAREA_4;
end else begin
state <= `STAREA_3;
end
end
`STAREA_3: begin
if(!in1) begin
state <= `STAREA_4;
end
end
`STAREA_4: begin
state <= `STAREA_4;
end
default: begin
state <= `STAREA_0;
end
endcase
end
end
assign out = state;
endmodule