HDLBits 系列(39)求解带有奇校验的串口接收数据的简化电路设计

目录

求助原题

我的方案

状态转移图

我的设计

等待你的方案?


求助原题

先给出原题:(蓝色字体,即是链接本身)

We want to add parity checking to the serial receiver. Parity checking adds one extra bit after each data byte. We will use odd parity, where the number of 1s in the 9 bits received must be odd. For example, 101001011 satisfies odd parity (there are 5 1s), but 001001011 does not.

Change your FSM and datapath to perform odd parity checking. Assert the done signal only if a byte is correctly received and its parity check passes. Like the serial receiver FSM, this FSM needs to identify the start bit, wait for all 9 (data and parity) bits, then verify that the stop bit was correct. If the stop bit does not appear when expected, the FSM must wait until it finds a stop bit before attempting to receive the next byte.

You are provided with the following module that can be used to calculate the parity of the input stream (It's a TFF with reset). The intended use is that it should be given the input bit stream, and reset at appropriate times so it counts the number of 1 bits in each byte.

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

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

endmodule

Note that the serial protocol sends the least significant bit first, and the parity bit after the 8 data bits.

HDLBits 系列(39)求解带有奇校验的串口接收数据的简化电路设计_第1张图片

我的方案

如何用状态机设计这个电路呢?

求助路过的同行尝试做下这个题?

如果能Success,希望能告知一下,感谢。

我已经把不带奇偶校验的设计给出,如下:

https://blog.csdn.net/Reborn_Lee/article/details/103438860

https://blog.csdn.net/Reborn_Lee/article/details/103439297

最后给出我的不成功的方案:

状态转移图

HDLBits 系列(39)求解带有奇校验的串口接收数据的简化电路设计_第2张图片

我的设计

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
    // Use FSM from Fsm_serial
    localparam START = 0, B1 = 1, B2 = 2, B3 = 3, B4 = 4, B5 = 5, B6 = 6, B7 = 7, B8 = 8, B9 = 9, STOP = 10, D0 = 11, D1 = 12, D2 = 13;
    reg [3:0] state, next_state;
    wire odd;
    wire en;
    reg [7:0] out_byte_mid;
    always@(*) begin
        case(state)
            START: begin
                if(~in) next_state = B1;
                else next_state = START;
            end
            B1: begin
                next_state = B2;
            end
            B2: begin
                next_state = B3;
            end
            B3: begin
                next_state = B4;
            end
            B4: begin
                next_state = B5;
            end
            B5: begin
                next_state = B6;
            end
            B6: begin
                next_state = B7;
            end
            B7: begin
                next_state = B8;
            end
            B8: begin
                next_state = B9;
            end
            B9: begin
                next_state = STOP;
            end
            STOP: begin
                if(in&&odd) next_state = D0;
                else if(in&&(~odd)) next_state = D2;
                else next_state = D1;
            end
            D0: begin
                if(in == 1) next_state = START;
                else next_state = B1;
            end
            D1: begin
                if(in == 0) next_state = D1;
                else next_state = START;
            end
            D2: begin
                if(in) next_state = D2; 
                else next_state = B1;
            end
            default: begin
                next_state = START;
            end
            
        endcase
    end
    
    always@(posedge clk) begin
        if(reset) state <= START;
        else state <= next_state;
    end
    
    always@(*) begin
        case(state)
            START: begin
                ;
            end
            B1: begin
                out_byte_mid[0] = in;
            end
            B2: begin
                out_byte_mid[1] = in;
            end
            B3: begin
                out_byte_mid[2] = in;
            end
            B4: begin
                out_byte_mid[3] = in;
            end
            B5: begin
                out_byte_mid[4] = in;
            end
            B6: begin
                out_byte_mid[5] = in;
            end
            B7: begin
                out_byte_mid[6] = in;
            end
            B8: begin
                out_byte_mid[7] = in;
            end
            B9: begin
                ;
            end
            STOP: begin
                ;
            end
            D0: begin
                ;
            end
            D1: begin
                ;
            end
             D2: begin
                ;
            end
            default: begin
                ;
            end
            
        endcase
    end
    assign done = (state == D0) ? 1 : 0;
    assign en = (state == B1)||(state == B2)||(state == B3)||(state == B4) ||(state == B5)||(state == B6)||(state == B7)||(state == B8)||(state == B9) ? 1: 0;

    assign out_byte = done ? out_byte_mid : 8'b0;

    // New: Add parity checking.
    parity inst_parity(
        .clk(clk),
        .reset(reset),
        .in(in&en),
        //.en(en),
        .odd(odd)
    );

endmodule

等待你的方案?

20200107更新,下面是群里的一位老哥的答案,十分感谢,还没来得及看,先放这里,以免忘记。

HDLBits 系列(39)求解带有奇校验的串口接收数据的简化电路设计_第3张图片

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); 

    reg odd;
    reg[4:0] state,nstate;
    parameter start=0,d0=1,d1=2,d2=3,d3=4,d4=5,d5=6,d6=7,d7=8,stop=9,done1=10,done2=11,w=13,p=12; 
    always@(*)
        begin
            case(state)
                start:begin if(in==0)nstate=d0;else nstate=start;end
                d0:begin nstate=d1;out_byte[0]=in;end
                d1:begin nstate=d2;out_byte[1]=in;end
                d2:begin nstate=d3;out_byte[2]=in;end
                d3:begin nstate=d4;out_byte[3]=in;end
                d4:begin nstate=d5;out_byte[4]=in;end
                d5:begin nstate=d6;out_byte[5]=in;end
                d6:begin nstate=d7;out_byte[6]=in;end
                d7:begin nstate=p;out_byte[7]=in;end
                p: begin nstate=stop; odd=^out_byte[7:0]^in; end
                stop: begin if(in==1) nstate=done1;else nstate=w; end
                done1:begin if(in==1) nstate=start;else nstate=d0; end
               w:begin if(in==1) nstate=start;else nstate=w; end
            endcase
        end
    
    always@(posedge clk)
        begin
        if(reset==1)
        state<=start;
        else
        state<=nstate;
        end
    assign done=(state==done1&&odd)?1:0;
endmodule

 

 

 

你可能感兴趣的:(#,HDLBits)