Verilog笔记(四)状态机

来自正点原子的学习笔记
我在学习的过程中会尽量把它和C语言进行比较,毕竟有较大的相似之处

RTL设计主要有组合电路时序电路两个部分,还有一个非常重要的部分就是状态机,都应该熟练的掌握(刷题网站里都有对应的题目哦!~)

状态机Verilog里非常常用的语法结构

1 状态机概念

1.1 引子

在这里插入图片描述

状态机非常适合在Verilog里实现一些顺序的逻辑(例子里的8023四个数字的输入和检测就是顺序逻辑)
而Verilog语言是并行的,不能像C语言一样顺序执行,因此采用状态机
在这里插入图片描述
从这个例子里我们能总结出状态机的概念

1.2 概念

状态机(State Machine):
有限状态机(Finite State Machine,简称FSM
有限状态之间按一定规律转换时序电路

2 状态机模型

下面介绍状态机的两个模型
在这里插入图片描述

状态寄存器由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变发生在时钟的跳变沿

组合逻辑F 不仅与 输入 有关,还与 当前状态 有关(F是当前状态和输入信号的函数)。

状态机的输出是由 输出组合逻辑G 提供的,G也是当前状态和输入信号的函数。(“解锁”就是状态机的输出结果)
更准确的说,刚才的“电子门锁”的G输出不直接(不)受输入的影响(当然,都与当前状态直接相关)
应该是Moore状态机
在这里插入图片描述

3 状态机设计

设计状态机的方法:四段论(八股文啊哈哈,严格的写法)
1 状态空间定义
2 状态跳转
3 下个状态判断
4 各个状态下的动作

3.1 状态空间定义

(偏抽象)
编码方式一:

//define  state space                               //定义了一天的四种状态,这个集合统称为“状态空间”
parameter  SLEEP   = 2'b00;                         //对四个状态进行编码,因为Verilog只能处理二进制数
parameter  STUDY 	= 2'b01;                        //用parameter来定义参数类型的数据
parameter  EAT      	= 2'b10;					//具体编码的值其实是无所谓的,顺序也是。
parameter  AMUSE 	= 2'b11;                        //但是还是尽量按照状态跳转的顺序来编码

// internal variable                                //定义储存状态的两个变量
reg 	[1:0] 	current_state;
reg 	[1:0] 	next_state;

编码方式二:独热码
:每个状态只有一个寄存器置位,译码逻辑简单

//define  state space                             
parameter  SLEEP   = 4'b1000;                      
parameter  STUDY 	= 4'b0100;                       
parameter  EAT      	= 4'b0010;   					
parameter  AMUSE 	= 4'b0001;   ;                     

// internal variable                                
reg 	[3:0] 	current_state;                       //状态位宽保持一致
reg 	[3:0] 	next_state;

3.2 状态跳转(时序逻辑)

// transition
always @(posedge  clk or negedge rst_n)begin
	if ( ! rst_n)
			current_state  <=  SLEEP;
	else 
			current_state  <= next _state; 			//时序逻辑里用非阻塞赋值,组合逻辑里用阻塞赋值
end 

3.3 下个状态判断(组合逻辑)

F是当前状态和输入信号的函数” 体现在 敏感列表上:

always @(current_state  or input_signals)begin 
//此处也可以用*,将块语句的中的所有变量添加到敏感列表中去

在这里插入图片描述
latch是电平触发的一个锁存器,会影响整个电路的时序分析,应避免
产生情况:
1.有if没else
2.case表达式没完全(比如default)

3.4 各个状态下的动作

组合逻辑有两种表达方式
方式一:assign的赋值语句

// action
wire read_book;
assign read_book = (current_state ==STUDY)	?	1'b1  : 1'b0			//条件运算符
//适用于输出信号不复杂

方式二:always 的组合语句

always @(current_stat)begin
	if (current_state == STUDY)
			read_book  =  1;
	else 
			read_book  =  0;			
end 
//适用于输出信号复杂

3.5 例子

除去状态空间定义,剩下 状态跳转下个状态判断各个状态下的动作,三个部分
因此也叫三段式状态机

模块的端口声明
在这里插入图片描述独热码来编码状态
s0没有位置置1,标明是初始状态
在这里插入图片描述
此处,状态空间定义完毕
///
下面开始三段式状态机

第一段:状态跳转(时序逻辑)
在这里插入图片描述
第二段:下个状态判断(组合逻辑)
至于当前状态有关,与输入无关
在这里插入图片描述
第三段:各个状态下的动作(时序逻辑)
虽然上文讲解的时候是组合逻辑但是在此处使用时序逻辑,还是有好处的
在这里插入图片描述在这里插入图片描述此处多了一个输出寄存器,多运用了一次时序逻辑,用于输出。

因此,三段式可以在组合逻辑后再增加一级寄存器来实现时序逻辑输出:
1.可以有效滤去组合逻辑输出的毛刺;
2.可以有效地进行时序计算与约束;
3.另外,对于总线形式的输出信号来说,容易使总线数据对齐,从而减小总线数据间的偏移(到达时间不同),减小接收端数据采样出错的频率。

  • 22
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Verilog是一种硬件描述语言,可以用于设计和建模数字电路。在Verilog中,可以使用段式状态机来实现状态机的行为。 段式状态机包括:状态寄存器、下一个状态逻辑、输出逻辑和输出寄存器。 1. 状态寄存器(State Register):用于存储当前系统的状态。它可以是一个寄存器或一个变量,表示当前系统所处的状态。 2. 下一个状态逻辑(Next State Logic):根据当前状态和输入信号,决定下一个状态。它可以是组合逻辑电路,根据输入信号和当前状态生成下一个状态的逻辑表达式。 3. 输出逻辑(Output Logic):根据当前状态和输入信号,决定系统的输出信号。它可以是组合逻辑电路,根据输入信号和当前状态生成输出信号的逻辑表达式。 4. 输出寄存器(Output Register):用于存储输出信号。它可以是一个寄存器或一个变量,表示当前系统的输出信号。 通过组合这个部分,可以实现一个完整的段式状态机。在Verilog中,可以使用always块来描述状态机的行为,并使用case语句来实现状态转移和输出逻辑。 以下是一个简单的Verilog示例,演示了一个基本的段式状态机: ```verilog module MyStateMachine ( input wire clk, input wire reset, input wire input_signal, output reg output_signal ); typedef enum logic [1:0] { STATE_IDLE, STATE_A, STATE_B, STATE_C } state_t; reg [1:0] current_state; reg [1:0] next_state; always @(posedge clk or posedge reset) begin if (reset) current_state <= STATE_IDLE; else current_state <= next_state; end always @(current_state or input_signal) begin case (current_state) STATE_IDLE: begin if (input_signal) next_state = STATE_A; else next_state = STATE_IDLE; end STATE_A: begin if (input_signal) next_state = STATE_B; else next_state = STATE_C; end STATE_B: begin if (input_signal) next_state = STATE_C; else next_state = STATE_IDLE; end STATE_C: begin if (input_signal) next_state = STATE_A; else next_state = STATE_B; end endcase end always @(posedge clk) begin case (current_state) STATE_IDLE: output_signal <= 1'b0; STATE_A: output_signal <= 1'b1; STATE_B: output_signal <= 1'b0; STATE_C: output_signal <= 1'b1; endcase end endmodule ``` 上述例子中,MyStateMachine模块表示一个简单的状态机,有个状态:IDLE、A、B和C。根据输入信号input_signal的值,状态机会进行状态转移,并根据当前状态生成输出信号output_signal的值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值