2010년 1월 21일 목요일

FSM(F??? State Machine)의Verilog HDL 코딩

State Machine의 타입

두 가지 종류의 State Machine이 있다.
  • Mealy State Machine : State Machine의 출력은 현재의 State와 입력에 의해서 결정된다.
  • Moore State Machine : State Machine의 출력이 현재의 State에 의해서만 결정된다.
필요에 따라서, 두 가지 종류중 한가지를 선택할 수 있다. 보통은 Mealy FSM을 사용한다.

Encoding Style

State Machine을 Digital 회로로 표현해야 하기 때문에 각 State를 다음의 세 가지 중하나로 표현해야 한다.
  • Binary Encoding : 각 State를 Binary Code로 표현한다. (i.e. 000, 001, 010, ...)
  • Gray Encoding : 각 State를 Gray Code로 표현한다. (i.e. 000, 001, 011, ...)
  • One Hot : 각 State를 한 Bit만 High가 되고 나머지는 Low가 되도록 한다. (i.e. 001, 010, 100)
  • One Cold : 각 State를 한 Bit만 Low가 되고 나머지는 High가 되도록 한다. (i.e. 110, 101, 011)
대부분의 경우 One Hot Encoding을 사용한다.

예제

두개의 request 입력과 두개의 grant 출력을 갖는 간단한 Arbiter를 살펴보자.
  • req_0가 활성화 되면, gnt_0를 활성화 한다.
  • req_1이 활성화 되면, gnt_1을 활성화 한다.
  • req_0과 req_1이 동시에 활성화 되면, gnt_0를 활성화 한다. 즉, req_1보다 req_0에 더 우선순위를 주는 방식이 된다.
그럼, 다음과 같이 세가지의 State를 정의 할 수 있다.
  • IDLE : 이 State에서 FSM은 req_0나 req_1의 활성화를 기다리고, gnt_0와 gnt_1의 비활성화 상태로 둔다. 이 State는 Reset후거나 오류 상태에 대한 FSM의 설정치이다.
  • GNT0 : FSM은 req_0가 활성화 되었을때 이 State로 진입하게 된다. 그리고 req_0가 활성화 되어 있는 동안 계속 유지된다. req_0가 비활성화 되면 FSM은 IDLE State가 된다.
  • GNT1 : FSM은 req_1가 활성화 되었을때 이 State로 진입하게 된다. 그리고 req_1가 활성화 되어 있는 동안 계속 유지된다. req_1가 비활성화 되면 FSM은 IDLE State가 된다.

Coding 방법

다양한 방법으로 위에서 진술한 FSM을 구현하였다. One Hot Encoding을 사용하였다.

module fsm_using_function(clock, reset, req_0, req_1, gnt_0, gnt_1);

input clock, reset, req_0, req_1;

output gnt_0, gnt_1;

wire clock, reset, req_0, req_1;

reg gnt_0, gnt_1;

parameter SIZE = 3;

parameter IDLE = 3'b001, GNT0 = 3'b010, GNT1 = 3'b100;

reg [SIZE-1:0] state;

wire [SIZE-1:0] next_state;


assign next_state = fsm_function(state, req_0, req_1);


function [SIZE-1:0] fsm_function;

input [SIZE-1:0] state;

input req_0;

input req_1;

case (state)

IDLE:

if (req_0 == 1'b1) begin

fsm_function = GNT0;

end else if (req_1 == 1'b1) begin

fsm_function = GNT1;

end else begin

fsm_function = IDLE;

end

GNT0:

if (req_0 == 1'b1) begin

fsm_function = GNT0;

end else begin

fsm_function = IDLE;

end

GNT1:

if (req_1 == 1'b1) begin

fsm_function = GNT1;

end else begin

fsm_function = IDLE;

end

default:

fsm_function = IDLE;

endcase

endfunction


// seq logic
always @(posedge clock)

begin : FSM_SEQ

if (reset == 1'b1) begin

state <= #1 IDLE;

end else begin state <= #1 next_state;

end

end

// output logic

always @(posedge clock)

begin : OUTPUT_LOGIC

if (reset == 1'b1) begin

gnt_0 <= #1 1'b0;

gnt_1 <= #1 1'b0;

end else begin

case (state)

...

end

댓글 없음:

댓글 쓰기