HDLBits-Exams/review2015 fsm
problem statement
这是五个系列练习中的第四个部分,它从几个小的电路中建立了一个复杂的计数器。请看最后的练习,了解整体设计。
你可能希望先做FSM: 启用移位寄存器和FSM: 序列识别器。
我们想创建一个定时器。
1、当检测到一个特定的模式(1101)时启动。
2、再移入4位以确定延迟的时间。
3、等待计数器完成计数,并
4、通知用户,并等待用户确认该定时器。
在这个问题中,只实现控制定时器的有限状态机。这里不包括数据路径(计数器和一些比较器)。
串行数据可以在数据输入引脚上获得。当接收到模式1101时,状态机就必须断言输出shift_ena,正好4个时钟周期。
之后,状态机断言其计数输出,以表明它正在等待计数器,并等待直到输入done_counting为高电平。
在这一点上,状态机必须断言done,以通知用户计时器已经超时,并等待输入ack为1,然后被重置,以寻找下一个出现的启动序列(1101)。
状态机应该复位到一个开始搜索输入序列1101的状态。
下面是一个预期输入和输出的例子。x "状态可能会让人读起来有点困惑。它们表示FSM在那个周期不应该关心那个特定的输入信号。例如,一旦检测到1101模式,FSM就不再看数据输入,直到它在其他事情完成后重新开始搜索。
分析:从题目中可以设置如下状态A,B,C,D,E,F,G;
A:初始状态,B:data[1]数据状态,C:data[2]数据状态,D:data[3]数据状态
E:data[4]数据状态,F:四个周期延迟状态,G:用户等待状态。
module top_module ( input clk, input reset, // Synchronous reset input data, output shift_ena, output counting, input done_counting, output done, input ack ); parameter A=0,B=1,C=2,D=3,E=4,F=5,G=6; reg [3:0] state,n_state,count; always@(posedge clk)begin if(reset) count<=4'd0; else if(state==E)begin if(count==4'd3) count<=0; else count <=count+1'b1; end else count<=count; end always@(*)begin case(state) A:n_state = (data==1)?B:A; B:n_state = (data==1)?C:A; C:n_state = (data==0)?D:C; D:n_state = (data==1)?E:A; E:n_state = (count==4'd3)?F:E; F:n_state = (done_counting==1)?G:F; G:n_state = (ack==1)?A:G; endcase end always@(posedge clk)begin if(reset) state<=A; else state<=n_state; end assign shift_ena =(state==E)?1:0; assign counting = (state==F)?1:0; assign done =(state==G)?1:0; endmodule