HDLBits刷题记录——FSM之Serial receiver with parity checking

导言

状态机这部分我一直理解得不太清楚,这一章节得习题花了比较长的时间。带校验码的串行接收器这题本身也不是非常难,解题关键在于读懂题目。HDLBits的题目往往由简到难,这道题之前有只要求描述状态转移以及FSM加Datapath两题。

  • 串行接收器的传输协议是1bit开始标志位+8bit数据+1bit结束标志位。开始接收标志是in=0,满足条件后连续传输1byte即8bit的数据(LSB到MSB),结束接收标志是in=1。
  • 传输线空闲IDLE时,输入in为置高状态。如果检测不到结束标志,则持续检测直到in=1出现,此时没有done信号的输出并丢弃此周期传输的数据。
  • 需要注意的是:观察波形可以看出,输出信号done是在接收结束后的下一个周期有效。输出的数据是在done有效的时候进行输出。
  • 采取奇校验的方式验证数据传输正确与否,因而多了1bit的校验位。done输出的条件变成:数据接收结束并且校验通过。

思路

  • FSM转换是关键,包括空闲状态、数据传输状态、校验状态、结束状态、等待状态。
    • IDLE:空闲状态,等待传输开始标志。一旦检测到0,则进入下一状态。
    • START:表示数据接收开始,可立即进入数据传输状态。
    • S0~S7:S0到S7都是数据传输状态,原则是这一位传完即对下一位传输。在最后一位数据传输完成以后,进入PARITY状态。
    • PARITY:校验传输状态,一方面根据此刻parity模块的输出信号odd来判断校验结果,另一方面根据此状态下in的值判断是否进入STOP状态。
    • STOP:进入结束状态则表明传输完成,检测下一轮接收开始信号。若按照预期的情况出现,则可以进入IDLE状态准备下一轮接收;否则进入WAIT。
    • WAIT:结束标志位没有按照预期的情况出现,说明接收不成功。停留在此状态,直到结束标志位出现,一旦出现即可进入IDLE状态准备下一轮接收。
  • done信号出现的时刻是STOP状态的下一时刻(见波形图)。红圈是parity校验位采集沿,绿圈是结束标志位采集沿,起作用的odd值正是两个圈中间的时间段。
    在这里插入图片描述

代码

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); 
    // Modify FSM and datapath from Fsm_serialdata
    parameter IDLE=4'd0,START=4'd1,S0=4'd2,S1=4'd3,S2=4'd4,S3=4'd5,S4=4'd6;
    parameter S5=4'd7,S6=4'd8,S7=4'd9,PARITY=4'd10,STOP=4'd11,WAIT=4'd12;
    reg [3:0] state,next;
    
    always@(posedge clk) begin
        if(reset) begin
            state <= IDLE;
        end
        else begin
            state <= next;
        end
    end
   
    always@(*) begin
        case(state)
            IDLE: next = in ? IDLE:START;
            START: next = S0;
            S0: next = S1;
            S1: next = S2;
            S2: next = S3;
            S3: next = S4;
            S4: next = S5;
            S5: next = S6;
            S6: next = S7;
            S7: next = PARITY;
            PARITY: next = in ? STOP:WAIT;
            STOP: next = in ? IDLE:START;
            WAIT: next = in ? IDLE:WAIT;
        endcase
    end
    
    reg [7:0] out_reg;
    always@(posedge clk) begin
        if(reset) begin
            out_reg <= 8'b0;
        end
        else begin
            case(next)
                S0: out_reg[0] <= in;
                S1: out_reg[1] <= in;
                S2: out_reg[2] <= in;
                S3: out_reg[3] <= in;
                S4: out_reg[4] <= in;
                S5: out_reg[5] <= in;
                S6: out_reg[6] <= in;
                S7: out_reg[7] <= in;
                PARITY: out_reg <= out_reg;
                STOP: out_reg <= out_reg;
                default: out_reg <= 8'b0;
            endcase
        end
    end 
    
    always@(posedge clk) begin
        if(reset) begin
            done <= 1'b0;
        end
        else if(next == STOP && odd == 1'b1) begin
            done <= 1'b1;
        end
        else begin
            done <= 1'b0;
        end
    end
    
    always@(posedge clk) begin
        if(reset) begin
            out_byte <= 8'b0;
        end
        else if(next == STOP && odd == 1'b1) begin
            out_byte <= out_reg;
        end
        else begin
            out_byte <= 8'b0;
        end
    end            
//    assign done = (state == STOP && odd == 1'b1);
//    assign out_byte = done ? out_reg:8'b0;        

    // New: Add parity checking.
    wire odd,reset_p;
    assign reset_p = (next == START || reset == 1'b1);
    parity U(clk,reset_p,in,odd);
  
endmodule

其中校验模块是题目给定的:

module parity (
    input clk,
    input reset,
    input in,
    output reg odd);

    always @(posedge clk)
        if (reset) odd <= 0;
        else if (in) odd <= ~odd;

endmodule

小结

  • 个人认为此题比较重要的是done什么时候输出,即在何状态下可以输出done。这里需要注意一下三段式状态机的输出逻辑的写法:当前状态作判断条件+组合逻辑、下一状态作判断条件+时序逻辑。
  • 此题的前两题都是Moore型状态机,这题是Mealy型状态机。前者的输出只和状态有关;后者的输出不仅与状态有关,还与输入有关。
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值