1. FSM 

1-1 개념

  • 유한상태 머신(FSM) 

Moore머신 : 출력이 현재상태에 의해서만 결정, 동기형 출력

Mealy머신 :  출력이 현재상태와 입력에 의해 결정, 비동기형 출력

  • 상태할당

상태값의 인코딩 방식에 따라 필요한 state register의 비트수가 달라진다.

 

  • 코딩 주의점

1. FSM의 state를 parameter로 정의하여 사용하는 것이 좋다. `define을 이용할 경우 컴파일 과정에서 광역적 영향을 미치므로 다수의 FSM에서 동일한 state 사용 시 오류가 발생할 수 있기 때문이다.

2. FSM이 async reset을 할 수 있도록 설계해야 한다.

3. next state logic/ state register/ output logic 을 분리하여 코딩한다.

4. next state logic은 case문을 사용한다.

 

1-2 응용 예

/////////////// 3.3-1 Moore
module moore_m (clk,rst,x,z,ps,ns);
input wire clk, rst, x;
output reg [1:0] ps, ns;
output wire z;

parameter  S0= 2'b00, S1= 2'b01, S2= 2'b10, S3= 2'b11;

always @ (posedge rst, posedge clk)
begin
   if (rst) ps <= S0;   //async reset
   else ps <= ns;   //present state <= next state
end

always @ (ps or x)
begin
    case (ns)
       S0 : if (x) ns = S1; else ns = S0;
       S1 : if (x) ns = S2; else ns = S1;
       S2 : if (x) ns = S3; else ns = S1;
       S3 : ns = S0;
       default : ns = S0;
    endcase
end

assign z = (ps == S3) ? 1'b1 : 1'b0; 

endmodule

output z가 동기형 출력인 이유는, ps가 S3상태로 가면 z값이 바로 결정되기 때문이다. (입력값 영향 x) -> moore 머신

테스트벤치를 보면 S0상태에서 x가 1이 되는 순간 ns가 1로 바뀌고 clock의 rising edge마다 ps <=ns가 되는 것을 확인할 수 있다.

 

밀리 머신의 경우 if (w)  ~ else 문을 보면 알 수 있듯이 현재 상태와 입력 w 에 따라 출력이 변한다.

 

1-3 패턴 검사기 설계해보기

페턴 감사기 : 011011 감지 

FSM 설계

module detect (clk,rst, st, x,y,ps,ns);
input wire clk, rst, st, x;
output [2:0] ps, ns;
output reg y;
reg [2:0] ps, ns;


parameter  S0= 3'b000, S1= 3'b001, S2= 3'b010, S3= 3'b011, S4=3'b100, S5=3'b101, S6=3'b110,  S7=3'b111;

always @ (posedge rst, posedge clk)
begin
   if (rst) ps <= S0;   //async reset
   else ps <= ns;   //present state <= next state
end

always @ (ps or x or st)
begin
    case (ns)
       S0 : begin y = 1'b0; if (st) ns = S1; else ns = S0; end
       S1 : begin y = 1'b0; if (x) ns = S1; else ns = S2; end
       S2 : begin y = 1'b0; if (x) ns = S3; else ns = S2; end
       S3 : begin y = 1'b0; if (x) ns = S4; else ns = S2; end
       S4 : begin y = 1'b0; if (x) ns = S1; else ns = S5; end
       S5 : begin y = 1'b0; if (x) ns = S6; else ns = S2; end
       S6 : begin y = 1'b0; if (x) ns = S7; else ns = S2; end
       S7 : begin y = 1'b1; if (x) ns = S1; else ns = S5; end
       default : begin y = 1'b0; ns = S0; end
    endcase 
end

endmodule

FSM에 따라 상태를 기술해주었다 

module tb_detect;
reg        clk = 1'b0, rst, st, x;
wire       y;
wire [2:0] ps, ns;

detect dt1 (clk,rst, st, x,y,ps,ns);

always #10 clk = ~clk;

initial 
begin
        rst = 1'b1; st = 0'b0; x =1'b0; 
 #20   rst = 1'b0; st = 0'b1; x =1'b1;
 #20               st = 0'b0; x =1'b0;
 #20               x =1'b0;
 #20               x =1'b1;
 #20               x =1'b1;
 #20               x =1'b0;
 #20               x =1'b1;
 #20               x =1'b1;
 #20               x =1'b1;
 #100;
 $stop;        
 end
 
 endmodule

테스트벤치를 작성할때, clock의 주기마다 x에 값을 할당해주었다. clock의 주기보다 짧게 delay를 줄 경우 ns의 값이 여러 번 바뀌어 의도대로 동작하지 않을 수 있다.

위의 시뮬레이션 결과를 확인해보면 정상적으로 011011을 detect하여 y값이 1이 된 것을 볼 수 있다.

 

ASM PISO SIPO 

 

+ Recent posts