⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statemachine.vhd

📁 这是一些经典的vhdl example
💻 VHD
字号:
Library IEEE ;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
ENTITY statemachine IS
	PORT(clk 				: IN STD_LOGIC;						--全局时钟
		 keyvalue			: IN STD_LOGIC_VECTOR(3 DOWNTO 0);	--按键值
		 keypressed			: IN STD_LOGIC;                     --有按键来标志
		 functionkey		: IN STD_LOGIC;                     --是否是功能键
		 buffertime			: BUFFER STD_LOGIC_VECTOR(23 DOWNTO 0);--缓存时间
		 iscount			: OUT STD_LOGIC;					--状态机状态是否是计数态
		 alarmload 			: OUT STD_LOGIC;                    --闹钟时间加载信号 
		 timeload			: OUT STD_LOGIC);                   --计时器时间加载信号
END statemachine;
ARCHITECTURE rtl OF statemachine IS
	--定义状态机状态类型
	TYPE state IS (count,modifytime1,modifytime2,modifytime3,modifytime4,modifytime5,
				   modifytime6,modifytime7,loadtime,
				   setalarm1,setalarm2,setalarm3,setalarm4,setalarm5,setalarm6,
				   setalarm7,loadalarm); 
    --当前状态和次态
	SIGNAL present_state  	: state :=count;
	SIGNAL next_state		: state :=count;
	--缓存时间的信号表示
	SIGNAL time_temp		: STD_LOGIC_VECTOR(23 DOWNTO 0);
BEGIN
	--状态更新
	PROCESS(clk)
	BEGIN
		IF(clk'event AND clk='1')THEN
			present_state <= next_state;
		END IF;
	END PROCESS;
	--状态译码
	PROCESS(keyvalue,keypressed,functionkey,present_state,clk)
	BEGIN
		IF(clk'event AND clk='0')THEN
		CASE present_state IS
			--计时状态
			WHEN count =>
				IF(keypressed='1' AND keyvalue="1110") THEN
					next_state <= modifytime1;            --返回计时状态
				ELSIF(keypressed='1' AND keyvalue="1111") THEN
					next_state <= setalarm1;               
				ELSE
					next_state <= present_state;
				END IF;
				time_temp <= "000000000000000000000000";
			--校时状态1,,等待输入小时的高位
			WHEN modifytime1 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;                --返回计时状态
				ELSIF(keypressed='1' AND keyvalue<="0010") THEN
				--小时的高位可以输入0~2
					next_state <= modifytime2;
					time_temp(23 DOWNTO 20) <= keyvalue;
				ELSE
					next_state <= present_state;
					time_temp <= time_temp;					
				END IF;
			--校时状态2,等待输入小时的低位	
			WHEN modifytime2 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND functionkey='0' AND time_temp(23 DOWNTO 20) <= "0001") THEN
					--小时的高位为0和1时,可以输入0~9
					next_state <= modifytime3;
					time_temp(19 DOWNTO 16) <= keyvalue;
				ELSIF(keypressed='1' AND time_temp(23 DOWNTO 20)="0010" AND keyvalue <= "0011") THEN
					--小时的高位为2时,只可以输入0~3
					next_state <= modifytime3;
					time_temp(19 DOWNTO 16) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;
			--校时状态2,等待输入分钟的高位
			WHEN modifytime3 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND keyvalue<="0101") THEN
				--分钟的高位可以输入0~5
					next_state <= modifytime4;
					time_temp(15 DOWNTO 12) <= keyvalue;
				ELSE
					next_state <= present_state;
					time_temp <= time_temp;		
				END IF;
			--校时状态4,等待输入分钟的低位
			WHEN modifytime4 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND functionkey = '0') THEN
				--分钟的低位可以输入0~9
					next_state <= modifytime5;
					time_temp(11 DOWNTO 8) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;	
				END IF;		
			--校时状态5,等待输入秒的高位
			WHEN modifytime5 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND keyvalue<="0101") THEN
				--秒的高位可以输入0~5
					next_state <= modifytime6;
					time_temp(7 DOWNTO 4) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;
			--校时状态6,,等待输入秒的低位
			WHEN modifytime6 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND functionkey='0') THEN
				--秒的低位可以输入0~9
					next_state <= modifytime7;
					time_temp(3 DOWNTO 0) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;	
			--校时状态7,等待输入确认键A
			WHEN modifytime7 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND keyvalue="1010") THEN
				--输入确认键
					next_state <= loadtime;
				ELSE
					next_state <= present_state;	
				END IF;
				time_temp <= time_temp;
			--计时器时间加载状态
			WHEN loadtime =>
				next_state <= count;
				time_temp <= time_temp;
			--设闹状态1,等待输入小时高位
			WHEN setalarm1 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND keyvalue<="0010") THEN
				--小时高位可以0~2
					next_state <= setalarm2;
					time_temp(23 DOWNTO 20) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;	
			--设闹状态2,等待输入小时低位
			WHEN setalarm2 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND functionkey='0' AND time_temp(23 DOWNTO 20)<="0001") THEN
				--小时的高位为0和1时,可以输入0~9
					next_state <= setalarm3;
					time_temp(19 DOWNTO 16) <= keyvalue;
				ELSIF(keypressed='1' AND time_temp(23 DOWNTO 20)="0010" AND keyvalue<="0011") THEN
				--小时的高位为2时,可以输入0~3
					next_state <= setalarm3;
					time_temp(19 DOWNTO 16) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;
			--设闹状态3,等待输入分钟高位
			WHEN setalarm3 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND keyvalue<="0101") THEN
				--分钟高位可以输入0~5
					next_state <= setalarm4;
					time_temp(15 DOWNTO 12) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;
			--设闹状态4,等待输入分钟低位
			WHEN setalarm4 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND functionkey='0') THEN
				--分钟低位可以输入0~9
					next_state <= setalarm5;
					time_temp(11 DOWNTO 8) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;
			--设闹状态5,等待输入秒高位		
			WHEN setalarm5 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND keyvalue<="0101") THEN
					next_state <= setalarm6;
					time_temp(7 DOWNTO 4) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;
			--设闹状态6,等待输入秒低位	
			WHEN setalarm6 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND functionkey='0') THEN
					next_state <= setalarm7;
					time_temp(3 DOWNTO 0) <= keyvalue;
				ELSE
					next_state <= present_state;	
					time_temp <= time_temp;
				END IF;	
			--设闹状态7,等待输入确认键	
			WHEN setalarm7 =>
				IF(keypressed='1' AND keyvalue="1011") THEN
					next_state <= count;
				ELSIF(keypressed='1' AND keyvalue="1010") THEN
					next_state <= loadalarm;
				ELSE
					next_state <= present_state;	
				END IF;
				time_temp <= time_temp;
			--闹钟时间加载状态
			WHEN loadalarm =>
				next_state <= count;
				time_temp <= time_temp;
			--多于态处理
			WHEN OTHERS =>
				next_state <= count;
				time_temp <= time_temp;
		END CASE;
		END IF;
	END PROCESS;
	--输出缓存时间
	buffertime <= time_temp;
	--输出译码
	PROCESS(present_state)
	BEGIN
		--状态机是否在计数态
		IF(present_state = count)THEN
			iscount <= '1';
		ELSE
			iscount <= '0';
		END IF;
		--计时器时间加载信号
		IF(present_state = loadtime)THEN
			timeload <= '1';
		ELSE
			timeload <= '0';
		END IF;
		--闹钟时间加载信号
		IF(present_state = loadalarm)THEN
			alarmload <= '1';
		ELSE
			alarmload <= '0';
		END IF;
	END PROCESS;
END rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -