Automate

De la WikiLabs
Schema bloc generică pentru automate Moore și Mealy

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;
Regulă: Un automat are în mod obligatoriu port de reset. Cand reset-ul este activ, automatul trece într-una din stări, care este desemnată starea inițială.

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:

Diagramă automat exemplu

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