3.2.5.20 Design a Mealy FSM
问题陈述:
实现一个Mealy类型的有限状态机,它可以识别名为x的输入信号上的序列“101”。您的FSM应该有一个输出信号z,当检测到“101”序列时,它被断言为逻辑1.您的FSM还应该有一个低电平有效的异步复位。您的状态机中可能只有3个状态。您的FSM应该能够识别重叠序列
Verilog代码:
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z );
parameter s0=2'b00,s1=2'b01,s2=2'b10;
wire [1:0]state,next;
always@(posedge clk or negedge aresetn)
begin
if(!aresetn)
state<=s0;
else
state<=next;
end
always@(*)
begin
case(state)
s0:next=x?s1:s0;
s1:next=x?s1:s2;
s2:next=x?s1:s0;
default:next=s0;
endcase
end
always@(*)
begin
case(state)
s0:z=0;
s1:z=0;
s2:z=x;
endcase
end
endmodule
3.2.5.21 Q5a:Serial two’s complementer (Moore FSM)
问题陈述:
你要设计一个单输入单输出串行2的补码摩尔状态机。输入(x)是一系列位(每个时钟周期一个),从数字的最低位有效位开始,输出(z)是输入的2的补码。机器将接受任意长度的输入数字。该电路需要异步复位。转换在释放复位时开始,在复位时停止。
例如:
Verilog代码:
module top_module (
input clk,
input areset,
input x,
output z
);
parameter A=0,B=1,C=2;
wire [1:0]state,next;
always@(posedge clk or posedge areset)
begin
if(areset)
state<=A;
else
state<=next;
end
always @(*)
begin
case(state)
A:next=x?B:A;
C:next=x?C:B;
B:next=x?C:B;
endcase
end
assign z=(state==B);
endmodule
3.2.5.22 Serial two’s complementer (Mealy FSM)
问题陈述:
下图是2的补码的Mealy机器实现。使用one-hot 编码实现。
Verilog代码:
module top_module (
input clk,
input areset,
input x,
output z
);
parameter A=1'b01,B=1'b10;
wire [1:0]state,next;
always@(posedge clk or posedge areset)
begin
if(areset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=x?B:A;
B:next=B;
endcase
end
always@(*)
begin
case(state)
A:z=x;
B:z=~x;
endcase
end
endmodule
3.2.5.23 FSM
问题陈述:
考虑一个有输入s和w的有限状态机。假设FSM以A为复位状态开始,如下所示。当s = 0时,FSM一直处于A状态,当s = 1时,FSM转移到B状态。一旦进入状态B, FSM在接下来的三个时钟周期内检查输入w的值。如果其中两个时钟周期w = 1,则FSM必须在下一个时钟周期中将输出z设置为1。否则z必须为0。FSM将继续检查w接下来的三个时钟周期,以此类推。下面的时序图说明了不同w值所需的z值。
使用尽可能少的状态。注意,s输入只在状态A中使用,因此您只需要考虑w输入。
Verilog代码:
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter A=1'b0,B=1'b1;
reg state,next;
reg w0,w1;
reg[1:0] counter;
always@(posedge clk)
begin
if(reset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=s?B:A;
B:next=B;
endcase
end
always@(posedge clk)
begin
if(reset)begin
w0<=1'b0;
w1<=1'b0;
end
else if(state==B)
begin
w0<=w;
w1<=w0;
end
else
begin
w0<=1'b0;
w1<=1'b0;
end
end
always@(posedge clk)
begin
if(reset)
z<=1'b0;
else if((state==B)&&(counter==2'd0))
begin
if(w&w0&~w1|w&~w0&w1|~w&w0&w1)
z<=1'b1;
else
z<=1'b0;
end
else
z<=1'b0;
end
always@(posedge clk)
begin
if(reset)
counter<=2'd0;
else if(counter==2'd2)
counter<=2'd0;
else if(next==B)
counter<=counter+1'b1;
end
endmodule
3.2.5.24 Q3b:FSM
问题陈述:
给定如下所示的状态分配表,实现有限状态机。重置应该将FSM重置状态000.
Verilog代码:
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100;
reg [2:0] state,next;
always@(posedge clk)
begin
if(reset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=x?B:A;
B:next=x?E:B;
C:next=x?B:C;
D:next=x?C:B;
E:next=x?E:D;
endcase
end
assign z=((state==D)||(state==E));
endmodule
3.2.5.25 Q3c:FSM logic
问题陈述:
给定如下所示的状态分配表,实现逻辑函数Y[0]和z。
Verilog代码:
module top_module (
input clk,
input [2:0] y,
input x,
output Y0,
output z
);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100;
reg [2:0] next;
always@(*)
begin
case(y)
A:next=x?B:A;
B:next=x?E:B;
C:next=x?B:C;
D:next=x?C:B;
E:next=x?E:D;
endcase
end
assign Y0=((next==B)||(next==D));
assign z=((y==D)||(y==E));
endmodule
3.2.5.26 Q6b:FSM next-state logic
问题陈述:
考虑如下所示的状态机,它有一个输入w和一个输出z。
假设您希望使用三个触发器和状态代码y[3:1]=000,001,…,101分别用于状态A、B、…F来实现FSM。显示此FSM的状态分配表。导出触发器y[2]的下一个状态表达式。
只为y[2]实现下一个状态逻辑。(这更像是一个FSM问题,而不是Verilog编码问题。)
Verilog代码:
module top_module (
input [3:1] y,
input w,
output Y2);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100,F=3'b101;
reg [2:0]next;
always@(*)
begin
case(y)
A:next=w?A:B;
B:next=w?D:C;
C:next=w?D:E;
D:next=w?A:F;
E:next=w?D:E;
F:next=w?D:C;
endcase
end
assign Y2=((next==C)||(next==D));
endmodule
3.2.5.27 Q6c:FSM one-hot next-state logic
问题陈述:
考虑如下所示的状态机,它有一个输入w和一个输出z。
对于一部分,假设状态分配y[6:1]=000001,000010,000100,001000,010000,100000分别表示A、B、…、F的one-hot代码。
为下一个状态信号Y2和Y4编写逻辑表达式。(通过假设one-hot编码的检查推导出逻辑方程。测试台将使用非one-hot 输入进行测试,以确保您不会尝试做更复杂的事情)
Verilog代码:
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);
parameter A=6'b000001,B=6'b000010,C=6'b000100,D=6'b001000,E=6'b010000,F=6'b100000;
reg [6:1]next;
always@(*)
begin
case(y)
A:next=w?A:B;
B:next=w?D:C;
C:next=w?D:E;
D:next=w?A:F;
E:next=w?D:E;
F:next=w?D:C;
endcase
end
assign Y2=~w&y[1];
assign Y4=w&(y[2]|y[3]|y[5]|y[6]);
endmodule
3.2.5.28 Q6:FSM
问题陈述:
考虑如下所示的状态机,它有一个输入w和一个输出z。
实现状态机。(这部分不在其中,但是编写FSM是一种很好的做法)。
Verilog代码:
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100,F=3'b101;
reg [2:0]state,next;
always@(posedge clk)
begin
if(reset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=w?A:B;
B:next=w?D:C;
C:next=w?D:E;
D:next=w?A:F;
E:next=w?D:E;
F:next=w?D:C;
endcase
end
assign z=((state==E)||(state==F));
endmodule
3.2.5.29 Q2a:FSM
问题陈述:
考虑如下所示的状态图。
编写代表此FSM的完整的Verilog代码。就像在讲座中所做的那样,对状态表和状态触发器使用单独的always块。使用连续赋值语句或always块(由您自行决定)描述FSM输出,称为z。分配您希望使用的代码。
Veriolg代码:
module top_module (
input clk,
input reset, // Synchronous active-high reset
input w,
output z
);
parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100,F=3'b101;
reg [2:0] state,next;
always@(posedge clk)
begin
if(reset)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:next=w?B:A;
B:next=w?C:D;
C:next=w?E:D;
D:next=w?F:A;
E:next=w?E:D;
F:next=w?C:D;
endcase
end
assign z=((state==E)||(state==F));
endmodule
3.2.5.30 Q2b:one-hot FSM equation
问题陈述:
这个问题状态图再次显示在下面。
假设在状态分配y[5:0]=000001(A),000010(B),000100©,001000(D),
010000(E),100000(F)中使用one-hot代码
为信号Y1写出一个逻辑表达式,它是触发器y[1]的输入。
为信号Y3写出一个逻辑表达式,它是触发器y[3]的输入。
(通过假设one-hot编码的检查推导出逻辑方程。测试台将使用非one-hot 输入进行测试,以确保您不会尝试做更复杂的事情)
Verilog代码:
module top_module (
input [5:0] y,
input w,
output Y1,
output Y3
);
assign Y1=w&y[0];
assign Y3=~w&(y[1]|y[2]|y[4]|y[5]);
endmodule
3.2.5.31 Q2a:FSM
问题陈述:
考虑下图所示状态图描述的FSM:
该FSM充当仲裁电路,控制三个请求设备对某种类型资源的访问。每个设备通过设置信号r[i] = 1来请求资源,其中r[i]要么是r[1], r[2],要么是r[3]。每个r[i]是FSM的一个输入信号,代表三个设备中的一个。只要没有请求,FSM一直保持A状态。当一个或多个请求发生时,FSM决定哪个设备获得使用资源的授权,并将该设备的g[i]信号设置为1。每个g[i]都是来自FSM的一个输出。存在一个优先级系统,即设备1的优先级高于设备2,设备3的优先级最低。因此,例如,设备3只有在它是唯一发出请求的设备时才会收到授权。当设备i从FSM获得授权后,只要设备的请求r[]= 1,该设备就会继续获得授权。编写完整的Verilog代码来表示这个FSM。对状态表和状态触发器使用单独的always块,就像在讲座中所做的那样。描述FSM输出,glil,使用连续赋值语句或always块(由您自行决定)。指定您希望使用的任何状态代码。
Verilog代码:
module top_module (
input clk,
input resetn, // active-low synchronous reset
input [3:1] r, // request
output [3:1] g // grant
);
parameter A=2'd0,B=2'd1,C=2'd2,D=2'd3;
reg[2:0]state,next;
always@(posedge clk)
begin
if(!resetn)
state<=A;
else
state<=next;
end
always@(*)
begin
case(state)
A:begin
if(r[1])
next=B;
else if(~r[1]&r[2])
next=C;
else if(~r[1]&~r[2]&r[3])
next=D;
else if(~r[1]&~r[2]&~r[3])
next=A;
end
B:next=r[1]?B:A;
C:next=r[2]?C:A;
D:next=r[3]?D:A;
endcase
end
assign g[1]=(state==B);
assign g[2]=(state==C);
assign g[3]=(state==D);
endmodule
3.2.5.32 Q2b:Another FSM
问题陈述:
考虑一个有限状态机,用来控制某种类型的电机。FSM有来自电机的输入x和y,产生控制电机的输出f和g。还有一个时钟输入叫做clk和一个重置输入叫做resetn。
FSM的工作原理如下:只要重置输入被置位,FSM就保持在开始状态,称为状态A。当重置信号无效时,在下一个时钟边缘之后,FSM必须在一个时钟周期内将输出f设置为1。然后,FSM需要监控x的输入。当x在三个连续的时钟周期中产生值1,0,1时,那么g应该在下一个时钟周期中设置为1。当保持g = 1时,FSM必须监视y输入。如果y在最多两个时钟周期内设置为1,则FSM应永久保持g = 1(即直到复位)。但是如果y在两个时钟周期内没有变成1,那么FSM应该永久设置g = 0(直到重置)。(最初的考试题目只要求一个状态图。但在这里,要实施FSM。)
Verilog代码:
module top_module (
input clk,
input resetn, // active-low synchronous reset
input x,
input y,
output f,
output g
);
parameter IDEL=4'd0,START=4'd1,A=4'd2,B=4'd3,C=4'd4,D=4'd5,E=4'd6,FONE=4'd7,FZERO=4'd8;
reg[3:0]state,next;
always@(posedge clk)
begin
if(!resetn)
state<=IDEL;
else
state<=next;
end
always@(*)
begin
case(state)
IDEL:next=START;
START:next=A;
A:next=x?B:A;
B:next=x?B:C;
C:next=x?D:A;
D:next=y?FONE:E;
E:next=y?FONE:FZERO;
FONE:next=FONE;
FZERO:next=FZERO;
endcase
end
assign f=(state==START);
assign g=((state==D)||(state==E)||(state==FONE));
endmodule