题目
See also: Lemmings1.In addition to walking left and right, Lemmings will fall (and presumably go "aaah!") if the ground disappears underneath them.In addition to walking left and right and changing direction when bumped, when ground=0, the Lemming will fall and say "aaah!". When the ground reappears (ground=1), the Lemming will resume walking in the same direction as before the fall. Being bumped while falling does not affect the walking direction, and being bumped in the same cycle as ground disappears (but not yet falling), or when the ground reappears while still falling, also does not affect the walking direction.Build a finite state machine that models this behaviour.
题目翻译:
另请参阅:旅鼠1.除了左右行走外,如果他们踩空,旅鼠会摔倒(大概发出“aaah!”的叫声)。除了左右行走和碰撞时改变方向,当地面消失时, 旅鼠会跌倒并说“aaah!”。 当地面重新出现时,旅鼠将继续沿与坠落前相同的方向行走。 下落时被撞不影响行走方向,被撞在与地面消失(但尚未下落)相同的循环中,或者当地面重新出现时仍然下落,也不影响行走方向。
逻辑抽象:
下落时被撞是指state处于惊吓状态时撞墙
被撞与地面消失(尚未下落是指)ground与被撞的上升沿处于同一时间,但由于时钟上升沿没到,state未变化
地面出现仍然处于下落是指ground=1,但由于下一上升沿没到,旅鼠仍然处于惊吓状态
若理解有误,请指正
有限状态机:
设计方法:三段法
注意事项:1、always 语句要注意如果外加posedge areset 注意语句块中要写清楚areset出现的情况发什么,因为当areset沿到来时,语句块不发生变化的话没有意义。会造成语句错误如:Error (10200): Verilog HDL Conditional Statement error at practice.v(32): cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct
2、需要清楚state和next_state由于在同一上升沿时的状态,由于Verilog的并行性,判断时的state仍然为上一周期的state,而next_state由于是组合逻辑输入,所以随时变化,即就是这一刻的输入影响下的state。
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output reg walk_left,
output reg walk_right,
output reg aaah );
reg [1:0] state,next_state;
parameter S0=0,S1=1,S2=2,S3=3;
always@(*)
begin
case(state)
S0:begin if(!ground) next_state<=S2; else if(bump_left) next_state<=S1; else next_state<=S0;end
S1:begin if(!ground) next_state<=S3; else if(bump_right) next_state<=S0;else next_state<=S1;end
S2:begin if(!ground) next_state<=S2; else next_state<=S0; end
S3:begin if(!ground) next_state<=S3; else next_state<=S1; end
endcase
end
always@(posedge clk,posedge areset)
begin
if(areset)
state<=S0;
else
state<=next_state;
end
always@(posedge clk,posedge areset)
begin
if(areset)//注意要说明areset的情况,否则会导致areset情况时没有语句没有作用而出现语句错误
begin
walk_left<=1;
walk_right<=0;
aaah<=0;end
else
if(!ground)
begin
aaah<=1;
walk_left<=0;
walk_right<=0;
end
else
begin
aaah<=0;
walk_left<=(state==S2)?1:((next_state==S0)?1:0); //注意后面这个是next_state不是state,因为后面这个在state状态过完后随时变化的,
walk_right<=(state==S3)?1:((next_state==S1)?1:0);//而如果是前一个的话在摔倒过后的周期state还未改变就进行判断导致不对
end
end
endmodule
本人vegetable,勿喷