HDLBITS笔记35:独热编码状态机,ps/2数据包解析器,ps/2数据包和数据路径

目录

题目1:Fsm onehot(热编码的有限状态机)

 题目2:Fsm ps2(ps/2数据包解析器)

题目3:Fsm ps2data(ps/2数据包解析器和数据路径)


题目1:Fsm onehot(热编码的有限状态机)

给定以下状态机,具有 1 个输入和 2 个输出:

假设此状态机使用单热编码,其中状态[0]通过状态[9]分别对应于状态S0和S9。除非另有指定,否则输出为零。

实现状态机的状态转换逻辑输出逻辑部分(但不是状态触发器)。在状态[9:0]中,您将获得当前状态,并且必须产生next_state[9:0]和两个输出。通过检查假设一热编码来推导逻辑方程。(测试平台将使用非一个热输入进行测试,以确保您不会尝试执行更复杂的操作)。

模块声明

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);

提示:一热状态转换逻辑的逻辑方程可以通过查看状态转换图的边缘来推导。

根据状态流程图写出逻辑关系,输出也是一样的道理。

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);
  parameter s0 =4'd0,s1 = 4'd1,s2 = 4'd2,s3 = 4'd3,s4 = 4'd4,s5 = 4'd5,s6 = 4'd6,s7 = 4'd7,s8 = 4'd8,s9 = 4'd9;
    //状态逻辑
    assign next_state[s0] = !in &( state[s0] | state[s1] | state[s2] | state[s3] | state[s4] | state[7] | state[s8] | state[s9]);
    assign next_state[s1] = in &( state[s0] | state[s8] | state[s9]);
    assign next_state[s2] = in &( state[s1]);
    assign next_state[s3] = in & state[s2] ;
    assign next_state[s4] = in & state[s3] ;
    assign next_state[s5] = in & state[s4] ;
    assign next_state[s6] = in & state[s5] ;
    assign next_state[s7] = in & (state[s6] | state[7]);
    assign next_state[s8] = !in & state[s5] ;
    assign next_state[s9] = !in & state[s6] ;
    
    //输出逻辑
    assign out1 = state[8]|state[9];
    assign out2 = state[7]|state[9];
endmodule

仿真结果:

 题目2:Fsm ps2(ps/2数据包解析器)

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

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

FSM 应在成功接收到每条消息的第三个字节后立即在周期内发出信号。

一些时序图来解释所需的行为

在无差错条件下,每三个字节形成一条消息:

发生错误时,搜索字节 1:

请注意,这与 1xx 序列识别器不同。此处不允许使用重叠序列:

模块声明

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

代码编写如下:

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output done); //
    reg [1:0] state,next_state;
    parameter s0 = 2'd0,s1 = 2'd1,s2 = 2'd2,s3 = 2'd3;
    // State transition logic (combinational),组合逻辑
    always @(*)
        begin
            case(state)
                s0:begin;
                    if(!in[3])
                        next_state = s0;
                    else
                        next_state = s1;
                end
                s1: next_state = s2;
                s2: next_state = s3;
                s3:begin
                    if(!in[3])
                        next_state = s0;
                    else
                        next_state = s1;
                end
            endcase
        end

    // State flip-flops (sequential),时序逻辑
                always @(posedge clk)
                    begin
                        if(reset)
                            state <= s0;
                        else
                            state <= next_state;
                    end
 
    // Output logic,输出逻辑
                assign done = (state==s3);

endmodule

题目3:Fsm ps2data(ps/2数据包解析器和数据路径)

另请参见:PS/2 数据包解析器

现在,您已经有了一个状态机,它将识别 PS/2 字节流中的三字节消息,请添加一个数据路径,该数据路径还将在收到数据包时输出 24 位(3 字节)消息(out_bytes[23:16] 是第一个字节,out_bytes[15:8] 是第二个字节,依此类推)。

每当断言完成信号时,out_bytes都需要有效。您可以在其他时间输出任何内容(即,不要在乎)。

模块声明 

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

分析:观察所给的图例,当done=1,in位1时,输出24位才有效。当in为1,done为1,输出out——bytes才依次从高8位,中8位,低8位输出。当done为0时,不关心输出。

代码如下:

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output [23:0] out_bytes,
    output done); //
    reg [1:0] state,next_state;
    parameter [1:0] s0 = 2'd0,s1 = 2'd1,s2 = 2'd2 ,s3 = 2'd3;

    // FSM from fsm_ps2
    always @(*)
        begin
            case(state)
                s0:begin
                    if(!in[3])
                        next_state = s0;
                    else
                        next_state = s1;
                end
                s1:next_state = s2;
                s2:next_state = s3;
                s3:begin
                    if(!in[3])
                        next_state = s0;
                    else
                        next_state = s1;
                end
            endcase
        end
    // New: Datapath to store incoming bytes.
                always @(posedge clk)
                    begin
                        if(reset)
                            state <= s0;
                        else
                            state <= next_state ;
                    end
                always @(posedge clk)
                    begin
                        if(next_state == s1) begin
                            out_bytes[23:16] <= in;
                        end
                        else if(next_state == s2)
                                begin
                                    out_bytes[15:8] <= in;
                                end
                        else if(next_state == s3)
                                begin
                                    out_bytes[7:0] <= in;
                                end
                            else begin
                                out_bytes <= 24'b0;
                            end
                     end
    assign done = (state == s3);

endmodule

仿真结果如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值