HDLbits--FSM-2
本篇文章接续介绍Verilog中FSM典型案例;
题目:Lemmings3

verilog
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );
parameter WALK_LEFT = 6'b0000_01;
parameter WALK_RIGHT= 6'b0000_10;
parameter DIG_RIGHT = 6'b0001_00;
parameter DIG_LEFT = 6'b0010_00;
parameter FALL_LEFT = 6'b0100_00;
parameter FALL_RIGHT= 6'b1000_00;
reg[5:0] cur_sta;
reg[5:0] nxt_sta;
//==state D-Flop-flop
always @(posedge clk or posedge areset) begin
if(areset) begin
cur_sta <= WALK_LEFT;
end else begin
cur_sta <= nxt_sta;
end
end
//==state transition
always @(*) begin
if(areset) begin
nxt_sta = WALK_LEFT;
end else begin
case(cur_sta)
WALK_LEFT: begin
if(ground==1'b0) begin
nxt_sta = FALL_LEFT;
end else if(dig==1'b1) begin
nxt_sta = DIG_LEFT;
end else if(bump_left==1'b1) begin
nxt_sta = WALK_RIGHT;
end else begin
nxt_sta = WALK_LEFT;
end
end
WALK_RIGHT: begin
if(ground==1'b0) begin
nxt_sta = FALL_RIGHT;
end else if(dig==1'b1) begin
nxt_sta = DIG_RIGHT;
end else if(bump_right==1'b1) begin
nxt_sta = WALK_LEFT;
end else begin
nxt_sta = WALK_RIGHT;
end
end
FALL_LEFT: begin
if(ground==1'b1) begin
nxt_sta = WALK_LEFT;
end else begin
nxt_sta = FALL_LEFT;
end
end
FALL_RIGHT: begin
if(ground==1'b1) begin
nxt_sta = WALK_RIGHT;
end else begin
nxt_sta = FALL_RIGHT;
end
end
DIG_LEFT: begin
if(ground==1'b0) begin
nxt_sta = FALL_LEFT;
end else begin
nxt_sta = DIG_LEFT;
end
end
DIG_RIGHT: begin
if(ground==1'b0) begin
nxt_sta = FALL_RIGHT;
end else begin
nxt_sta = DIG_RIGHT;
end
end
endcase
end
end
//====State output
always @(*) begin
walk_left = 0;
walk_right= 0;
aaah = 0;
digging = 0;
case(cur_sta)
WALK_LEFT: walk_left = 1'b1;
WALK_RIGHT:walk_right= 1'b1;
FALL_LEFT: aaah = 1'b1;
FALL_RIGHT:aaah = 1'b1;
DIG_LEFT: digging=1'b1;
DIG_RIGHT: digging=1'b1;
endcase
end
endmodule
题目:Lemmings4

verilog
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );
parameter WALK_LEFT = 6'b0000_01;
parameter WALK_RIGHT= 6'b0000_10;
parameter DIG_RIGHT = 6'b0001_00;
parameter DIG_LEFT = 6'b0010_00;
parameter FALL_LEFT = 6'b0100_00;
parameter FALL_RIGHT= 6'b1000_00;
parameter SPLAT = 6'b0000_00;
reg[5:0] cur_sta;
reg[5:0] nxt_sta;
reg[7:0] cnt_20;
always @(posedge clk or posedge areset) begin
if(areset) begin
cnt_20 <= 0;
end else begin
if(!ground) begin
cnt_20 <= cnt_20 + 1;
end else begin
cnt_20 <= 0;
end
end
end
//==state D-Flop-flop
always @(posedge clk or posedge areset) begin
if(areset) begin
cur_sta <= WALK_LEFT;
end else begin
cur_sta <= nxt_sta;
end
end
//==state transition
always @(*) begin
if(areset) begin
nxt_sta = WALK_LEFT;
end else begin
case(cur_sta)
WALK_LEFT: begin
if(ground==1'b0) begin
nxt_sta = FALL_LEFT;
end else if(dig==1'b1) begin
nxt_sta = DIG_LEFT;
end else if(bump_left==1'b1) begin
nxt_sta = WALK_RIGHT;
end else begin
nxt_sta = WALK_LEFT;
end
end
WALK_RIGHT: begin
if(ground==1'b0) begin
nxt_sta = FALL_RIGHT;
end else if(dig==1'b1) begin
nxt_sta = DIG_RIGHT;
end else if(bump_right==1'b1) begin
nxt_sta = WALK_LEFT;
end else begin
nxt_sta = WALK_RIGHT;
end
end
FALL_LEFT: begin
if(ground==1'b1) begin
if(cnt_20>20) begin
nxt_sta = SPLAT;
end else begin
nxt_sta = WALK_LEFT;
end
end else begin
nxt_sta = FALL_LEFT;
end
end
FALL_RIGHT: begin
if(ground==1'b1) begin
if(cnt_20>20) begin
nxt_sta = SPLAT;
end else begin
nxt_sta = WALK_RIGHT;
end
end else begin
nxt_sta = FALL_RIGHT;
end
end
DIG_LEFT: begin
if(ground==1'b0) begin
nxt_sta = FALL_LEFT;
end else begin
nxt_sta = DIG_LEFT;
end
end
DIG_RIGHT: begin
if(ground==1'b0) begin
nxt_sta = FALL_RIGHT;
end else begin
nxt_sta = DIG_RIGHT;
end
end
SPLAT: begin
nxt_sta = SPLAT;
end
endcase
end
end
//====State output
always @(*) begin
walk_left = 0;
walk_right= 0;
aaah = 0;
digging = 0;
case(cur_sta)
WALK_LEFT: walk_left = 1'b1;
WALK_RIGHT:walk_right= 1'b1;
FALL_LEFT: aaah = 1'b1;
FALL_RIGHT:aaah = 1'b1;
DIG_LEFT: digging=1'b1;
DIG_RIGHT: digging=1'b1;
endcase
end
endmodule
题目:
verilog
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
parameter S0=10'b00_0000_0001;
parameter S1=10'b00_0000_0010;
parameter S2=10'b00_0000_0100;
parameter S3=10'b00_0000_1000;
parameter S4=10'b00_0001_0000;
parameter S5=10'b00_0010_0000;
parameter S6=10'b00_0100_0000;
parameter S7=10'b00_1000_0000;
parameter S8=10'b01_0000_0000;
parameter S9=10'b10_0000_0000;
always @(*) begin
case(state)
S0: next_state = (in==1'b1) ? S1 : S0;
S1: next_state = (in==1'b1) ? S2 : S0;
S2: next_state = (in==1'b1) ? S3 : S0;
S3: next_state = (in==1'b1) ? S4 : S0;
S4: next_state = (in==1'b1) ? S5 : S0;
S5: next_state = (in==1'b1) ? S6 : S8;
S6: next_state = (in==1'b1) ? S7 : S9;
S7: next_state = (in==1'b1) ? S7 : S0;
S8: next_state = (in==1'b1) ? S1 : S0;
S9: next_state = (in==1'b1) ? S1 : S0;
default: next_state = 0;
endcase
end
assign out1 = (state==S8) || (state==S9);
assign out2 = (state==S7) || (state==S9);
endmodule
题目:
verilog
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done); //
// FSM from fsm_ps2
parameter S1 = 4'b0001;
parameter S2 = 4'b0010;
parameter S3 = 4'b0100;
parameter S4 = 4'b1000;
reg[4 -1:0] cur_sta;
reg[4 -1:0] nxt_sta;
//===state transition
always @(*) begin
if(reset) begin
nxt_sta = S1;
end else begin
case(cur_sta)
S1 : nxt_sta = (in[3]==1'b1) ? S2 : S1;
S2 : nxt_sta = S3;
S3 : nxt_sta = S4;
S4 : nxt_sta = (in[3]==1'b1) ? S2 : S1;
default : nxt_sta = S1;
endcase
end
end
//==state flop-flop
always @(posedge clk) begin
if(reset) begin
cur_sta <= S1;
end else begin
cur_sta <= nxt_sta;
end
end
assign done = (cur_sta==S4);
// New: Datapath to store incoming bytes.
always @(posedge clk) begin
case(cur_sta)
S1 : out_bytes[24 -1:16] <= in;
S2 : out_bytes[16 -1:8] <= in;
S3 : out_bytes[8 -1: 0] <= in;
S4 : out_bytes[24 -1:16] <= in;
endcase
end
endmodule