本节练习为状态机,是在应用中常使用的一个基础模块,希望能和大家一起牢牢掌握。
第一题:
正确答案:本题为异步复位的情况,下题为同步复位
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//
parameter A=0, B=1;
reg state, next_state;
always @(*) begin // This is a combinational always block
// State transition logic
case(state)
A:begin
if(in==1'b1)begin
next_state<=A;
end
else begin
next_state<=B;
end
end
B:begin
if(in==1'b1)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
第二题:本题与上题不同的是为同步复位,以下是正确答案及个人理解:
// 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 A=0,B=1;
reg present_state, next_state;
//状态机内部模块,与复位不相关
always@(*)begin
case(present_state)
A:if(in==1'b1)begin
next_state<=A;
end
else begin
next_state<=B;
end
B:
if(in==1'b1)begin
next_state<=B;
end
else begin
next_state<=A;
end
endcase
end
//同步复位部分,状态机复位情况
always @(posedge clk) begin
if (reset) begin
present_state<=B;
end
else begin
present_state<=next_state;
end
end
//赋值部分
assign out = (present_state==B);
endmodule
第三题:
2输入1输出,为异步状态复位;
正确答案:
这道题一开始有点犯傻,把case语句写成了jk,应该直接写成OFF和ON即可
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=0, ON=1;
reg present_state, next_state;
always @(*) begin
// State transition logic
case(present_state)
OFF:
if(j==1'b0)begin
next_state<=OFF;
end
else begin
next_state<=ON;
end
ON:
if(k==1'b0)begin
next_state<=ON;
end
else begin
next_state<=OFF;
end
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset)begin
present_state<=OFF;
end
else begin
present_state<=next_state;
end
end
assign out = (present_state == ON);
// Output logic
// assign out = (state == ...);
endmodule
第四题:FSM2
该题与上题的不同之处在于:本题为同步复位:
正确答案:
module top_module(
input clk,
input reset, // Synchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
// State transition logic
case(state)
OFF:
if(j==1'b1)begin
next_state<=ON;
end
else begin
next_state<=OFF;
end
ON:
if(k==1'b1)begin
next_state<=OFF;
end
else begin
next_state<=ON;
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
写到这里我还是不是很懂为什么要使用assign out==?这句话的,很不懂,但是之前也是这么写所以写了。
我的经验来看,就是一个always(*)case模块,一个always@(clk)模块,一个assign赋值模块;
第五题:FSM3:
下面是具有一个输入、一个输出和四个状态的Moore状态机的状态转换表。使用以下状态编码:A=2'b00, B=2'b01, C=2'b10, D=2'b11。
仅为此状态机实现状态转换逻辑和输出逻辑(组合逻辑部分)。给定当前状态(state),根据状态转换表计算next_state和输出(out)。
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out); //
parameter A=0, B=1, C=2, D=3;
always@(*)begin
case(state)
A:
if(in)begin
next_state<=B;
end
else begin
next_state<=A;
end
B:
if(in)begin
next_state<=B;
end
else begin
next_state<=C;
end
C:
if(in)begin
next_state<=D;
end
else begin
next_state<=A;
end
D:
if(in)begin
next_state<=B;
end
else begin
next_state<=C;
end
endcase
end
assign out = (state==D);
// State transition logic: next_state = f(state, in)
// Output logic: out = f(state) for a Moore state machine
endmodule
第六题:fsm3onehot:
下面是具有一个输入、一个输出和四个状态的Moore状态机的状态转换表。使用以下单热状态编码:A=4'b0001, B=4'b0010, C=4'b0100, D=4'b1000。
通过假设单热编码的检验,推导出状态转换和输出逻辑方程。仅为此状态机实现状态转换逻辑和输出逻辑(组合逻辑部分)。(测试台架将使用非一个热输入进行测试,以确保您没有尝试做更复杂的事情)。
下面有一部分What does "derive equations by inspection" mean?的相关理解,大概是该单热状态机的逻辑语言只需要用assign赋值表示时,可具有更简单的逻辑,达到仅通过一个状态位来判断状态。包括该题,意在让完成者使用assign语句来通过逻辑实现。
单热状态机编码保证只有一个状态位是1。这意味着可以通过仅检查一个状态位(而不是所有状态位)来确定状态机是否处于特定状态。通过检查状态转换图中每个状态的传入边,可以得到状态转换的简单逻辑方程。
例如,在上面的状态机中,状态机如何到达状态A?它必须使用两条传入边中的一条:“当前处于状态A且in=0”或“当前处于状态C且in=0”。由于单热编码,测试“当前处于状态A”的逻辑方程只是状态A的状态位。这导致状态位A的下一个状态的最终逻辑方程:next_state[0] = state[0]&(~in) | state[2]&(~in)。one-hot编码保证一次最多有一个子句(产品项)是“活动的”,因此这些子句只能被组合在一起。
当一个习题要求“通过检查”求状态转换方程时,使用这种特殊的方法。裁判将使用非一热输入进行测试,以确保您的逻辑方程遵循此方法,而不是对状态位的非法(非一热)组合执行其他操作(例如重置FSM)。
这种编程方法的好处是,可提升速度,该逻辑判断的状态改变只需要1bits。
正确答案:
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[A]&&~in)|(state[C]&&~in);
assign next_state[B] = (state[B]&&in)|(state[D]&&in)|(state[A]&&in);
assign next_state[C] = (state[D]&&~in)|(state[B]&&~in);
assign next_state[D] = (state[C]&&in);
// Output logic:
assign out = (state[D]);
endmodule
第七题:本题大意与上题相同,但使用异步复位
正确答案:
module top_module(
input clk,
input in,
input areset,
output out); //
parameter A=2'd0,B=2'd1,C=2'd2,D=2'd3;
reg[1:0]state;
reg[1:0]next_state;
// State transition logic
always@(*)begin
case(state)
A:
if(!in)begin
next_state<=A;
end
else begin
next_state<=B;
end
B:
if(!in)begin
next_state<=C;
end
else begin
next_state<=B;
end
C:
if(!in)begin
next_state<=A;
end
else begin
next_state<=D;
end
D:
if(!in)begin
next_state<=C;
end
else begin
next_state<=B;
end
endcase
end
// State flip-flops with asynchronous reset
always@(posedge clk,posedge areset)begin
if(areset)begin
state<=A;
end
else begin
state<=next_state;
end
end
assign out=(state==D);
// Output logic
endmodule
以上为状态机的上部分答案情况。