文件名称:微波炉控制器的FPGA实现
文件大小:876KB
文件格式:DOC
更新时间:2016-01-17 08:33:44
FPGA
状态控制电路的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;