HDLBits刷题合集—17 Finite State Machines-3

HDLBits刷题合集—17 Finite State Machines-3

HDLBits-133 Fsm onehot

Problem Statement
给定以下具有1个输入和2个输出的状态机:
假设此状态机使用独热编码,其中state[0]至state[9]分别对应于状态S0至S9。 除非另有说明,否则输出为零。

实现状态机的状态转换逻辑和输出逻辑部分(但不实现状态触发器)。 你将给定state[9:0]中的当前状态,并且必须产生next_state [9:0]和两个输出。通过假设独热编码,通过检验推导出逻辑方程 。(测试台将使用非独热码输入进行测试,以确保你没有尝试做更复杂的事情)。

在这里插入图片描述

Hint:可以通过查看状态转换图的in部分,来推导出独热状态转换逻辑的逻辑方程式。

代码如下:

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);
    
    assign next_state[0] = ~in & (state[0]|state[1]|state[2]|state[3]|state[4]|state[7]|state[8]|state[9]);
    assign next_state[1] = in & (state[0] | state[8] | state[9]);
    assign next_state[2] = in & state[1];
    assign next_state[3] = in & state[2];
    assign next_state[4] = in & state[3];
    assign next_state[5] = in & state[4];
    assign next_state[6] = in & state[5];
    assign next_state[7] = in & (state[6] | state[7]);
    assign next_state[8] = ~in & state[5];
    assign next_state[9] = ~in & state[6];
    
    assign out1 = state[8] | state[9];
    assign out2 = state[7] | state[9];

endmodule

HDLBits-134 Fsm ps2

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

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

在成功接收到每个消息的第三个字节之后,FSM应该立即在周期中发出完成信号。

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

在这里插入图片描述
出现错误时,搜索字节1:

在这里插入图片描述

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

在这里插入图片描述
Hint:尽管in[7:0]是一个字节,但是FSM只有一个输入:in[3]。你需要大约4个状态。 三种状态可能不起作用,因为其中一种状态需要断言完成,并且对于每个收到的消息,仅在一个周期内断言完成状态。

代码如下:

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output done); //
    reg [1:0] state,state_next;
	parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3;
	
    // State transition logic (combinational)
    always @(*) begin
        case (state)
            S0 : begin
                if (in[3]==1) state_next <= S1;
                else state_next <= S0;
            end
            S1 : begin
                state_next <= S2;
            end
            S2 : begin
                state_next <= S3;
            end
            S3 : begin
                if (in[3]==1) state_next <= S1;
                else state_next <= S0;
            end
        endcase
    end
    // State flip-flops (sequential)
    always @(posedge clk) begin
        if (reset)
            state <= S0;
        else
            state <= state_next;
    end
    // Output logic
    assign done = (state == S3);
endmodule

HDLBits-135 Fsm ps2data

Problem Statement
另请参阅:上一题Fsm ps2。

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

断言完成信号时,out_bytes必须有效。 你可能会在其他时间输出任何内容(即,don’t-care)。

例如:

在这里插入图片描述
代码如下:

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

    // FSM from fsm_ps2
	reg [1:0] state,state_next;
    reg [23:0] data;
	parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3;
	
    // State transition logic (combinational)
    always @(*) begin
        case (state)
            S0 : begin
                if (in[3]==1) state_next <= S1;
                else state_next <= S0;
            end
            S1 : begin
                state_next <= S2;
            end
            S2 : begin
                state_next <= S3;
            end
            S3 : begin
                if (in[3]==1) state_next <= S1;
                else state_next <= S0;
            end
        endcase
    end
    // State flip-flops (sequential)
    always @(posedge clk) begin
        if (reset)
            state <= S0;
        else
            state <= state_next;
    end
    // Output logic
    assign done = (state == S3);
    
    // New: Datapath to store incoming bytes.
	always @(posedge clk) begin
        if (reset) begin
            data <= 24'd0;
        end
        else begin
            data[23:16] <= data[15:8];
            data[15:8] <= data[7:0];
            data[7:0]  <= in;
        end
    end
    assign out_bytes = (done) ? data : 24'd0;
endmodule

HDLBits-136 Fsm serial

Problem Statement
在许多(较旧的)串行通信协议中,每个数据字节都与起始位和停止位一起发送,以帮助接收器从比特流中分隔字节。 一种常见的方案是使用一个起始位(0),8个数据位和1个停止位(1)。 当没有任何传输(空闲)时,线路也处于逻辑1。

设计一个有限状态机,当给定比特流时,它将识别何时正确接收了字节。 它需要标识开始位,等待所有8个数据位,然后验证停止位是否正确。 如果在预期的情况下没有出现停止位,则FSM必须等待直到找到停止位,然后再尝试接收下一个字节。

无错误的情况:

在这里插入图片描述

未找到停止位。第一个字节被丢弃:

在这里插入图片描述
代码如下:

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    reg [3:0] state, state_next;
    parameter START=0, S0=1, S1=2, S2=3, S3=4, S4=5, S5=6, S6=7, S7=8, S8=9, DONE0=10, DONE1=11;
    
    always @(*) begin
        case (state)
            START : begin
                if (in == 0) state_next <= S0;
                else state_next <= START;
            end
            S0    : begin
                state_next <= S1;
            end
            S1    : begin
                state_next <= S2;
            end
            S2    : begin
                state_next <= S3;
            end
            S3    : begin
                state_next <= S4;
            end
            S4    : begin
                state_next <= S5;
            end
            S5    : begin
                state_next <= S6;
            end
            S6    : begin
                state_next <= S7;
            end
            S7    : begin
                state_next <= S8;
            end
            S8    : begin
                if (in == 1) state_next <= DONE1;
                else  state_next <= DONE0;
            end 
            DONE0  : begin
                if (in == 1) state_next <= START;
                else  state_next <= DONE0;
            end
             DONE1 : begin
                 if (in == 1) state_next <= START;
                else  state_next <= S0;
             end
            default: begin
               state_next <= START;
            end
        endcase
    end
    
    always @(posedge clk) begin
            if(reset) 
                state <= START;
            else 
                state <= state_next;
    end
    		
    assign done = (state == DONE1);
    
endmodule

HDLBits-137 Fsm serialdata

Problem Statement
另请参阅:上一题Fsm serial。

现在已经有了一个有限状态机,可以确定何时在串行位流中正确接收了字节,添加一个数据路径,它将输出正确接收的数据字节。 当完成为1时,out_byte需要有效,否则don’t-care。

请注意,串行协议首先发送最低有效位。

在这里插入图片描述
代码如下:

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
	reg [3:0] state, state_next;
    parameter START=0, S0=1, S1=2, S2=3, S3=4, S4=5, S5=6, S6=7, S7=8, S8=9, DONE0=10, DONE1=11;
    
    always @(*) begin
        case (state)
            START : begin
                if (in == 0) state_next <= S0;
                else state_next <= START;
            end
            S0    : begin
                state_next <= S1;
            end
            S1    : begin
                state_next <= S2;
            end
            S2    : begin
                state_next <= S3;
            end
            S3    : begin
                state_next <= S4;
            end
            S4    : begin
                state_next <= S5;
            end
            S5    : begin
                state_next <= S6;
            end
            S6    : begin
                state_next <= S7;
            end
            S7    : begin
                state_next <= S8;
            end
            S8    : begin
                if (in == 1) state_next <= DONE1;
                else  state_next <= DONE0;
            end 
            DONE0  : begin
                if (in == 1) state_next <= START;
                else  state_next <= DONE0;
            end
             DONE1 : begin
                 if (in == 1) state_next <= START;
                else  state_next <= S0;
             end
            default: begin
               state_next <= START;
            end
        endcase
    end
    
    reg [7:0] out_byte_mid;
    
    always @(posedge clk) begin
            if(reset) 
                state <= START;
            else 
                state <= state_next;
    		end
     assign done = (state == DONE1);
     
	 always@(*) begin
        case(state)
            START: begin
                ;
            end
            S0: begin
                out_byte_mid[0] <= in;
            end
            S1: begin
                out_byte_mid[1] <= in;
            end
            S2: begin
                out_byte_mid[2] <= in;
            end
            S3: begin
                out_byte_mid[3] <= in;
            end
            S4: begin
                out_byte_mid[4] <= in;
            end
            S5: begin
                out_byte_mid[5] <= in;
            end
            S6: begin
                out_byte_mid[6] <= in;
            end
            S7: begin
                out_byte_mid[7] <= in;
            end
            S8: begin
                ;
            end
            DONE0: begin
                ;
            end
            DONE1: begin
                ;
            end
            default: begin
                ;
            end
            
        endcase
    end
    
    assign out_byte = (done == 1) ? out_byte_mid : 'bz;
    
endmodule

HDLBits-138 Fsm serialdp

Problem Statement
另请参阅:上一题Fsm serialdata。

我们要向串行接收器添加奇偶校验。奇偶校验在每个数据字节后增加一个额外的位。我们将使用奇数奇偶校验,其中接收到的9位中1的数量必须为奇数。例如,101001011满足奇偶校验(有5个1),而001001011不满足。

更改上面的FSM和数据路径以执行奇偶校验。仅当正确接收到一个字节并且其奇偶校验通过时,才声明完成信号。与串行接收器FSM一样,该FSM需要标识起始位,等待所有9位(数据和奇偶校验),然后验证停止位是否正确。如果在预期的情况下没有出现停止位,则FSM必须等待直到找到停止位,然后再尝试接收下一个字节。

提供了以下模块,该模块可用于计算输入流的奇偶校验(这是带复位的TFF)。预期的用途是应为它提供输入位流,并在适当的时间进行重置,以便它计算每个字节中1位的数目。

module parity (
    input clk,
    input reset,
    input in,
    output reg odd);

    always @(posedge clk) 
        if (reset) odd <= 0;
        else if (in) odd <= ~odd;

endmodule

注意,串行协议先发送最低有效位,然后发送奇偶校验位。

没有成帧错误。 奇偶校验通过第一个字节,失败通过第二个字节。

在这里插入图片描述

代码如下:

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

    // Modify FSM and datapath from Fsm_serialdata
    parameter idle = 4'd0, start = 4'd1, trans0 = 4'd2,trans1 = 4'd3, trans2 = 4'd4, trans3 = 4'd5;
    parameter trans4 = 4'd6, trans5 = 4'd7, trans6 = 4'd8, trans7 = 4'd9, stop = 4'd10, err = 4'd11, pari = 4'd12;
    reg [3:0] state, next_state;
    reg [7:0] data;
    wire odd, reset_p;
    reg done_reg;

    always @(*) begin
        case (state)
            idle:   next_state <= in ? idle : start;
            start:  next_state <= trans0;
            trans0: next_state <= trans1;
            trans1: next_state <= trans2;
            trans2: next_state <= trans3;
            trans3: next_state <= trans4;
            trans4: next_state <= trans5;
            trans5: next_state <= trans6;
            trans6: next_state <= trans7;
            trans7: next_state <= pari;
            pari:   next_state <= in ? idle : err;
            err:    next_state <= in ? idle : err;
        endcase
    end

    always @(posedge clk) begin
        if (reset) begin
            state <= idle;
        end
        else begin
            state <= next_state;
        end
    end

    // New: Add parity checking.
    always @(posedge clk) begin
        if (reset) begin
            data <= 8'd0;
            reset_p <= 1'b1;
            done_reg <= 1'b0;
        end
        else begin
            if (next_state == trans0 || next_state == trans1 || next_state == trans2 || next_state == trans3 || next_state == trans4 || next_state == trans5 || next_state == trans6 || next_state == trans7) begin
                data <= {in, data[7:1]};
            end
            else if (next_state == start) begin
                data <= 8'd0;
                reset_p <= 1'b0;
                done_reg <= 1'b0;
            end
            else if (next_state == idle) begin
                done_reg <= odd;
            end
            else if (next_state == pari) begin
                reset_p <= 1'b1;
            end
        end
    end

    assign done = done_reg;
    assign out_byte = done ? data : 8'd0;
    parity par_mod(clk, reset | reset_p, in, odd);

endmodule

HDLBits-139 Fsm hdlc

Problem Statement
Synchronous HDLC framing涉及对数据的连续位流进行解码,以寻找指示帧(数据包)开始和结束的位模式。 恰好看到6个连续的1(即01111110)是表示帧边界的“flag”。 为了避免数据流意外包含“flag”,发送方必须在每5个连续的1秒后插入一个零,接收方必须检测并丢弃。 如果连续7个或更多1,我们还需要发出错误信号。

创建一个有限状态机来识别这三个序列:

0111110:信号位需要丢弃(disc)。
01111110:标记帧的开始/结束(flag)。
01111111 …:错误(7或更多1s)(err)。
重置FSM时,其状态应类似于先前的输入为0。

以下是一些示例序列,它们说明了所期望的操作。

Discard 0111110:
在这里插入图片描述
Flag 01111110:
在这里插入图片描述

Reset behaviour and error 01111111…:
在这里插入图片描述
Hint:
使用一个大约有10个状态的莫尔型状态机。

在这里插入图片描述
代码如下:

module top_module(
    input clk,
    input reset,    // Synchronous reset
    input in,
    output disc,
    output flag,
    output err);
    
	parameter S0=0, S1=1, S2=2, S3=3, S4=4, S5=5, S6=6, DISC=7, FLAG=8, ERR=9;
    reg [3:0] state, state_next;
    
    always @(*) begin
        case (state)
            S0 : begin
                if (in)  state_next <= S1;
                else 	 state_next <= S0;
            end
            S1 : begin
                if (in)  state_next <= S2;
                else 	 state_next <= S0;
            end
            S2 : begin
                if (in)  state_next <= S3;
                else 	 state_next <= S0;
            end
            S3 : begin
                if (in)  state_next <= S4;
                else 	 state_next <= S0;
            end
            S4 : begin
                if (in)  state_next <= S5;
                else 	 state_next <= S0;
            end
            S5 : begin
                if (in)  state_next <= S6;
                else 	 state_next <= DISC;
            end
            S6 : begin
                if (in)  state_next <= ERR;
                else 	 state_next <= FLAG;
            end
            DISC : begin
                if (in)  state_next <= S1;
                else 	 state_next <= S0;
            end
            FLAG : begin
                if (in)  state_next <= S1;
                else 	 state_next <= S0;
            end
            ERR : begin
                if (in)  state_next <= ERR;
                else 	 state_next <= S0;
            end
        endcase
    end
    
    always @(posedge clk)
        begin
            if (reset) state <= S0;
            else state <= state_next;
        end
    
    assign disc = (state == DISC);
    assign flag = (state == FLAG);
    assign err  = (state == ERR);    
endmodule

Note
新手一枚,主要分享博客,记录学习过程,后期参考大佬代码或思想会一一列出。欢迎大家批评指正!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
有限创新速率(finite-rate-of-innovation)是指在一定时间内创新的速率有限。这个概念最早由Mathe Zibulevsky等人提出,并应用于信号处理中的稀疏表示算法。 在稀疏表示算法中,通常假设信号是以某些基向量的线性组合表示的,而稀疏表示算法的目标就是通过选择尽量少的基向量来近似原始信号。然而,如果信号的创新速率较高,即信号中出现的细节和特征的变化较快,那么传统的稀疏表示算法可能无法精确地捕捉到信号中的全部信息。 有限创新速率的概念是为了解决这个问题。它假设信号在一段时间内的变化相对较慢,并且引入了一种慢变化模型,即假设信号的创新速率是有限的。在这种情况下,可以通过在信号的表示中引入一些先验知识和约束条件,来提高稀疏表示的准确性。这些约束条件可以是基于信号本身的性质,也可以是来自外部领域知识的先验信息。 有限创新速率的概念在稀疏表示算法中被广泛应用,并且在信号处理和图像处理等领域取得了很好的效果。它提供了一种有效的方法来处理变化较快的信号,提高信号表示的精度和稳定性。同时,由于引入了先验知识和约束条件,这种方法也可以有效地减少所需的计算量和存储空间,提高算法的效率和实用性。 有限创新速率的概念在现代科学和工程中具有一定的重要性,它为我们理解和处理快速变化的信号提供了有益的思路和方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值