HDLBits(3)--FSM ps2 & ps2data

FSM ps2

题目:The PS/2 mouse protocol sends messages that are three bytes long. However, within a continuous byte stream, it’s not obvious where messages start and end. The only indication is that the first byte of each three byte message always has bit[3]=1 (but bit[3] of the other two bytes may be 1 or 0 depending on data).

We want a finite state machine that will search for message boundaries when given an input byte stream. The algorithm we’ll use is to discard bytes until we see one with bit[3]=1. We then assume that this is byte 1 of a message, and signal the receipt of a message once all 3 bytes have been received (done).

The FSM should signal done in the cycle immediately after the third byte of each message was successfully received.

在这里插入图片描述
分析:

  1. 下图状态转移图钟的BYTE1,BYTE2,BYTE3和上图波形图中的不对应,上图收到起始符时已经是BYTE1,我的状态转移图在收到起始符后才变为BYTE1;
  2. 在BYTE3之后需要进行判断,如果是in[3]==1开始进行技术,在IDLE,BYTE1,BYTE2三个阶段则会收到全部的三个数据,BYTE3状态下收到的其实是下一数据的判断位,因此需要直接进行判断,如果此时in[3]==1,则直接进入下一个数据的接受周期;在这里插入图片描述
module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output done); //
    
    parameter IDLE=2'b00;
    parameter BYTE1=2'b01;
    parameter BYTE2=2'b10;
    parameter BYTE3=2'b11;
    
    reg [1:0] state, next_state;
    
    //状态寄存器 state flip-flops (sequential)
    always @(posedge clk) begin 
        if (reset) state<=IDLE;
        else state<=next_state;
    end
    
    //状态转移逻辑
    always @(*) begin
        case(state)
            IDLE: begin
                if (in[3]==1'b1) next_state=BYTE1;
                else next_state=IDLE;
            end
            BYTE1: begin
                next_state=BYTE2;
            end
            BYTE2: begin
                next_state=BYTE3;
            end
            BYTE3: begin
                next_state=(in[3]==1'b1)?BYTE1:IDLE;
            end
        endcase
    end
    
    //输出逻辑 output
    always @(*) begin
        if (reset) done<=1'b0;
        else if (state == BYTE3) done<=1'b1;
        else done<=1'b0;
    end

endmodule

FSM ps2data

题目:Now that you have a state machine that will identify three-byte messages in a PS/2 byte stream, add a datapath that will also output the 24-bit (3 byte) message whenever a packet is received (out_bytes[23:16] is the first byte, out_bytes[15:8] is the second byte, etc.).

out_bytes needs to be valid whenever the done signal is asserted. You may output anything at other times (i.e., don’t-care).
在这里插入图片描述
分析:
在这里插入图片描述
和上题一样的状态机设置时,BYTE3进行done信号和out_bytes数据的输出,此时依然有可能正在接收着作为下一个周期的第一位数据,在这种情况下是没有IDLE状态来接收第一个数据的,而是直接进入BYTE1。因此,需要一个flip-flop暂存BYTE3时的数据,如果之后紧接着一个数据周期的话,则将这个寄存器中的数据存入原本的out_temp[23:16]
在这里插入图片描述
可以看出,如果前后两个数据没有相连,是可以存在IDLE状态的,此时则可以正常接收第一个数据,也就是out_temp[23:16]。具体的代码逻辑如下图所示:
在这里插入图片描述

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

    // FSM from fsm_ps2
    // definition for states
    parameter IDLE=2'b00;
    parameter BYTE1=2'b01;
    parameter BYTE2=2'b10;
    parameter BYTE3=2'b11;
    reg [1:0] state, next_state;
    reg [23:0] out_temp;
    
    // flip-flops (synchronous reset)
    always@(posedge clk) begin
        if (reset) state<=IDLE;
        else state<=next_state;
    end
    
    // state transition
    always@(*) begin
        case (state)
            IDLE: begin
                if (in[3]==1'b1) next_state=BYTE1;
                else next_state=IDLE;
            end
            BYTE1:begin
                next_state=BYTE2;
                //out_temp[23:16]=in[7:0];
            end
            BYTE2:begin
                next_state=BYTE3;
                //out_temp[15:8]=in[7:0];
            end
            BYTE3: begin
                //out_temp[7:0]=in[7:0];
                if(in[3]==1'b1) next_state=BYTE1;
                else next_state=IDLE;
            end
        endcase
    end
    
    
    //output logic
    always@(*) begin
        if (reset) begin
            done=1'b0;
            out_bytes=24'bx;
        end
        else if (state==BYTE3) begin
            done=1'b1;
            out_bytes=out_temp;
        end
        else done=1'b0;
    end

    // New: Datapath to store incoming bytes.
    reg [7:0] in_r;
    reg [1:0] state_r;
    
    always@(posedge clk) begin
        if (reset) begin
            in_r<=8'b0;
            state_r<=IDLE;
        end
        else begin
            state_r<=state;
            in_r<=in;
        end
    end
    
    always@(*) begin
        case (state)
            IDLE: begin
                if (in[3]==1'b1) out_temp[23:16]=in;
            end
            BYTE1: begin
                if (state_r==BYTE3 && in_r[3]==1'b1) begin
                    out_temp[15:8]=in;
                    out_temp[23:16]=in_r;
                end
                else out_temp[15:8]=in;
            end
            BYTE2: begin
                out_temp[7:0]=in;
            end
            BYTE3: begin
                ;
            end
            default: begin
                ;
            end
        endcase
    end
                    

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值