Fsm ps2_HDLbits

1、PS/2鼠标协议发送三字节长的消息。然而,在一个连续的字节流中,消息的开始和结束位置并不明显。唯一的指示是,每个三字节消息的第一个字节的bit[3]=1(但其他两个字节的bit[3]可能是1或0,具体取决于数据)。

我们需要一个有限状态机,当给定一个输入字节流时,它将搜索消息边界。我们将使用的算法是丢弃字节,直到我们看到bit[3]=1的字节。然后我们假设这是一条消息的字节1,并在所有3个字节都被接收(完成)后发出消息接收信号。

FSM应在成功接收到每条消息的第三个字节后立即发送信号完成循环。

状态图一开始想了好一会儿,这里是将byte1作为常态,直到in[3]=1时才跳到次态。而将三个状态变换之后到done,此时如果in[3]=0,则回到byte1,如果in[3]=1,则直接跳到byte2,因为byte3结束若in[3]=1则会直接到下个三字节,是连续的,如果跳到byte1会有一个间隔。

状态图正确太重要了!

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output done); //
    parameter byte1=0,byte2=1,byte3=2,done0=3;
    reg [1:0] state,next_state;
    // State transition logic (combinational)
    always @(*)
        begin
            case(state)
                byte1: next_state<=(in[3])?byte2:byte1;
                byte2: next_state<=byte3;
                byte3: next_state<=done0;
                done0: next_state<=(in[3])?byte2:byte1; 
                //出现一个done就输出一个done的高电平,这里一开始我把done设置成常态,in[3]=1时才变化,这样会导致输出不匹配。
            endcase
        end
    // State flip-flops (sequential)
    always @(posedge clk)
        begin
            if(reset) state<=0;
            else state<=next_state;
        end
    // Output logic
    assign done = (state==done0)? 1:0;

endmodule

2、现在有了一个状态机,它可以识别PS/2字节流中的三字节消息,添加一个数据路径,每当接收到数据包时,它也会输出24位(3字节)消息(out_bytes[23:16]是第一个字节,out_bytes[15:8]是第二个字节等)。

无论何时断言done信号,out_字节都必须有效。您可以在其他时间输出任何内容(即不关心)。

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output [23:0] out_bytes,
    output done); //
    parameter byte1=0,byte2=1,byte3=2,done0=3;
    reg [1:0] state,next_state;

    always @(*) //组合逻辑
        begin
            case(state)
                byte1: next_state<=(in[3])?byte2:byte1;
                byte2: next_state<=byte3;
                byte3: next_state<=done0;
                done0: next_state<=(in[3])?byte2:byte1; 
            endcase
        end
   
    always @(posedge clk)
        begin
            if(reset) state<=0;
            else state<=next_state;
            //唯一不同于上一题的部分:
            //易错:只有当in[3]=1时才读入in的值,如果没有这个判断,在任意时刻in都会载入out_bytes[23:16]中。
            //同时,done状态时也需要考虑下一状态的变化时out_bytes[23:16]的输出。
            //三字节的首位输出很重要
            case(state)
                byte1:out_bytes[23:16] <=(in[3])?in:0;
                byte2:out_bytes[15:8] <=in;
                byte3:out_bytes[7:0] <=in;
                done0:out_bytes[23:16] <=(in[3])?in:0;
                
            endcase  
        end
 
    assign done = (state==done0)? 1:0;

endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值