目录
1、Simple FSM 1(asynchronous reset)——Fsm1
2、Simple FSM 1(synchronous reset)——Fsm1s
3、Simple FSM 2(asynchronous reset)——Fsm2
4、Simple FSM 2(synchronous reset)——Fsm2s
5、simple state transitions 3——Fsm3comb
6、Simple one-hot statetransitions 3——Fsm3onehot
7、Simple FSM 3(asynchronous reset)——Fsm3
8、Simple FSM 3(synchronous reset)——Fsm3s
9、Design a Moore FSM——Exams/ece241 2013 q4
FSM这一节分为了两篇,此部分为FSM的上篇内容。
1、Simple FSM 1(asynchronous reset)——Fsm1
本部分主要是参考题目给出的图的(异步复位)有限状态机,主要目的是了解状态机的主要知识。
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//
parameter A=1'b0, B=1'b1;
reg state, next_state;
always @(*) begin // This is a combinational always block
// State transition logic
case(state)
B: begin
if(in == 0)begin
next_state = A;
end
else begin
next_state = B;
end
end
A:begin
if(in == 0)begin
next_state = B;
end
else begin
next_state = A;
end
end
endcase
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if(areset)begin
state <= B;
end
else begin
state <= next_state;
end
end
// Output logic
// assign out = (state == ...);
assign out = (state == B);
endmodule
2、Simple FSM 1(synchronous reset)——Fsm1s
这个题目本身暗示我们用一段式来进行书写,当个人认为三段式是最方便理解且后期调试的。
// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
input clk;
input reset; // Synchronous reset to state B
input in;
output out;
reg out;
// Fill in state name declarations
parameter B=1'b0, A=1'b1;
reg present_state, next_state;
always@(posedge clk)begin
if(reset)begin
present_state <= B;
end
else begin
present_state <= next_state;
end
end
always@(*)begin
case(present_state)
B:begin
if(in == 1'b0)begin
next_state = A;
end
else begin
next_state = B;
end
end
A:begin
if(in == 0)begin
next_state = B;
end
else begin
next_state = A;
end
end
endcase
end
assign out = (present_state == B);
//out输出也可以使用标准三段式
/*
always@(*)begin
if(present_state == B) begin
out = 1'b1;
end
else begin
out = 1'b1;
end
end
*/
endmodule
3、Simple FSM 2(asynchronous reset)——Fsm2
这是一个Moore 状态机
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=1'b0, ON=1'b1;
reg state, next_state;
always @(*) begin
// State transition logic
case(state)
OFF:begin
if(j)begin
next_state = ON;
end
else begin
next_state = OFF;
end
end
ON:begin
if(k)begin
next_state = OFF;
end
else begin
next_state = ON;
end
end
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset)begin
state <= OFF;
end
else begin
state <= next_state;
end
end
// Output logic
// assign out = (state == ...);
assign out = (state == ON);
endmodule
4、Simple FSM 2(synchronous reset)——Fsm2s
module top_module(
input clk,
input reset, // Synchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=1'b0, ON=1'b1;
reg state, next_state;
always @(*) begin
// State transition logic
case(state)
OFF:begin
if(j)begin
next_state = ON;
end
else begin
next_state = OFF;
end
end
ON:begin
if(k)begin
next_state = OFF;
end
else begin
next_state = ON;
end
end
endcase
end
always @(posedge clk) begin
// State flip-flops with synchronous reset
if(reset)begin
state <= OFF;
end
else begin
state <= next_state;
end
end
// Output logic
// assign out = (state == ...);
assign out = (state == ON);
endmodule
5、simple state transitions 3——Fsm3comb
此部分只需要写组合逻辑和输出逻辑部分
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out); //
parameter A=2'b00, B=2'b01, C=2'b10, D=2'b11;
// State transition logic: next_state = f(state, in)
always@(*)begin
case(state)
A:begin
next_state = in ? B : A;
end
B:begin
next_state = in ? B : C;
end
C:begin
next_state = in ? D : A;
end
D:begin
next_state = in ? B : C;
end
endcase
end
// Output logic: out = f(state) for a Moore state machine
assign out = (state == D);
endmodule
6、Simple one-hot statetransitions 3——Fsm3onehot
相关翻译:
“通过检查得出方程”是什么意思?
One-hot 状态机编码保证恰好有一个状态位为 1。这意味着可以通过仅检查一个状态位而不是所有状态位来确定状态机是否处于特定状态。通过检查状态转换图中每个状态的输入边,这导致了状态转换的简单逻辑方程。
比如上面的状态机中,状态机如何才能达到状态A?它必须使用两个传入边之一:“当前处于状态 A 且 in=0”或“当前处于状态 C 且 in = 0”。由于 one-hot 编码,用于测试“当前处于状态 A”的逻辑方程只是状态 A 的状态位。这导致状态位 A 的下一个状态的最终逻辑方程:next_state[0] =状态[0]&(~in) |状态[2]&(~in)。 one-hot 编码保证一次最多有一个子句(乘积项)是“活动的”,因此这些子句可以被 ORed 在一起。
当练习要求“通过检查”获得状态转移方程时,请使用此特定方法。法官将使用非单热输入进行测试,以确保您的逻辑方程遵循此方法,而不是对状态位的非法(非单热)组合执行其他操作(例如重置 FSM)。
虽然知道这个算法对于 RTL 级设计(逻辑合成器处理这个)不是必需的,但它说明了为什么 one-hot FSM 通常具有更简单的逻辑(以更多的状态位存储为代价),并且这个主题经常显示参加数字逻辑课程的考试。
module top_module(
input in,
input [3:0] state,
output [3:0] next_state,
output out); //
parameter A=0, B=1, C=2, D=3;
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = state[0]&(~in) | state[2]&(~in);
assign next_state[B] = state[1]&( in) | state[0]&( in) | state[3]&( in);
assign next_state[C] = state[1]&(~in) | state[3]&(~in);
assign next_state[D] = state[2]&( in);
// Output logic:
assign out = (state[3] == 1'b1);
endmodule
7、Simple FSM 3(asynchronous reset)——Fsm3
分两种方法来完成,其中第一种方法采用前面一题的思路:采用One-Hot独热码状态机原理来编写,第二种就用最开始几道题的思路来完成,主要不同点就在于组合逻辑部分。
//方案一
module top_module(
input clk,
input in,
input areset,
output out); //
reg [3:0] current_state, next_state;
parameter A=0, B=1, C=2, D=3;
// State transition logic
assign next_state[A] = current_state[A]&~in | current_state[C]&~in ;
assign next_state[B] = current_state[B]&in | current_state[D]&in | current_state[A]∈
assign next_state[C] = current_state[B]&~in | current_state[D]&~in;
assign next_state[D] = current_state[C]∈
// State flip-flops with asynchronous reset
always@(posedge clk or posedge areset)begin
if(areset)begin
current_state <= 4'b0001;
end
else begin
current_state <= next_state;
end
end
// Output logic
assign out = (current_state[D] == 1'b1);
endmodule
module top_module(
input clk,
input in,
input areset,
output reg out); //
reg [1:0] current_state, next_state;
parameter A=2'd0, B=2'd1, C=2'd2, D=2'd3;
// State transition logic
always@(*)begin
case(current_state)
A:begin
if(in == 0)begin
next_state = A;
end
else begin
next_state = B;
end
end
B:begin
if(in == 0)begin
next_state = C;
end
else begin
next_state = B;
end
end
C:begin
if(in == 0)begin
next_state = A;
end
else begin
next_state = D;
end
end
D:begin
if(in == 0)begin
next_state = C;
end
else begin
next_state = B;
end
end
endcase
end
// State flip-flops with asynchronous reset
always@(posedge clk or posedge areset)begin
if(areset)begin
current_state <= A;
end
else begin
current_state <= next_state;
end
end
// Output logic
always@(*)begin
if(current_state == D)begin
out = 1'b1;
end
else begin
out = 1'b0;
end
end
endmodule
8、Simple FSM 3(synchronous reset)——Fsm3s
和前面差不多的,这里主要是从异步复位修改成了同步复位,只需要修改时序敏感列表中的敏感信号即可。
module top_module(
input clk,
input in,
input reset,
output reg out); //
parameter A=0, B=1, C=2, D=3;
reg [2:0] current_state, next_state;
// State transition logic
always@(*)begin
case(current_state)
A:begin
if(in == 0)begin
next_state = A;
end
else begin
next_state = B;
end
end
B:begin
if(in == 0)begin
next_state = C;
end
else begin
next_state = B;
end
end
C:begin
if(in == 0)begin
next_state = A;
end
else begin
next_state = D;
end
end
D:begin
if(in == 0)begin
next_state = C;
end
else begin
next_state = B;
end
end
endcase
end
// State flip-flops with synchronous reset
always@(posedge clk)begin
if(reset)begin
current_state <= A;
end
else begin
current_state <= next_state;
end
end
// Output logic
always@(*)begin
if(current_state == D)begin
out = 1'b1;
end
else begin
out = 1'b0;
end
end
endmodule
9、Design a Moore FSM——Exams/ece241 2013 q4
此篇主要就是偏实际应用的了,着重搞清楚这一篇的思路:如何划分出多少个状态,各个状态之间是怎么进行转换的。
这道题目根据题意,水管的3个探测器的电平变化相当于输入信号,可以分出6个状态出来,分别为:
- 没有任何水的状态A
- 中间状态B1,B2,C1,C2(B1、C1对应没有开额外补水阀的情况,即从低水位加到高水位进入的状态,而B2、C2为需要开额外补水阀的状态,即从高水位降到低水位的状态)
- 满水状态D
module top_module (
input clk,
input reset,
input [3:1] s,
output reg fr3,
output reg fr2,
output reg fr1,
output reg dfr
);
parameter A=3'd0, B1=3'd1, B2=3'd2, C1=3'd3, C2=3'd4, D=3'd5;
reg [2:0] current_state, next_state;
always@(*)begin
case(current_state)
A:next_state = s[1] ? B1 : A;
B1:next_state = s[2] ? C1 : (s[1] ? B1 : A);
C1:next_state = s[3] ? D : (s[2] ? C1 : B2);
D:next_state = s[3] ? D : C2;
C2:next_state = s[3] ? D : (s[2] ? C2 : B2);
B2:next_state = s[2] ? C1 : (s[1] ? B2 : A);
default: next_state = 'x;
endcase
end
always@(posedge clk)begin
if(reset)begin
current_state <= A;
end
else begin
current_state <= next_state;
end
end
always@(*)begin
case(current_state)
A: {fr3, fr2, fr1, dfr} = 4'b1111;
B1: {fr3, fr2, fr1, dfr} = 4'b0110;
B2: {fr3, fr2, fr1, dfr} = 4'b0111;
C1: {fr3, fr2, fr1, dfr} = 4'b0010;
C2: {fr3, fr2, fr1, dfr} = 4'b0011;
D: {fr3, fr2, fr1, dfr} = 4'b0000;
default: {fr3, fr2, fr1, dfr} = 'x;
endcase
end
endmodule
10、Lemmings1
此部分将进入一个逐步递进试的题目,主要对象是写一个旅鼠游戏,详情可以看题目,这个部分的内容有很强的递进逻辑思维,后面的题目需要前面题目的基础上增加一些逻辑,逐步完善成一个游戏。
本题是一个旅鼠游戏,就是像自动小车一样,假设有两个车道,小车只能处于其中一个车道,当小车在此车道遇到障碍物时,就会选择另外一个车道继续行驶
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
output walk_left,
output walk_right); //
// parameter LEFT=0, RIGHT=1, ...
parameter left = 0, right = 1;
reg state, next_state;
always @(*) begin
// State transition logic
case(state)
left: next_state = bump_left ? right : left;
right:next_state = bump_right? left : right;
default next_state = 'x;
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset)begin
state <= left;
end
else begin
state <= next_state;
end
end
assign walk_left = (state == left);
assign walk_right = (state == right);
// Output logic
// assign walk_left = (state == ...);
// assign walk_right = (state == ...);
endmodule
11、Lemmings2
此题目为第一题的递进版本,引入了上下空间的元素,从状态机上来看就相当于新引入了两个状态。此处逻辑和上一题是一样的,此题在组合逻辑部分采用了与上一题不同的方式进行编写。
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 );
//状态定义,定义4个状态,分别为:1、向左走, 2、像右走,3、左走时跌落,4、右走时跌落
parameter left = 2'd0, right = 2'd1, fall_left = 2'd2, fall_right = 2'd3;
reg [1:0] state, next_state;
always@(*)begin
case(state)
left:next_state = ground ? (bump_left ? right : left) : fall_left;
right:next_state = ground ? (bump_right ? left : right) : fall_right;
fall_left:next_state = ground ? left : fall_left;
fall_right:next_state = ground ? right : fall_right;
default: next_state = 'x;
endcase
end
always@(posedge clk or posedge areset)begin
if(areset)begin
state <= left;
end
else begin
state <= next_state;
end
end
assign walk_left = (state == left);
assign walk_right = (state == right);
assign aaah = (state == fall_left) || (state == fall_right);
endmodule
12、Lemmings3
本题就是同理在第二道题目的基础上加入了挖掘的动作。
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 );
//状态定义,定义4个状态,分别为:1、向左走, 2、像右走,3、左走时跌落,4、右走时跌落
parameter left = 3'd0, right = 3'd1, fall_left = 3'd2, fall_right = 3'd3, dig_left = 3'd4, dig_right = 3'd5;
reg [2:0] state, next_state;
always@(*)begin
case(state)
left:next_state = ground ? (dig ? dig_left : (bump_left ? right : left)) : fall_left;
right:next_state = ground ? (dig ? dig_right : (bump_right ? left : right)) : fall_right;
fall_left:next_state = ground ? left : fall_left;
fall_right:next_state = ground ? right : fall_right;
dig_left:next_state = ground ? dig_left : fall_left;
dig_right:next_state = ground ? dig_right : fall_right;
default: next_state = 'x;
endcase
end
always@(posedge clk or posedge areset)begin
if(areset)begin
state <= left;
end
else begin
state <= next_state;
end
end
assign walk_left = (state == left);
assign walk_right = (state == right);
assign aaah = (state == fall_left) || (state == fall_right);
assign digging = (state == dig_left) || (state == dig_right);
endmodule
13、Lemmings4
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 );
//状态定义,定义7个状态,分别为:1、向左走, 2、像右走,3、左走时跌落,4、右走时跌落,5、挖掘_左走状态,挖掘_右走状态,6、摔了(splatter)
parameter left = 3'd0, right = 3'd1, fall_left = 3'd2, fall_right = 3'd3, dig_left = 3'd4, dig_right = 3'd5, splatter = 3'd6;
reg [2:0] state, next_state;
//integer cnt; //使用integer型就可以编译成功
reg [31:0] cnt; //此处我使用了reg型变量作为寄存器就编译不成功
//-> 已解决主要本人在此处定的reg型变量cnt的位宽不够,在短时间内可以满足fall计时任务
//但是如果超出了计时寄存器的位宽的话就会出现错误
always@(*)begin
case(state)
left:next_state = ground ? (dig ? dig_left : (bump_left ? right : left)) : fall_left;
right:next_state = ground ? (dig ? dig_right : (bump_right ? left : right)) : fall_right;
//前面部分进行判断,因此本题可以有两种方案:1:在落地的时候进行状态变换;2:在落地前进行状态变换。
fall_left:next_state = ground ? ((cnt > 32'd19) ? splatter : left) : fall_left;
fall_right:next_state = ground ? ((cnt > 32'd19) ? splatter : right) : fall_right;
dig_left:next_state = ground ? dig_left : fall_left;
dig_right:next_state = ground ? dig_right : fall_right;
splatter:next_state = splatter;
default: next_state = left;
endcase
end
always@(posedge clk or posedge areset)begin
if(areset)begin
state <= left;
end
else begin
state <= next_state;
end
end
always@(posedge clk or posedge areset)begin
if(areset)begin
cnt <= 32'd0;
end
//此处需要用 '||(逻辑或)'逻辑操作符,之前没注意,便使用的为 '|(或)'按位操作符
//此处没什么影响,但需要形成良好习惯
else if(state == fall_left || state == fall_right)begin
cnt <= cnt + 1'd1;
end
else begin
cnt <= 32'd0;
end
end
assign walk_left = (state == left);
assign walk_right = (state == right);
assign aaah = (state == fall_left) || (state == fall_right);
assign digging = (state == dig_left) || (state == dig_right);
endmodule