⭐本专栏针对 FPGA 进行入门学习,从数电中常见的逻辑代数讲起,联合 Verilog HDL 语言学习与仿真,次要对组合逻辑电路与时序逻辑电路进行剖析与设计,对状态机 FSM 进行分析与建模。
🔥文章和代码已归档至【Github 仓库:hardware-tutorial】,须要的敌人们自取。或者关注公众号【AIShareLab】,回复 FPGA 也可获取。
状态编码
在应用 Verilog HDL 形容状态机时,通常用参数定义语句 parameter 指定状态编码。状态编码方案个别有三种:天然二进制编码、格雷 (Gray) 编码和独热码(one-hot 编码)。对应于图所示的状态图的各种编码方案如表所示。
无限状态机的编码方案
状态机编码对状态机速度和面积关系重大
罕用编码
- 二进制码(binary)
- 格雷码(Gray)
- 独热码(one-hot)
二进制码与格雷码是压缩状态编码,应用起码的状态位进行编码。
二进制编码的长处是应用的状态向量起码,但从一个状态转换到相邻状态时,可能有多个比特位发生变化,瞬变次数多,易产生毛刺。
格雷码
特点是以后状态扭转时,状态向量中仅一位发生变化,因而当零碎的状态变动是基于异步的输出信号时,格雷编码可能防止进入谬误的状态。
格雷码既能够打消状态转换时多状态信号传输提早产生的毛刺,又可降低功耗。
独热码(one-hot 编码)
N 个状态应用 N 个触发器(FF)
- 缩小了状态寄存器之间的组合逻辑级数,因而进步了运行速度;
- 触发器 (FF) 数量减少,组合逻辑电路缩小;
- 任何状态都能够间接增加 / 删除等批改而不会影响状态机的其余部分;
- 因为译码简略,可进步速度,且易于批改。
独热码 (one-hot 编码) 的特点是:状态数等于触发器 (FF) 的数目,冗余的触发器带来的益处是译码电路的简单化,因而它的速度十分快,此外因为 FPGA 器件外部触发器的数量是固定的且比拟丰盛,所以 one-hot 编码非常适合于 FPGA 设计。
独热码的毛病
- 变动的状态位越多,组合输入稳固前所需的工夫就越长,产生的毛刺就越多;
- 多个寄存器可能受异步输出的影响,使得亚稳态产生的概率有所增加;
状态机简单状态跳转的分支很多时,要正当的调配状态编码,保障每个状态跳转都仅有 1 位发生变化,这是很艰难的事件。
不论应用哪种编码,状态机中的各个状态都应该应用符号常量,而不应该间接应用编码数值,赋予各状态有意义的名字对于设计的验证和代码的可读性都是无益的。
编码方法 | 面积 | 速度 | 状态数量 |
---|---|---|---|
Binary (程序二进制) | 较好 | 较差 | Log2(state N) |
One-hot | 较差 | 较好 | States Number |
Gray | 较好 | 较差 | Log2(state N) |
如何打消输入端产生的毛刺
后面介绍的一般状态机由组合逻辑电路决定电路的输入. 当组合逻辑较大时,若状态触发器的值发生变化或者输出信号发生变化,因为各信号在组合逻辑外部通过的门路不一样,就容易在输入端产生毛刺。
上面介绍两种罕用打消毛刺的办法:
1. 具备流水线输入的 Mealy 状态机
为了打消毛刺,能够在一般 Mealy 的输入逻辑后加一组输入寄存器,将寄存器的输入值作为输入向量,这种 Mealy 状态机的等效方框如图所示。
2. 在状态位里编码输入的 Moore 状态机
这种办法的指导思想是将状态寄存器和输入向量对立进行编码,行将状态位自身作为输入信号,其等效状态框图如下所示。
上面以图所示的状态图阐明在状态位里编码输入的办法。图中,状态机共有三个状态:IDLE,START 和 WAIT,输出信号为:input_1,input_2,input_3,input_4。这些输出信号的不同逻辑组合就形成了状态之间跳转的条件。
该状态机须要管制两个输入信号:output_1 和 output_2。能够采纳 4bits 的状态编码,其中高两位示意以后的状态,开端两位管制 output_1 和 output_2 的输入。IDLE 状态编码为 4’b0000,START 状态编码为 4’b0101,WAIT 状态编码为 4’b1011。
参考程序如下所示:
module FSM1 (nRST, CP, input_1, input_2, input_3, input_4, output_1, output_2) ;
input input_1, input_2, input_3, input_4; // 定义输出变量
input nRST, CP;
output output_1, output_2 ; // 定义输入变量
wire output_1, output_2;
reg [3 : 0] Current_state, Next_state;
// 状态参量的定义,依据后面所述的全译码状态编码
parameter [3 : 0] IDLE = 4'b0000, START = 4'b0101, WAIT = 4'b1011;
//The first always block, sequential state transition
always @(posedge CP or negedge nRST)
if (!nRST) // 当零碎复位时,状态寄存器置为 IDLE 状态
Current_state <= IDLE; // 设置初态(IDLE)
else // 状态寄存器进行状态存储,将下一状态存储到状态寄存器成为以后状态
Current_state <= Next_state;
// The second always block, combinational condition judgment
always @(Current_state or input_1 or input_2 or input_3 or input_4)
case(Current_state) // 依据以后状态和状态转换条件进行译码
IDLE:
if(input_1 && input_2) Next_state = START;
else Next_state = IDLE;
START:
if(input_3) Next_state = WAIT;
else Next_state = START;
WAIT:
if(input_4) Next_state = IDLE;
else Next_state = WAIT;
default: Next_state = IDLE;
endcase
// 状态机的输入逻辑
assign output_1 = Current_state[1];
assign output_2 = Current_state[0];
endmodule
如何应用 One-hot 编码方案设计状态机
对状态机的各个状态赋予一组特定的二进制数称为状态编码。比拟罕用的有天然二进制码、格雷码和 One-hot 编码。天然二进制码和格雷码的编码方案应用的触发器较少,其编码效率较高,但负责依据以后状态和状态转换条件进行译码的组合电路会比较复杂,其逻辑规模也较大,使得次态逻辑在传输过程中须要通过多级逻辑,从而影响电路的工作速度。
One-hot 编码方案应用 n 位状态触发器示意具备 n 个状态的状态机,每个状态与一个独立的触发器绝对应,并且在任何时刻其中只有一个触发器无效(其值为 1)。尽管这种计划会应用较多的触发器,但它的编码方式非常简单,可无效地简化组合电路,并换得工作可靠性和工作速度的进步。在大规模可编程逻辑器件如 FPGA 中,触发器数量较多而门逻辑绝对较少,One-hot 编码方案有时反而更有利于进步器件资源的利用率。
定义以后状态向量 state 为一个 5 -bits 向量,开端的两位示意状态机输入,state[2]为 1 示意状态 IDLE,state[3]为 1 示意状态 START,state[4]为 1 示意状态 WAIT。
上面是基于 One-Hot 编码方式的状态机实现代码:
module FSM2 (nRST, CP, input_1, input_2, input_3, input_4, output_1, output_2) ;
input input_1, input_2, input_3, input_4; // 定义输出变量
input nRST, CP;
output output_1, output_2 ; // 定义输入变量
wire output_1, output_2;
reg [4 : 0] state, Next_state;
parameter [4 : 0] IDLE = 5’b001_00, // 状态参量,开端两位示意对应的输入
START = 5’b010_01,
WAIT = 5’b100_11;
// 状态对应在 state 中的示意地位,One-hot
parameter [2:0] IDLE_POS = 3'd2, // IDLE POSition
START_POS = 3'd3, // START POSition
WAIT_POS = 3'd4; // WAIT POSition
always @(posedge CP or negedge nRST) // 状态存储
if (!nRST) state <= IDLE;
else state <= Next_state;
always @(input_1 or input_2 or input_3 or input_4)// 状态转移逻辑
begin
Next_state = IDLE; // 设置初态
case(1’b1) //One-Hot 编码实现状态转移时,
// 每次取 state 的一位与 1 比拟
state[IDLE_POS]:
if(input_1 && input_2)
Next_state = START;
else Next_state = IDLE;
state[START_POS]:
if(input_3)
Next_state = WAIT;
else Next_state = START;
state[WAIT_POS]:
if(input_4)
Next_state = IDLE;
else Next_state = WAIT;
default: Next_state = IDLE;
endcase
end
// 状态机的输入逻辑
assign output_1 = state[1];
assign output_2 = state[0];
endmodule
One-hot 编码特点:指定各个状态在状态编码中的示意位,采纳参量定义形式指定 One-hot 状态编码;应用 always 语句形容状态寄存器的状态存储;应用敏感表和 case 语句形容状态转换逻辑,在 case 语句中只采纳一位寄存器比拟形式;应用 assign 语句形容状态编码管制的状态机输入。
参考文献:
- Verilog HDL 与 FPGA 数字零碎设计,罗杰,机械工业出版社,2015 年 04 月
- Verilog HDL 与 CPLD/FPGA 我的项目开发教程(第 2 版), 聂章龙, 机械工业出版社, 2015 年 12 月
- Verilog HDL 数字设计与综合(第 2 版), Samir Palnitkar 著,夏宇闻等译, 电子工业出版社, 2015 年 08 月
- Verilog HDL 入门(第 3 版), J. BHASKER 著 夏宇闻甘伟 译, 北京航空航天大学出版社, 2019 年 03 月
欢送关注公众号【AIShareLab】,一起交换更多相干常识,前沿算法,Paper 解读,我的项目源码,面经总结。