这几天在刷HDLBits,参考的是HDLBits中文导学专栏:HDLBits中文导学,刷到120题的时候发现缺少了中间的120题到126题的解析,就打算自己边写边记录一下。也方便其他的同学进行参考。
Problem 120 Simple FSM 1s
牛刀小试
一个很简单的状态机的题目,给定一个输入,两种状态,一个输出。注意复位的时候复位成B状态,复位采用同步复位。
解答与分析
这里我们采用三段式的写法来描述这个简单的状态机。
三段式状态机基本格式是:
- 采用组合逻辑判断状态转移条件
- 状态触发器实现
- 描述输出逻辑(既可以用组合电路输出,也可以用时序电路输出)
状态转移条件:根据输入信号以及当前的状态确定次态。
always @(*) begin case(state) B:next_state=in?B:A; A:next_state=in?A:B; endcase end
状态触发器实现,在时钟边沿实现状态寄存器的跳变以及状态复位
always @(posedge clk) begin if(reset) state<=B; else state<=next_state; end
输出逻辑,根据当前状态实现输出
assign out=state?1:0;
Problem 121 Simple FSM 2
牛刀小试
一个很简单的状态机的题目,给定两个输入,两种状态,一个输出。两种状态分别为开,关。复位的时候复位成OFF状态。复位采用异步复位,OFF状态输出0,ON状态输出1。
解答与分析
状态转移条件:根据输入信号以及当前的状态确定次态。
always @(*) begin case(state) OFF:next_state=j?ON:OFF; ON:next_state=k?OFF:ON; endcase end
状态触发器实现,在时钟边沿实现状态寄存器的跳变以及状态复位
always @(posedge clk, posedge areset) begin if(areset) state<=OFF; else state<=next_state; end
输出逻辑,根据当前状态实现输出
assign out=state?1:0;
Problem 122 Simple FSM 1s
牛刀小试
跟上题类似,只是复位方式不同而已,不再赘述。
Problem 123 Simple state transitions 3
牛刀小试
如图所示,一共有A,B,C,D四种状态。需要在满足特定输出的情况下进行状态转移和输出,state、next_state此时作为输入输出信号而不是内部信号。
解答与分析
如图所示,一共有A,B,C,D四种状态。状态转移逻辑和输出也很清晰的告诉了我们了。我们只要用状态机进行实现就可以了。
状态转移条件:根据输入信号以及当前的状态确定次态。
always @(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end
输出逻辑,根据当前状态实现输出
assign out=(state==D)?1:0;
Problem 124 Simple one-hot state transitions 3
牛刀小试
解答与分析
独热码状态机的正确写法。独热码状态机仅使用单bit表示状态,是否处在某一状态仅跟一个bit有关,而下个状态的转移也仅与一个bit有关。与其他bit无关。因此我们要按下面的写法写状态转移条件。
状态转移条件:根据输入信号以及当前的状态确定次态。
assign next_state[A] = state[A]&(in == 0) | state[C] & (in == 0); assign next_state[B] = state[A]&in | state[B]&in | state[D]∈ assign next_state[C] = state[B]&(in == 0) | state[D]&(in == 0); assign next_state[D] = state[C] & in;
输出逻辑,根据当前状态实现输出
assign out=(state[D])?1:0;
Problem 125 Simple FSM 3
牛刀小试
同样是一道状态机的题目,给定一个输入,四种状态,一个输出。复位采用异步复位,复位成A状态。D状态输出1,其他状态输出0
解答与分析
状态转移条件:根据输入信号以及当前的状态确定次态。
always @(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end
状态触发器实现,在时钟边沿实现状态寄存器的跳变以及状态复位
always @(posedge clk, posedge areset) begin if(areset) state<=A; else state<=next_state; end
输出逻辑,根据当前状态实现输出
assign out=(state==D)?1:0;
Problem 126 Simple FSM 3s
牛刀小试
解答与分析
跟上题类似,只是复位方式不同而已,不再赘述。直接给出代码
module top_module( input clk, input in, input reset, output out); // reg [1:0] state,next_state; parameter A=0,B=1,C=2,D=3; always @(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end always @(posedge clk) begin if(reset) state<=A; else state<=next_state; end assign out=(state==D)?1:0; endmodule