Fsm serial_HDLbits详解

1、在许多(较旧的)串行通信协议中,每个数据字节与一个开始位和一个停止位一起发送,以帮助接收器从比特流中划分字节。一种常见的方案是使用一个起始位(0)、8个数据位和1个停止位(1)。当无任何传输(空闲)时,线路也处于逻辑1。

设计一个有限状态机,当给定一个比特流时,它将识别何时正确接收字节。它需要识别起始位,等待所有8个数据位,然后验证停止位是否正确。如果停止位未按预期出现,FSM必须等待找到停止位,然后再尝试接收下一个字节。

 这里我设置了五种状态变化:
 (1)默认态idel,in=0时到data,=1时保持 (2)数据输入data,维持8个clk 到stop0(3)停止信号的接收判断态stop0,in=1时到done(接收到停止态,完成输出),=0时到 stop1(继续等待停止信号);(4) 完成态done, in=1时到idel,=0时到data (5)未接收到停止信号时的判断态stop1,in=1时到idel(接收到停止信号,等待开始信号in=0),=0时保持。

这一题想了好久,状态图一定要画出来才明确一些。

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    reg [2:0] state,next_state; 
    //一定记得设置足够的位,好几次在修改过程中把bit写小了导致错误
    reg [3:0] cout;
    parameter idel=0,data=1,stop0=2,stop1=3,done0=4;
    always @(*)
        begin
            case(state)
                //五种状态变化:
                //(1)默认态idel (2)数据输入data (3)停止信号接收判断态stop0
                // (4) 完成态done  (5)未接收到停止信号时的判断态stop1
                idel : next_state<=(in)? idel:data;
                data : next_state<=(cout==4'd7)?stop0:data;
                stop0: next_state<=(in)? done0:stop1;
                done0: next_state <= (!in)? data:idel;
                stop1: next_state <= (in)? idel:stop1;
                
            endcase
        end
    
    always @(posedge clk)
        begin
            if(reset)
                state<=idel;
            else 
                begin
                	state<=next_state;
                    if(state==data) cout<=cout+1;
                    else cout<=0;
                end
        end
    assign done = (state==done0);
    //一开始没有设置done0状态,是在state==stop0时为1。但不匹配实际情况,应该是在state==idel且上一状态时stop0时,done=1;(在stop0时,要当in=1才算收到截至信号)

endmodule

Fsm serial_HDLbits详解_第1张图片

折磨了一晚上终于弄明白了/(ㄒoㄒ)/~~

你可能感兴趣的:(Verilog例题,fpga开发)