HDLbits中PS/2 packet parser的解法思考

一、题目

这一篇的题目中要求我们做一个类似不重叠的1xx序列检测器。

二、我的解法(2个状态)

我还是一贯的跟随前一题Lemmings 4的思路,其中加入参数进行计数器的效果。而这题与之类似,分为两个状态:发送和不发送,通过计数器的值来使每次发送的状态持续3个时钟周期,且在第三个时钟周期时对in[3]进行判断,来决定进入下一个发送状态还是进入不发送状态。这题比较简单,只是我的思路与作者给的提示思路不同,所以记录一下。下面是我的完整代码。

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

    reg [0:0] state, next_state ;
    parameter not_send=0, send=1 ;
    reg [1:0] cnt ;
    // State transition logic (combinational)
    always@(*)begin
        case(state)
            not_send : next_state = in[3] ? send : not_send ;
            send : next_state = ((cnt==3)&~in[3]) ? not_send : send ;
        endcase
    end

    // State flip-flops (sequential)
    always@(posedge clk)begin
        if(reset)begin
            state <= not_send ;
            cnt <= 1 ;
        end
        else begin
            state <= next_state ;
            if(cnt == 3)
                cnt <= 1 ;
            else if(state)
                cnt++ ;
        end
    end
                
    // Output logic
    assign done = (cnt == 3) & state ;

endmodule

三、作者思路

3.1 4个状态

作者提供的hint还是从每一个字节发送单独考虑的角度出发,将发送每一个字节的状态单独分开,同时加入一个状态用以判断done。hint及代码如下。

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

    reg [1:0] state, next_state ;
    parameter byte1=0, byte2=1, byte3=2, bdone=3 ;

    // State transition logic (combinational)
    always@(*)begin
        case(state)
            byte1 : next_state = in[3] ? byte2 : byte1 ;
            byte2 : next_state = byte3 ;
            byte3 : next_state = bdone ;
            bdone : next_state = in[3] ? byte2 : byte1 ;
        endcase
    end

    // State flip-flops (sequential)
    always@(posedge clk)begin
        if(reset)
            state <= byte1 ;
        else 
            state <= next_state ;
    end
                
    // Output logic
    assign done =  (state == bdone) ;

endmodule

3.2 3个状态

上述思路中,作者给的hint中说三个状态的话可能无法将done置1,所以添加了一个状态来给done置1。但是从我自己的解法出发,可以通过计数器的值对done是否置1进行判断,那么我认为在将发送每一个比特的状态拆分开的思路中,同样可以添加这样的一个参数来进行判断。

从原理出发,只要从byte1开始的三个时钟周期完整发送后,done便置1。那么,即在状态为byte3的下一周期将done置1即可。但这时我们只有三个状态,就无法直接通过现有状态判断,所以我加入last_state参数,在reset不置1时,记录当前周期的状态以便于下一个周期进行判断。代码如下。

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

    reg [1:0] state, next_state, last_state ;
    parameter byte1=0, byte2=1, byte3=2, bdone=3 ;

    // State transition logic (combinational)
    always@(*)begin
        case(state)
            byte1 : next_state = in[3] ? byte2 : byte1 ;
            byte2 : next_state = byte3 ;
            byte3 : next_state = byte1 ;
            //bdone : next_state = in[3] ? byte2 : byte1 ;
        endcase
    end

    // State flip-flops (sequential)
    always@(posedge clk)begin
        if(reset)
            state <= byte1 ;
        else begin
            state <= next_state ;
        	last_state <= state ;
        end
    end
                
    // Output logic
    assign done =  (last_state == byte3) ;

endmodule

四、总结反思

我在第一遍思考时,觉得自己的思路减少了状态,比作者的思路更巧妙一些。但是在做完回过头来看时,还是觉得分成四个状态更直接,更符合有限状态机的思路。不同于我两次添加标志位来对done是否置1进行判断,作者的思路直接给出一个状态来对done进行置1操作,思路更清晰,也更便于修改。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值