我们知道状态机输出为当前状态和输入的函数,事实上还存在这样的状态机,它的输出不仅与当前状态和输入有关还与前一个(或者多个)状态有关。这类状态机通常被称为“扩展状态机”或“历史状态机”,相比常规状态机能够处理更加复杂的情况,因为它可以记住先前的状态信息,常规状态机的原理图见图一。

历史状态机主要特征在于,历史状态机通过记录在此之前的少数状态,能够立刻恢复到此前的某一状态,或者输出与此前状态有关的信号,图二中只展示了记录当前状态的前一状态历史状态机,不难推广到多个状态寄存器组记录前多个历史状态。

历史状态机能够保持对过去状态的记录,即它在状态转移后存储最近此前的状态信息,可以在必要时进行回溯或重新计算。历史状态机的这种属性能辅助系统进行进行决策,系统可以根据当前状态和历史状态(记录)进行决策和执行相应的行为,这使得历史状态机能够对系统的演变历史和先前的决策做出反应。
比较图二和图一可见,如果从图二紫色虚线处隔断,历史状态机可以使用常规状态机加上当前状态的延迟逻辑等效表达,与常规状态机的次态判决只使用当前状态和输入不同的是,历史状态机的次态组合逻辑还额外使用了滞后一定周期的“历史态”,下面是基于Verilog语言描述的一个简单例子:
下面的状态机代码中,添加了一个名为protocol_state_hist的历史状态寄存器,它记录上一个周期的状态供下一个周期的状态转移决策使用。在时钟的上升沿,当前态被保存到protocol_state_hist中成为历史状态,它可以被次态逻辑使用进行条件判断以决定次态protocol_state_next。
module CommunicationProtocol (
input wire clk, // 时钟信号
input wire reset, // 复位信号
input wire connect_request, // 连接请求信号
input wire data, // 数据包信号
input wire ack, // 确认消息信号
output wire send_data, // 发送数据信号
output wire send_ack // 发送确认消息信号
);
// 定义状态
reg[1:0] protocol_state;
parameter CONNECTING = 2'b00;
parameter SENDING = 2'b01;
parameter RECEIVING = 2'b10;
// 次态定义
reg[1:0] protocol_state_next;
// 定义状态寄存器(当前)
reg[1:0] protocol_state_reg;
// 定义历史状态寄存器
reg[1:0] protocol_state_hist;
// 定义状态转移规则
always @(posedge clk or posedge reset) begin
if (reset) begin
protocol_state_reg <= CONNECTING;
protocol_state_hist <= CONNECTING;
end
else begin
protocol_state_reg <= protocol_state_next;
protocol_state_hist <= protocol_state_reg;
end
end
// 定义状态逻辑
always @(*) begin
case (protocol_state_hist) /*也可能是protocol_state_reg,根据需要(这里就是上图中的“云”——求解次态的组合逻辑)*/
CONNECTING:
if (connect_request)
protocol_state_next = SENDING;
else
protocol_state_next = CONNECTING;
SENDING:
if (data)
protocol_state_next = RECEIVING;
else
protocol_state_next = SENDING;
RECEIVING:
if (ack)
protocol_state_next = SENDING;
else
protocol_state_next = RECEIVING;
default:
protocol_state_next = CONNECTING;
endcase
end
// 输出动作逻辑
assign send_data = (protocol_state_reg == SENDING);
assign send_ack = (protocol_state_reg == RECEIVING);
endmodule
在数字逻辑设计中,历史状态机(Historical State Machine)可用于实现以下功能:
- 状态序列控制:历史状态机用于控制系统在不同状态之间的转移。通过记录历史状态和定义状态转移规则,可以确定系统在不同条件下应采取的行动,从而实现状态序列的控制。
- 错误检测和纠正:历史状态机可用于检测和纠正数字系统中的错误。通过在状态转移过程中检查输入和输出,可以捕捉和处理错误情况,例如错误的输入序列或未预期的状态转换。
- 协议处理:历史状态机常用于处理通信协议。通过定义协议的状态和状态转移规则,可以有效地处理协议消息的接收、解析、验证和响应。历史状态机能够跟踪通信过程中的状态和历史信息,确保协议的正确执行。
- 计数器和序列生成器:历史状态机可用于实现计数器和序列生成器。通过定义不同状态和状态转移规则,可以实现不同的计数模式和序列生成模式,例如二进制计数器、循环计数器、序列生成器等。
- 复杂逻辑控制:历史状态机可以实现复杂的逻辑控制功能。通过定义不同的状态和状态转移规则,可以根据输入信号和历史状态来决定系统的行为,实现复杂的逻辑运算和控制逻辑。
设计历史状态机时,需要考虑以下几个关键要素:
- 状态集合:确定系统或程序的所有可能状态。状态应该能够清晰地描述系统的特定时刻的情况,并包括系统内部状态和外部环境的状态。
- 状态转移规则:定义从一个状态转移到另一个状态的规则。这些规则可以基于输入信号、外部事件或内部条件来确定状态转移。状态转移规则决定了系统在给定条件下如何响应和变化。
- 输入信号和外部事件:确定系统接收的输入信号和外部事件。这些信号和事件可以触发状态转移或影响系统的行为。输入信号和外部事件可以是来自外部环境的传感器信号、用户输入或其他系统的输出。
- 输出动作:定义系统在特定状态下采取的操作或行为。输出动作可以是产生输出信号、控制外部设备、修改内部状态或执行其他操作。输出动作可以与状态转移规则和输入信号关联,以实现系统的预期行为。
- 历史记录:确定是否需要记录历史状态。历史记录允许系统回溯到先前的状态,并根据历史状态做出决策或执行操作。历史记录可以通过寄存器或其他方式来实现。
- 初始化状态:确定系统的初始状态。在系统启动或复位时,需要指定系统应处于的初始状态。初始状态应与系统的要求和预期行为相符。