状态控制电路的VHDL实现如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY controllor IS
PORT(
RESET:IN STD_LOGIC; --复位信号
KEY: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --输入时间
SET_T:IN STD_LOGIC; --时间设置信号
START:IN STD_LOGIC; --开始烹调信号
TEST:IN STD_LOGIC; --显示电路测试信号
CLK:IN STD_LOGIC; --时钟脉冲
DONE:IN STD_LOGIC; --完成信号
COOK:OUT STD_LOGIC; --指示烹调状态,提示计时器开始计数
LD_TEST:OUT STD_LOGIC; --指示数据装载电路载入的用于测试的数据
LD_CLK:OUT STD_LOGIC; --指示数据装载电路载入设置时间数据
DATA:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);--16位数据
LED_SET_T:OUT STD_LOGIC; --LED显示状态
LD_DONE:OUT STD_LOGIC --LED显示完成
);
END controllor;
ARCHITECTURE rtl OF controllor IS
TYPE STATES IS(IDLE,LAMP_TEST,SET_CLOCK,TIMER,DONE_MSG);
SIGNAL NXT,CUR:STATES; --2个信号:下一状态、当前状态
SIGNAL DATATMP:STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL SET_T0: STD_LOGIC; --设置时间信号
BEGIN
PROCESS(CLK,RESET) --时钟和复位的进程
BEGIN
IF RESET='1' THEN --复位时将IDLE(显示0000)赋予当前状态
CUR<=IDLE;
ELSIF CLK'EVENT AND CLK='1' THEN
CUR<=NXT; --如果不是,遇到上边沿则自动跳转下一状态
END IF;
END PROCESS;
PROCESS(RESET,KEY) --复位和输入的进程
BEGIN --可以让输入4位数字 显示时间
IF RESET = '1' THEN --复位时不论任何状态数码管都将显示0000
DATATMP <= (others => '0');
ELSE
IF KEY(3)'EVENT AND KEY(3) = '1' THEN --设置分的十位
IF DATATMP(15 DOWNTO 12) = "0101" THEN --5自动跳转到0
DATATMP(15 DOWNTO 12) <= "0000";
ELSE
DATATMP(15 DOWNTO 12) <= DATATMP(15 DOWNTO 12) + 1;
END IF; --否则自动加1
END IF;
IF KEY(2)'EVENT AND KEY(2) = '1' THEN --设置分的个位
IF DATATMP(11 DOWNTO 8) = "1001" THEN --9自动跳转到0
DATATMP(11 DOWNTO 8) <= "0000";
ELSE
DATATMP(11 DOWNTO 8) <= DATATMP(11 DOWNTO 8) + 1;
END IF; --否则自动加1
END IF;
IF KEY(1)'EVENT AND KEY(1) = '1' THEN --设置秒的十位
IF DATATMP(7 DOWNTO 4) = "0101" THEN --5自动跳转到0
DATATMP(7 DOWNTO 4) <= "0000";
ELSE
DATATMP(7 DOWNTO 4) <= DATATMP(7 DOWNTO 4) + 1;
END IF; --否则自动加1
END IF;
IF KEY(0)'EVENT AND KEY(0) = '1' THEN --设置秒的个位
IF DATATMP(3 DOWNTO 0) = "1001" THEN --9自动跳转到0
DATATMP(3 DOWNTO 0) <= "0000";
ELSE
DATATMP(3 DOWNTO 0) <= DATATMP(3 DOWNTO 0) + 1;
END IF;
END IF; --否则自动加1
END IF;
DATA <= DATATMP;
END PROCESS;
PROCESS(SET_T,RESET) --设置时间和复位进程
BEGIN
IF RESET = '1' THEN --复位时设置时间变为低电平
SET_T0 <= '0';
ELSIF SET_T'EVENT AND SET_T = '1' THEN --按下SET_T键时
SET_T0 <= NOT SET_T0; --SET_T非它前之状态
END IF;
IF SET_T0 = '1' THEN
LED_SET_T <= '1'; --赋予SET_T持续电平
ELSE
LED_SET_T <= '0'; --赋予SET_T持续电平
END IF;
END PROCESS;
PROCESS(CLK,CUR,SET_T,START,TEST,DONE) IS
BEGIN
NXT<=IDLE; --将IDLE载入NXT
LD_TEST<='0'; --复位
LD_DONE<='0';
LD_CLK<='0';
COOK<='0';
CASE CUR IS
WHEN LAMP_TEST=> --译码器显示测试状态
LD_TEST<='1';
COOK<='0';
WHEN SET_CLOCK=> --烹调时间测试状态
LD_CLK<='1';
COOK<='0';
WHEN DONE_MSG=> --完成信息显示状态
LD_DONE<='0';
COOK<='0';
WHEN IDLE=> --初始状态定义
IF TEST='1' THEN
NXT<=LAMP_TEST; --设置TEST
LD_TEST<='1';
ELSIF SET_T0='1' THEN --设置 SET_T
NXT<=SET_CLOCK;
LD_CLK<='1';
ELSIF START='1' AND DONE='0' THEN --设置计时模式
NXT<=TIMER;
COOK<='1';
END IF;
WHEN TIMER=>
IF DONE='1' THEN --设置计时完成
NXT<=DONE_MSG;
LD_DONE<='0';
ELSE
NXT<=TIMER;
COOK<='1';
END IF;
-- WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
END rtl;
--------------------------------------------------------------------------------------
--数据装载电路的VHDL实现如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY loader IS
PORT(
DATAIN:IN STD_LOGIC_VECTOR(15 DOWNTO 0); --输入16位数据
LD_TEST:IN STD_LOGIC;
LD_CLK:IN STD_LOGIC;
LD_DONE:IN STD_LOGIC;
DATAOUT:OUT STD_LOGIC_VECTOR(15 DOWNTO 0); --输出16位数据
LOAD:OUT STD_LOGIC --选择状态
);
END loader;
ARCHITECTURE rtl OF loader IS
BEGIN
PROCESS(DATAIN,LD_TEST,LD_CLK,LD_DONE)
CONSTANT ALLS:STD_LOGIC_VECTOR(15 DOWNTO 0)--测试信息
:="1000100010001000"; --显示8888
CONSTANT DONE:STD_LOGIC_VECTOR(15 DOWNTO 0)--烹调完成信息
:="1010101111001101";
VARIABLE TEMP:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
LOAD<=LD_TEST OR LD_DONE OR LD_CLK; --三选一状态
TEMP:=LD_TEST&LD;_DONE&LD;_CLK; --中间变量定义
CASE TEMP IS
WHEN"100"=>--测试
DATAOUT<=ALLS;
WHEN"010"=>--烹调完成
DATAOUT<=DONE;
WHEN"001"=>
DATAOUT<=DATAIN;
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
END rtl;
--------------------------------------------------------------------------------------------------
--十进制计数器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt10 IS
PORT(
CLK:IN STD_LOGIC;
LOAD,CLR:IN STD_LOGIC; --CLR:清除数据
EN:IN STD_LOGIC; --信号使能
DATAIN:IN STD_LOGIC_VECTOR(3 DOWNTO 0); --输入的4位数据
Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --输出的4位数据
CARRY_OUT:OUT STD_LOGIC --数据装载
);
END cnt10;
ARCHITECTURE rtl OF cnt10 IS
SIGNAL TMP:STD_LOGIC_VECTOR(3 DOWNTO 0); --链接输入输出
BEGIN --数据的信号
PROCESS(CLK,LOAD,CLR,EN)
BEGIN
IF CLR = '1' THEN --当CLR高电平,数据变为0000
TMP<= "0000";
ELSIF LOAD='1'THEN --否则装载输入的数据
TMP<=DATAIN;
ELSIF CLK'EVENT AND CLK='0'THEN --上升沿时,执行10进制减法
IF EN='1'THEN
IF TMP="0000"THEN --0跳转到9
TMP<="1001";
ELSE --自动减1
TMP<=TMP-'1';
END IF;
END IF;
END IF;
IF TMP="0000"THEN
CARRY_OUT<='1'; --COOK<=CARRY_OUT
ELSE
CARRY_OUT<='0';
END IF;
END PROCESS;
Q<=TMP;
END rtl;
--------------------------------------------------------------------------------------------------
--六进制减法计数器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt6 IS
PORT(
CLK:IN STD_LOGIC;
LOAD,CLR:IN STD_LOGIC;
EN:IN STD_LOGIC;
DATAIN:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
CARRY_OUT:OUT STD_LOGIC
);
END cnt6;
ARCHITECTURE rtl OF cnt6 IS
SIGNAL TMP:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
PROCESS(CLK,LOAD,CLR,EN)
BEGIN
IF CLR = '1' THEN
TMP<= "0000";
ELSIF LOAD='1' THEN
TMP<=DATAIN;
ELSIF CLK'EVENT AND CLK='0'THEN --上升沿时进行6进制减法
IF EN='1'THEN
IF TMP="0000"THEN --0自动跳转到5
TMP<="0101";
ELSE
TMP<=TMP-'1'; --否则自动减1
END IF;
END IF;
END IF;
IF TMP="0000"THEN
CARRY_OUT<='1'; --赋值给COOK
ELSE
CARRY_OUT<='0';
END IF;
END PROCESS;
Q<=TMP;
END rtl;
--------------------------------------------------------------------------------------------------
--计时电路的VHDL实现如下:
--计数器电路模块设计
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY counter IS
PORT(
COOK:IN STD_LOGIC;
LOAD,CLR:IN STD_LOGIC;
CLK:IN STD_LOGIC;
DATA:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
SEC0:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --秒个位
SEC1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --秒十位
MIN0:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --分个位
MIN1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --分十位
DONE:OUT STD_LOGIC --完成
);
END counter;
ARCHITECTURE rtl OF counter IS
--定义十进制和六进制计数器电路模块
COMPONENT cnt10 IS
PORT(
CLK:IN STD_LOGIC;
LOAD,CLR:IN STD_LOGIC;
EN:IN STD_LOGIC;
DATAIN:IN STD_LOGIC_VECTOR(3 DOWNTO 0); --输入
Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --输出
CARRY_OUT:OUT STD_LOGIC --状态
);
END COMPONENT cnt10;
COMPONENT cnt6 IS
PORT(
CLK:IN STD_LOGIC;
LOAD,CLR:IN STD_LOGIC;
EN:IN STD_LOGIC;
DATAIN:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
CARRY_OUT:OUT STD_LOGIC
);
END COMPONENT cnt6;
SIGNAL CLK0:STD_LOGIC;
SIGNAL S0:STD_LOGIC;
SIGNAL S1:STD_LOGIC;
SIGNAL S2:STD_LOGIC;
SIGNAL S3:STD_LOGIC;
BEGIN
--元件例化
CLK0 <= NOT CLK;
U1:cnt10 PORT MAP(CLK0,LOAD,CLR,COOK,DATA(3 DOWNTO 0),SEC0,S0);
U2:cnt6 PORT MAP(S0,LOAD,CLR,COOK,DATA(7 DOWNTO 4),SEC1,S1);
U3:cnt10 PORT MAP(S1,LOAD,CLR,COOK,DATA(11 DOWNTO 8),MIN0,S2);
U4:cnt6 PORT MAP(S2,LOAD,CLR,COOK,DATA(15 DOWNTO 12),MIN1,S3);
DONE<=S0 AND S1 AND S2 AND S3;
END rtl;
--------------------------------------------------------------------------------------------------
--顶层模块的VHDL实现如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY top IS
PORT(
KEY: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --输入4位16进制
RESET:IN STD_LOGIC; --复位键
SET_T:IN STD_LOGIC; --设置时间
START:IN STD_LOGIC; --开始计时
TEST:IN STD_LOGIC; --测试模式
CLK :IN STD_LOGIC; --输入脉冲
COOK:OUT STD_LOGIC; --烹调状态
LED2:OUT STD_LOGIC_VECTOR(1 DOWNTO 0); --LED显示状态
SEC0:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
SEC1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
MIN0:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
MIN1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END top;
ARCHITECTURE rtl OF top IS
--定义状态控制电路模块
COMPONENT controllor IS
PORT(
RESET:IN STD_LOGIC;
KEY: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
SET_T:IN STD_LOGIC;
START:IN STD_LOGIC;
TEST:IN STD_LOGIC;
CLK :IN STD_LOGIC;
DONE:IN STD_LOGIC;
COOK:OUT STD_LOGIC;
LD_TEST:OUT STD_LOGIC;
LD_CLK:OUT STD_LOGIC;
DATA:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
LED_SET_T:OUT STD_LOGIC;
LD_DONE:OUT STD_LOGIC
);
END COMPONENT controllor;
--定义数据装载电路模块
COMPONENT loader IS
PORT(
DATAIN:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
LD_TEST:IN STD_LOGIC;
LD_CLK:IN STD_LOGIC;
LD_DONE:IN STD_LOGIC;
DATAOUT:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
LOAD:OUT STD_LOGIC);
END COMPONENT loader;
--定义计时电路模块
COMPONENT counter IS
PORT(
COOK:IN STD_LOGIC;
LOAD,CLR:STD_LOGIC;
CLK:IN STD_LOGIC;
DATA:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
SEC0:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
SEC1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
MIN0:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
MIN1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
DONE:OUT STD_LOGIC
);
END COMPONENT counter;
SIGNAL COOK_TMP:STD_LOGIC;
SIGNAL TEST_TMP:STD_LOGIC;
SIGNAL CLK_TMP:STD_LOGIC;
SIGNAL DONE_TMP:STD_LOGIC;
SIGNAL LOAD_TMP:STD_LOGIC;
SIGNAL DONE:STD_LOGIC;
SIGNAL DATA_TMP,DATA_TMP1:STD_LOGIC_VECTOR(15 DOWNTO 0);
BEGIN
COOK<=COOK_TMP;
LED2(0)<=COOK_TMP;
--电路模块例化
U1:controllor PORT MAP(RESET,KEY,SET_T,START,TEST,CLK,DONE,COOK_TMP,
TEST_TMP,CLK_TMP,DATA_TMP1,LED2(1),DONE_TMP);
U2:loader PORT MAP(DATA_TMP1,TEST_TMP,CLK_TMP,DONE_TMP,DATA_TMP,
LOAD_TMP);
U3:counter PORT MAP(COOK_TMP,LOAD_TMP,RESET,CLK,DATA_TMP,SEC0,SEC1,MIN0,
MIN1,DONE);
END rtl;