状态机的HDL设计与仿真验证

在这里插入图片描述
作者:毛茏玮 / Saint
掘金:https://juejin.im/user/5aa1f89b6fb9a028bb18966a
微博:https://weibo.com/5458277467/profile?topnav=1&wvr=6&is_all=1
GitHub:github.com/saint-000
CSDN: https://me.csdn.net/qq_40531974

状态机的HDL设计与仿真验证

一、实验原理:
状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。状态机分为三大类型:
1. Moore状态机:次态=f(现状),输出=f(现状),即输出信号是直接由状态寄存器译码得到

2.Mealy状态机:次态=f(现状,输入),输出=f(现状,输入),即以现时的输入信号结合即
将变成次态的现状编码成信号输出。

3.混合型状态机

二、实验目的:
在实验中经常会涉及到状态的改变,有时候任何状态之间都可以互相切换,如果直接用常规的编写方式对于一些没有规律的或则极其复杂的设计而言效率是非常低的。我们通过三段式的状态机代码的编写,体会该框架的综合性,熟悉了相应的编码方式后可以将其用来带入其他模块代码的编写。

三、实验内容:
摩尔状态机的VHDL代码录入及波形仿真。

四、实验器材(设备、元器件):
①软件Active-HDL9.2 ②Windows操作系统

五、(1)选择器
实验步骤:
1.打开Active-HDL9.2,页面会跳出提示框,可以选择之前建立好的文件打开,也可以创建新的设计文件,这里我们对选择器进行创建新的设计,故点击Create new workspace,然后
设置Workspace name为Moore。
2. 创建一个空的设计,添加一些基本信息,输入设计文件名。
3.在软件中点击File,选择New然后点击创建VHDL Source,对设计模型的实体,构造体进行命名,命名为Moore,此处四选一数据选择器的构造体填behavior,我们采用行为级描述。
4.在描述端口的时候输入输出应用不同的端口方向,rst,clk,x设为输入端口,z设为输出端口。
5.完成了端口设定软件会自动生成好基本的代码框架,我们在此基础上进行程序的编写。
代码如下:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity Moore is
	 port(
		 rst : in STD_LOGIC;	
		 clk : in STD_LOGIC;				   	
		 X : in STD_LOGIC;
		 Z : out STD_LOGIC
	     );
end Moore;
--}} End of automatically maintained section
architecture behavior of Moore is 
TYPE state_type is (S0,S1,S2,S3);
SIGNAL current_state,next_state:state_type;
begin 	
SYNCH:PROCESS(clk,rst)
begin
	if clk'EVENT AND clk='1'THEN
		if rst='1'THEN
			current_state<=S1;
		else
			current_state<=next_state;
		end if;
	end if;
end process;
STATE_TRANS:PROCESS(current_state,X)
begin
	case current_state is
		WHEN S0=>
		 IF X='0'THEN
			next_state<=S0;
		 ELSE
			next_state<=S2;
		 END IF;
		WHEN S1=>
		 IF X='0'THEN
			next_state<=S0;
		 ELSE
			next_state<=S2;
		 END IF;	
		WHEN S2=>
		 IF X='0'THEN
			next_state<=S2;
		 ELSE
			next_state<=S3;
		 END IF;
		WHEN S3=>
		 IF X='0'then
			next_state<=S3;
		 ELSE
			next_state<=S1;
		 END IF;
		WHEN others=>
		    next_state<=S1;
	END CASE;
END PROCESS;
OUTPUT_GEN:PROCESS(current_state)
begin
	CASE current_state is
		WHEN S0=>
		  Z<='0';
		WHEN S1=>
		  Z<='1';
		WHEN S2=>
		  Z<='1';
		WHEN S3=>
		  Z<='0';
		WHEN others=>
		  Z<='0';
	END CASE;
END PROCESS;		
	 -- enter your statements here --
end behavior;

6.把完成的代码进行编译,编译好的文件出现子项,其对应于文件中的实体和构造体,我们将出现的子项设为顶层,其目的是优先进行仿真,有时候多项目在同一个工作环境中,我们需选定优先仿真对象,然后进行仿真。

7.将待测信号加载到波形窗口,然后对各项输入信号设定波形信号,加激励进行仿真。

六、摩尔状态机
实验数据及结果分析:
对于摩尔状态机而言,其输出值仅由其当前状态确定。与Mealy不同,它的输出值由其当前状态和输入值决定。我们在波形图上可以发现当前状态为S0时,输出Z=0,当前状态为S1时,输出Z=1,当前状态为S2时,输出Z=1,当前状态为S3时,输出Z=0。观察仿真波形结果对比moore型状态机的状态转换表验证设计。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

七、实验结论:
描述状态机有三种方法:状态转移图、状态转移表、HDL描述,状态转移图直观,设计用,而HDL语言方便描述,实现时用;本次实验对moore状态机进行了HDL描述,通过对设计代码各个语法的编写思想,我们可以将状态机两个定义,三个进程的编写方式套用到其他复杂模块功能描述上,减小了编程难度。

八、总结及心得体会:
(1)分析状态机特点: 
1. 对于状态的描述一般先声明一个枚举数据类型,语句如下: 
Type state_type is(idle,tap1,tap2,tap3,tap4); 
2. 对于存储当前状态的对象一般用是一个信号,即: 
Signal state: state_type; 
3. 对于状态机的下一个状态的判断一般是通过对时钟上升沿判断的if then else 语句内嵌
case when 语句 
4. 对于状态机的输出则可以用一个条件或者选择信号声明语句,或者再用一个case语句来
实现信号输出。

(2)Moore状态机:在时钟脉冲的有限个门延时之后,输出达到稳定。输出会在一个完整的时钟周期内保持稳定,即使在该时钟内输入信号改变了,输出信号也不改变。输入对输出的影响要到下个时钟才能反应出来。所以对于摩尔状态机的设计中,体会到了其独特的编码方式具有模板性,编程模式较为简单,但同时也要注意对非法状态的处理,提高系统的可靠性和稳定性。

九、对本实验过程及方法、手段的改进建议:
对于本实验我们采用的是代码录入,我们还可以尝试用FSM(状态图编辑器)录入方式。
在这里插入图片描述
在这里插入图片描述
编译生成源程序代码:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity \ Moore \ is 
	port (
		clk: in STD_LOGIC;
		rst: in STD_LOGIC;
		X: in STD_LOGIC;
		Z: out STD_LOGIC);
end \ Moore \;
architecture \behavior \ of \ Moore \ is
-- SYMBOLIC ENCODED state machine: Sreg0
type Sreg0_type is (
    S2, S3, S1, S0
);
-- attribute enum_encoding of Sreg0_type: type is ... -- enum_encoding attribute is not supported for symbolic encoding
signal Sreg0, NextState_Sreg0: Sreg0_type;
-- Declarations of pre-registered internal signals
begin


----------------------------------------------------------------------
-- Machine: Sreg0
----------------------------------------------------------------------
------------------------------------
-- Next State Logic (combinatorial)
------------------------------------
Sreg0_NextState: process (X, Sreg0)
begin
	NextState_Sreg0 <= Sreg0;
	-- Set default values for outputs and signals
	Z <= '1';
	case Sreg0 is
		when S2 =>
			z<='1';
			if x='1' then
				NextState_Sreg0 <= S3;
			elsif x='0' then
				NextState_Sreg0 <= S2;
			end if;
		when S3 =>
			z<='0';
			if x='1' then
				NextState_Sreg0 <= S1;
			elsif x='0' then
				NextState_Sreg0 <= S3;
			end if;
		when S1 =>
			z<='1';
			if x='1' then
				NextState_Sreg0 <= S2;
			elsif x='0' then
				NextState_Sreg0 <= S0;
			end if;
		when S0 =>
			Z<='0';
			if X='0' then
				NextState_Sreg0 <= S0;
			elsif x='1' then
				NextState_Sreg0 <= S2;
			end if;
--vhdl_cover_off
		when others =>
			null;
--vhdl_cover_on
	end case;
end process;
------------------------------------
-- Current State Logic (sequential)
------------------------------------
Sreg0_CurrentState: process (clk, rst)
begin
	if rst='1' then
		Sreg0 <= S1;
	elsif clk'event and clk = '1' then
		Sreg0 <= NextState_Sreg0;
	end if;
end process;
end \behavior \;

猜你喜欢

转载自blog.csdn.net/qq_40531974/article/details/85788464
今日推荐