3.2.5.9 Design a Moore FSM
问题陈述:
还包括一个高电平有效同步复位,它将状态机复位到相当于水位长时间处于低位状态(没有传感器断言,并且所有四个输出都断言)。
Verilog代码:
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
parameter Bs1=0,bts1l=1,bts1h=2,bts2l=3,bts2h=4,As3=5;
reg [2:0]state ,next;
always@(*) begin
case(state)
Bs1:next=s[1]?bts1l:Bs1;
bts1l:next=s[2]?bts2l:(s[1]?bts1l:Bs1);
bts1h:next=s[2]?bts2l:(s[1]?bts1h:Bs1);
bts2l:next=s[3]?As3:(s[2]?bts2l:bts1h);
bts2h:next=s[3]?As3:(s[2]?bts2h:bts1h);
As3:next=s[3]?As3:bts2h;
default :next='x;
endcase
end
always@(posedge clk) begin
if(reset)
state<=Bs1;
else
state<=next;
end
always@(*) begin
case(state)
Bs1:{fr3,fr2,fr1,dfr}=4'b1111;
bts1l:{fr3,fr2,fr1,dfr}=4'b0110;
bts1h:{fr3,fr2,fr1,dfr}=4'b0111;
bts2l:{fr3,fr2,fr1,dfr}=4'b0010;
bts2h:{fr3,fr2,fr1,dfr}=4'b0011;
As3:{fr3,fr2,fr1,dfr}=4'b0000;
endcase
end
endmodule
3.2.5.10 Lemmings 1
问题陈述:
Lemmings这款游戏涉及大脑相当简单的小动物。如此简单,我们将会用有限状态机来建模。
在旅鼠的2D世界中,旅鼠可以处于两种状态之一:向左走或向右走。如果遇到障碍,它会改变方向。特别是,如果Lemming撞到左边,它会向右走。如果它撞到右边,它就会向左走。如果它同时在两边碰撞,它仍然会改变方向。
实现一个具有两个状态、两个输入和一个输出的摩尔状态机来模拟这种行为。
Verilog代码:
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
output walk_left,
output walk_right); //
reg state, next_state;
parameter left=0,right=1;
always @(*) begin
case(state)
left:next_state=bump_left? right:left;
right:next_state=bump_right? left:right;
endcase
end
always @(posedge clk, posedge areset) begin
if(areset)
state<=left;
else
state<=next_state;
end
assign walk_left=(state==left);
assign walk_right=(state==right);
endmodule
3.2.5.11 Lemmings 2
问题陈述:
除了左右行走,如果脚地面消失时,旅鼠还会摔倒(并且哈会发出“啊!”的叫声)。
除了左右行走和碰撞时改变方向,当ground=0时,旅鼠会摔倒
然后说“啊!”当地面重新出现时(ground=1),旅鼠将按照坠落前的相同方向继续行走。下落时被碰撞并不影响行走方向,在地面消失(但尚未下落)的同一周期中被碰撞,或在下落时地面再次出现,也不影响行走方向。
构建一个模拟此行为的有限状态机
Verilog代码:
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );
parameter left=1,right=2,fall_l=3,fall_r=4;
reg [2:0] state,next;
always@(*)begin
case(state)
left: next=ground?(bump_left? right:left):fall_l;
right:next=ground?(bump_right?left:right):fall_r;
fall_l:next=ground?left:fall_l;
fall_r:next=ground?right:fall_r;
endcase
end
always@(posedge clk,posedge areset)begin
if(areset)
state<=left;
else
state<=next;
end
assign walk_left=(state==left);
assign walk_right=(state==right);
assign aaah=(state==fall_l||state==fall_r);
endmodule
3.2.5.12 Lemmings 3
问题陈述:
除了行走和跌倒,旅鼠有时还会被告知做一些有用的事情,比如挖(当dig=1时,旅鼠开始挖)。如果旅鼠正在地面上行走(ground=1且没有下落),它可以挖洞,并会继续挖掘直到另一边(ground=0)。在这一点上,因为没有地面,它会掉下来(啊!),然后当它再次着地时,继续朝原来的方向走。和坠落时一样,在挖掘时被撞没有效果,在坠落或没有地面时被告知要挖掘也会被忽略
(换句话说,一只行走的旅鼠可以摔倒、挖洞或改变方向。如果满足上述条件中的多个,则fall的优先级高于dig,而dig的优先级高于切换方向。)
扩展您的有限状态机来建模这种行为。
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 left=0,right=1,dig_r=2,dig_l=3,fall_l=4,fall_r=5;
reg[2:0] state,next;
always@(*)begin
case(state)
left: next=ground?( dig?dig_l:(bump_left?right:left)):fall_l;
right:next=ground?(dig?dig_r:(bump_right?left:right)):fall_r;
dig_r:next=ground?dig_r:fall_r;
dig_l:next=ground?dig_l:fall_l;
fall_l:next=ground?left:fall_l;
fall_r:next=ground?right:fall_r;
endcase
end
always@(posedge clk, posedge areset) begin
if(areset)
state<=left;
else
state<=next;
end
assign walk_left=(state==left);
assign walk_right=(state==right);
assign digging=(state==dig_l||state==dig_r);
assign aaah=(state==fall_l||state==fall_r);
endmodule
3.2.5.13 Limmings 4
问题陈述:
尽管旅鼠会走路、跌倒和挖洞,但它们并非无懈可击。如果旅鼠跌落太久然后撞到地面,它可能会飞溅。特别地,如果旅鼠下落超过20个时钟周期撞到地面,它会飞溅并停止行走、下落或挖掘(所有4个输出都变成0),直到永远(或直到FSM重置)。旅鼠在落地前的坠落高度没有上限。旅鼠只有在撞击地面时才会飞溅;它们不会在半空中飞溅。·
扩展您的有限状态机来建模这种行为。
跌倒20个周期是可以生存的:
跌倒21个周期会导致飞溅:
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 left=0,right=1,dig_l=2,dig_r=3,fall_l=4,fall_r=5,splat=6;
reg [2:0] state,next;
reg [4:0]T;
reg signal;
always@(*) begin
case(state)
left: next=ground?(dig?dig_l:(bump_left?right:left)):fall_l;
right: next=ground?(dig? dig_r:(bump_right?left:right)):fall_r;
dig_l:next=ground?dig_l:fall_l;
dig_r :next=ground? dig_r:fall_r;
fall_l: begin
if(signal)
next=ground? splat:fall_l;
else
next=ground? left:fall_l;
end
fall_r: begin
if(signal)
next=ground?splat:fall_r;
else
next=ground? right:fall_r;
end
splat:next=splat;
endcase
end
always@(posedge clk, posedge areset) begin
if(areset)
T<=0;
else if(state==fall_l||state==fall_r)
begin
if(T==19)
signal<=1;
else
T<=T+1;
end
else
begin
signal<=0;
T<=0;
end
end
always@(posedge clk or posedge areset) begin
if(areset)
state<=left;
else
state<=next;
end
assign walk_left=(state==left);
assign walk_right=(state==right);
assign digging=(state==dig_l||state==dig_r);
assign aaah=(state==fall_l||state==fall_r);
endmodule
3.2.5.14 One-hot FSM
问题陈述:
给定以下具有1个输入和2个输出状态机:
假设此状态机使用One-hot编码,其中state[0]到state[9]分别对应于状态S0和S9。除非另有说明,否则输出为零。
实现状态机的状态转移逻辑和输出逻辑部分(但不是状态触发器)。您在state[9:0]中获得当前状态,并且必须生成next_state[9:0]和两个输出。假设one-hot编码,通过检查推导逻辑方程。(测试台将使用非一个热输入进行测试,以确保您不会尝试做更复杂的事情)。
Verilog代码:
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
assign next_state[0]= ~in&(state[0]|state[1]|state[2]|state[3]|state[4]|state[7]|state[8]|state[9]);
assign next_state[1]= in&(state[0]|state[8]|state[9]);
assign next_state[6:2]={in&state[5],in&state[4],in&state[3],in&state[2],in&state[1]};
assign next_state[7]= in&(state[6]|state[7]);
assign next_state[8]= ~in&state[5];
assign next_state[9]=~in&state[6];
//output
assign out1=(state[8]|state[9]);
assign out2=(state[7]|state[9]);
endmodule