hdlbits.01xz.net /Circuits/Sequential Logic/Finite State Machines/Serial receiver and datapath

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

    // Use FSM from Fsm_serial

    // New: Datapath to latch input bits.
    

    parameter IDLE =     13'b0000000000001;
    parameter START =     13'b0000000000010;
    parameter B0 =         13'b0000000000100;
    parameter B1 =         13'b0000000001000;
    parameter B2 =         13'b0000000010000;
    parameter B3 =         13'b0000000100000;
    parameter B4 =         13'b0000001000000;
    parameter B5 =         13'b0000010000000;
    parameter B6 =         13'b0000100000000;
    parameter B7 =         13'b0001000000000;
    parameter STOP =     13'b0010000000000;
    parameter END =     13'b0100000000000;
    parameter ERROR =   13'b1000000000000;
    
    reg [12:0] state, next;
    
    //ff
    always @(posedge clk) begin
        if(reset)
            state = START;
        else
            state = next;
    end
    
    // trans
    always @(*) begin
        next = START;
        case(state)
            START:begin
                if(in == 0)
                    next = B7;
                else
                    next = START;
            end
            B7:begin
                next = B6;
            end
            B6:begin
                next = B5;
            end
            B5:begin
                next = B4;
            end
            B4:begin
                next = B3;
            end
            B3:begin
                next = B2;
            end
            B2:begin
                next = B1;
            end
            B1:begin
                next = B0;
            end
            B0:begin
                next = STOP;
            end
            STOP:begin
                if(in == 1)
                    next = END;
                else
                    next = ERROR;
            end
            ERROR:
                if(in == 1)
                    next = START;
                else
                    next = ERROR;
            END:
                if(in == 0)
                    next = B7;
                else
                    next = START;
            default:begin
                next = START;
            end
        endcase
    end
    
    //out
    assign done = (state == END)? 1: 0;
    always @(negedge clk) begin
        case (state) 
            B7:
                out_byte[7] = in;
            B6:
                out_byte[6] = in;
            B5:
                out_byte[5] = in;
            B4:
                out_byte[4] = in;
            B3:
                out_byte[3] = in;
            B2:
                out_byte[2] = in;
            B1:
                out_byte[1] = in;
            B0:
                out_byte[0] = in;
            default:
                out_byte = out_byte;
        endcase
    end

endmodule

题目故意在clk下降沿放了一次in的改变, 我是下降沿锁存, 所以错了

改成上升沿

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

    // Use FSM from Fsm_serial

    // New: Datapath to latch input bits.
    

    parameter IDLE =     13'b0000000000001;
    parameter START =     13'b0000000000010;
    parameter B0 =         13'b0000000000100;
    parameter B1 =         13'b0000000001000;
    parameter B2 =         13'b0000000010000;
    parameter B3 =         13'b0000000100000;
    parameter B4 =         13'b0000001000000;
    parameter B5 =         13'b0000010000000;
    parameter B6 =         13'b0000100000000;
    parameter B7 =         13'b0001000000000;
    parameter STOP =     13'b0010000000000;
    parameter END =     13'b0100000000000;
    parameter ERROR =   13'b1000000000000;
    
    reg [12:0] state, next;
    
    //ff
    always @(posedge clk) begin
        if(reset)
            state = START;
        else
            state = next;
    end
    
    // trans
    always @(*) begin
        next = START;
        case(state)
            START:begin
                if(in == 0)
                    next = B7;
                else
                    next = START;
            end
            B7:begin
                next = B6;
            end
            B6:begin
                next = B5;
            end
            B5:begin
                next = B4;
            end
            B4:begin
                next = B3;
            end
            B3:begin
                next = B2;
            end
            B2:begin
                next = B1;
            end
            B1:begin
                next = B0;
            end
            B0:begin
                next = STOP;
            end
            STOP:begin
                if(in == 1)
                    next = END;
                else
                    next = ERROR;
            end
            ERROR:
                if(in == 1)
                    next = START;
                else
                    next = ERROR;
            END:
                if(in == 0)
                    next = B7;
                else
                    next = START;
            default:begin
                next = START;
            end
        endcase
    end
    
    //out
    assign done = (state == END)? 1'b1: 1'b0;
    always @(posedge clk) begin
        case (state) 
            START:
                out_byte = 8'b0;
            B7:
                out_byte[7] = in;
            B6:
                out_byte[6] = in;
            B5:
                out_byte[5] = in;
            B4:
                out_byte[4] = in;
            B3:
                out_byte[3] = in;
            B2:
                out_byte[2] = in;
            B1:
                out_byte[1] = in;
            B0:
                out_byte[0] = in;
            default:
                out_byte = out_byte;
        endcase
    end

endmodule

修改位顺序, 验证OK了, 但是感觉很奇怪

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

    // Use FSM from Fsm_serial

    // New: Datapath to latch input bits.
    

    parameter IDLE =     13'b0000000000001;
    parameter START =     13'b0000000000010;
    parameter B0 =         13'b0000000000100;
    parameter B1 =         13'b0000000001000;
    parameter B2 =         13'b0000000010000;
    parameter B3 =         13'b0000000100000;
    parameter B4 =         13'b0000001000000;
    parameter B5 =         13'b0000010000000;
    parameter B6 =         13'b0000100000000;
    parameter B7 =         13'b0001000000000;
    parameter STOP =     13'b0010000000000;
    parameter END =     13'b0100000000000;
    parameter ERROR =   13'b1000000000000;
    
    reg [12:0] state, next;
    
    //ff
    always @(posedge clk) begin
        if(reset)
            state = START;
        else
            state = next;
    end
    
    // trans
    always @(*) begin
        next = START;
        case(state)
            START:begin
                if(in == 0)
                    next = B0;
                else
                    next = START;
            end
            B0:begin
                next = B1;
            end
            B1:begin
                next = B2;
            end
            B2:begin
                next = B3;
            end
            B3:begin
                next = B4;
            end
            B4:begin
                next = B5;
            end
            B5:begin
                next = B6;
            end
            B6:begin
                next = B7;
            end
            B7:begin
                next = STOP;
            end
            STOP:begin
                if(in == 1)
                    next = END;
                else
                    next = ERROR;
            end
            ERROR:
                if(in == 1)
                    next = START;
                else
                    next = ERROR;
            END:
                if(in == 0)
                    next = B0;
                else
                    next = START;
            default:begin
                next = START;
            end
        endcase
    end
    
    //out
    assign done = (state == END)? 1'b1: 1'b0;
    always @(posedge clk) begin
        case (state) 
            START:
                out_byte = 8'b0;
            B7:
                out_byte[7] = in;
            B6:
                out_byte[6] = in;
            B5:
                out_byte[5] = in;
            B4:
                out_byte[4] = in;
            B3:
                out_byte[3] = in;
            B2:
                out_byte[2] = in;
            B1:
                out_byte[1] = in;
            B0:
                out_byte[0] = in;
            default:
                out_byte = out_byte;
        endcase
    end

endmodule

更新:对bit计数减少状态

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

    // Use FSM from Fsm_serial

    // New: Datapath to latch input bits.

    parameter START =     5'b00001;
    parameter RECV =    5'b00010;
    parameter STOP =     5'b00100;
    parameter END =     5'b01000;
    parameter ERROR =   5'b10000;
    
    reg [4:0] state, next;
    
    //ff
    always @(posedge clk) begin
        if(reset)
            state = START;
        else
            state = next;
    end
    
    integer cnt;
    
    // trans
    always @(*) begin
        next = START;
        case(state)
            START:begin
                if(in == 0)
                    next = RECV;
                else
                    next = START;
            end
            RECV: begin
                if(cnt == 7)
                    next = STOP;
                else
                    next = RECV;
            end
            STOP:begin
                if(in == 1)
                    next = END;
                else
                    next = ERROR;
            end
            ERROR:
                if(in == 1)
                    next = START;
                else
                    next = ERROR;
            END:
                if(in == 0)
                    next = RECV;
                else
                    next = START;
            default:begin
                next = START;
            end
        endcase
    end
    
    always @(posedge clk) begin
        if(reset)
            cnt = 0;
        else begin
            if((state == START) || (state == END))
                cnt = 0;
            else 
                cnt = cnt+1;
        end
    end
    
    //out
    assign done = (state == END)? 1'b1: 1'b0;
    always @(posedge clk) begin
        case (state) 
            START:
                out_byte = 8'b0;
            RECV:
                case(cnt)
                    0:
                        out_byte[0]=in;
                    1:
                        out_byte[1]=in;
                    2:
                        out_byte[2]=in;
                    3:
                        out_byte[3]=in;
                    4:
                        out_byte[4]=in;
                    5:
                        out_byte[5]=in;
                    6:
                        out_byte[6]=in;
                    7:
                        out_byte[7]=in;
                endcase
            default:
                out_byte = out_byte;
        endcase
    end

endmodule

验证成功,但是有个warrning

修改:完美了

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

    // Use FSM from Fsm_serial

    // New: Datapath to latch input bits.

    parameter START =     5'b00001;
    parameter RECV =    5'b00010;
    parameter STOP =     5'b00100;
    parameter END =     5'b01000;
    parameter ERROR =   5'b10000;
    
    reg [4:0] state, next;
    
    //ff
    always @(posedge clk) begin
        if(reset)
            state = START;
        else
            state = next;
    end
    
    integer cnt;
    
    // trans
    always @(*) begin
        next = START;
        case(state)
            START:begin
                if(in == 0)
                    next = RECV;
                else
                    next = START;
            end
            RECV: begin
                if(cnt == 7)
                    next = STOP;
                else
                    next = RECV;
            end
            STOP:begin
                if(in == 1)
                    next = END;
                else
                    next = ERROR;
            end
            ERROR:
                if(in == 1)
                    next = START;
                else
                    next = ERROR;
            END:
                if(in == 0)
                    next = RECV;
                else
                    next = START;
            default:begin
                next = START;
            end
        endcase
    end
    
    always @(posedge clk) begin
        if(reset)
            cnt = 0;
        else begin
            if((state == START) || (state == END))
                cnt = 0;
            else 
                cnt = cnt+1;
        end
    end
    
    //out
    assign done = (state == END)? 1'b1: 1'b0;
    always @(posedge clk) begin
        case (state) 
            START:
                out_byte = 8'b0;
            RECV:
                out_byte[cnt] = in;
            default:
                out_byte = out_byte;
        endcase
    end

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值