HDLBit 之 Fsm serialdp

1.原题复现

在这里插入图片描述

代码
思考过程

首先,可以根据上一题比较而言,这一题不过是多了一个校验位(这里要注意的是:这个校验位在停止位之前,校验位和停止位是分开的两个不同的bit,刚开始没写出来,就是因为这里没弄清楚)
上一题的题目见蓝色部分点击进入https://hdlbits.01xz.net/wiki/Fsm_serialdata
然后贴上该题的串行数据代码:

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
	parameter IDLE=0,START=1,bit0=2,bit1=3,bit2=4,bit3=5,bit4=6,bit5=7,bit6=8,bit7=9,STOP=11,DONE0=12,DONE1=13;
    reg[3:0]state,next_state;
    reg [7:0] mid_byte;
    always@(*)begin
        case(state)
            	IDLE:next_state = in?IDLE:START;
               START:next_state = bit0;
                bit0:next_state = bit1;
                bit1:next_state = bit2;
                bit2:next_state = bit3;
                bit3:next_state = bit4;
                bit4:next_state = bit5;
                bit5:next_state = bit6;
                bit6:next_state = bit7;
                bit7:next_state = in?STOP:DONE0;
                STOP:next_state = in?IDLE:START;
           		DONE0:next_state = in?IDLE:DONE0;
        endcase
    end
    
    always@(posedge clk)begin
        if(reset)begin
           state<= IDLE;
        end
        else begin
           state <=next_state; 
            case(state)
                START:mid_byte[0] <= in;
                bit0:mid_byte[1] <= in;
                bit1:mid_byte[2] <= in;
                bit2:mid_byte[3] <= in;
                bit3:mid_byte[4] <= in;
                bit4:mid_byte[5] <= in;
                bit5:mid_byte[6] <= in;
                bit6:mid_byte[7] <= in;
                default:mid_byte = mid_byte;
            endcase
        end
    end
    
    assign done = (state ==STOP);
    // Use FSM from Fsm_serial
	assign out_byte = done?mid_byte:0;
    // New: Datapath to latch input bits.
    // Use FSM from Fsm_serial

    // New: Datapath to latch input bits.

endmodule

本题是思路就是在该代码上进行改进:
本题思路捋顺之后会发现:

1.这里面多了一个状态bit8:该状态在停止位之前,用来输入校验位。
2.在接受校验位之后,进入停止状态的判断:

判断情况又分为三种:
1.当停止位有效时候,分为校验过后,1的个数为奇数
2.以及1的个数为偶数。
3.以及当停止位无效(in=0)。
一共三种情况。因此,停止状态后根据不同的条件应该列写出三种情况。

3.计数情况分析:

1.分析是奇数还是偶数,应当在进入相应的读取数据时候才开始分析,也就是说在IDLE,以及STOP状态下(当判断为有效数据时候,此时奇数的结果为1,不应该在对odd的取值进行分析,也就是此时应该复位为0.
2.通过上述1,我们可以了解,需要分析odd的变化情况应当处于:
START bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 (bit8状态时候,已经接受了校验位了,此时的状态是根据in来判断是否为停止位,不应当计入校验判断当中。)同时odd只有在满足: 处于这些状态下,而且需要输入的数据为1的时候才会发生变化。

据此,给出的代码为:

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
	parameter IDLE=0,START=1,bit0=2,bit1=3,bit2=4,bit3=5,bit4=6,bit5=7,bit6=8,bit7=9,bit8=10,STOP=11,DONE0=12,DONE1=13;
    reg[3:0]state,next_state;
    reg [8:0] d_s;
    wire p_s ,odd;
    always@(*)begin
        case(state)
            	IDLE:next_state = in?IDLE:START;
                START:next_state = bit0;
                bit0:next_state = bit1;
                bit1:next_state = bit2;
                bit2:next_state = bit3;
                bit3:next_state = bit4;
                bit4:next_state = bit5;
                bit5:next_state = bit6;
                bit6:next_state = bit7;
            	bit7:next_state = bit8;//进入第七位后,表明有效数据都传入了,接下来,接受奇偶校验位
                bit8: begin//进入bit8后,也就是接受校验位了,然后接下来根据结束位和校验位共同判断是否数据有效。
                    if(in & odd)
                        next_state = STOP;
                    else if (in & ~odd )
                        next_state = DONE1;
                    else 
                        next_state = DONE0;
                   end
                STOP:next_state = in?IDLE:START;
           		DONE0:next_state = in?IDLE:DONE0;
            	DONE1: next_state = in?IDLE:START;
        endcase
    end
    
    always@(posedge clk)begin
        if(reset)begin
           state<= IDLE;
        end
        else begin
           state <=next_state; 

        end
    end
    
    always@(posedge clk) begin
        if(reset)
            d_s <= 9'b0;
        else  begin
            case(state)//将输入的数据传递给中间存储的寄存器
           		START:d_s[0] <= in;  //在START状态时候,此时的in就是第一个数据
                bit0: d_s[1] <= in;
                bit1: d_s[2] <= in;
                bit2: d_s[3] <= in;
                bit3: d_s[4] <= in;
                bit4: d_s[5] <= in;
                bit5: d_s[6] <= in;
                bit6: d_s[7] <= in;
                bit7: d_s[8] <= in;
        endcase
        end
    end
    
    assign p_s = (state == START )|(state == bit0 )|(state == bit1 )|(state == bit2 )|(state == bit3 )|(state == bit4 )|(state == bit5 )|(state == bit6 )|(state == bit7); 
    
    wire  in2 ;
    
    assign in2 =  p_s &in;
    
    wire p_rst;
    assign p_rst = (reset |(state ==IDLE)|(state == STOP));
    parity instance1(clk,p_rst,in2,odd);
    assign done = (state == STOP );
    // Use FSM from Fsm_serial
    assign out_byte = done?d_s[7:0]:0;
    // Modify FSM and datapath from Fsm_serialdata
  
    // New: Add parity checking.

endmodule

参考的CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值