题目:
Exams/2014 q3fsm
Consider a finite state machine with inputs s and w. Assume that the FSM begins in a reset state called A, as depicted below. The FSM remains in state A as long as s = 0, and it moves to state B when s = 1. Once in state B the FSM examines the value of the input w in the next three clock cycles. If w = 1 in exactly two of these clock cycles, then the FSM has to set an output z to 1 in the following clock cycle. Otherwise z has to be 0. The FSM continues checking w for the next three clock cycles, and so on. The timing diagram below illustrates the required values of z for different values of w.
Use as few states as possible. Note that the s input is used only in state A, so you need to consider just the w input.
解题:
cpp
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter A=0,B=1,B1=2,B2=3;
reg [2:0]state,next_state;
reg [2:0]cnt;
always@(posedge clk)begin
if(reset)
state=A;
else
state=next_state;
end
always@(*)begin
case(state)
A:next_state=s?B:A;
B:next_state=B1;
B1:next_state=B2;
B2:next_state=B;
default:next_state=A;
endcase
end
always@(posedge clk)begin
if(reset)begin
cnt=0;
end
else begin
case(state)
A:cnt=0;
B: cnt=w;
B1:cnt=w?cnt+1:cnt;
B2:cnt=w?cnt+1:cnt;
default:cnt=0;
endcase
end
end
assign z=((state==B)&(cnt==2))?1:0;
endmodule
结果正确:
网上看到另一种解法,记录一下,类似FIFO思想,先进先出。
cpp
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
localparam A = 1'b0,
B = 1'b1;
reg [1:0] state,next_state;
reg [2:0] data;
reg [1:0] cnt;
always@(posedge clk)begin
if(reset)
state <= A;
else
state <= next_state;
end
always@(*)begin
case (state)
A: next_state = s?B:A;
B: next_state = B;
endcase
end
always@(posedge clk)begin
if(reset)
data <= 3'b0;
else case (next_state)
A: data <= 3'b0;
B: begin
data[0] <= w;
data[1] <= data[0];
data[2] <= data[1];
end
endcase
end
always@(posedge clk)begin
if(reset)
cnt <= 2'h0;
else if(state == A)
cnt <= 2'h0;
else if(cnt==2'h3&&(state == B))
cnt <= 2'h1;
else
cnt <= cnt+2'h1;
end
assign z = ((data==3'b011)|(data==3'b101)|(data==3'b110))&&(cnt==2'h3);
endmodule