设计一个10层楼的电梯控制器模块,要求:(1)时间先后优先级;(2)位置先后优先级。
电梯运行规则:
当电梯处在上升模式时,只响应比电梯所在位置高的上楼请求,由下向上逐个执行,直到最后一个上楼请求执行完毕。如果高层有下楼请求,直接升到有下楼请求的最高楼层,然后进入下降模式。下降模式类似。
定义每层楼的状态,可扩展至任意楼层。
FLOOR(IN):XXXXXXXXXX(10~1楼;1有效,0无效)
POSITION(OUT):XXXX(当前楼层)
UP_DOWN:X(0上升模式,1下降模式)
Design Block:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ELEVATOR IS
PORT(CLK,RST:IN STD_LOGIC;
FLOOR:IN STD_LOGIC_VECTOR(10 DOWNTO 1);
POSITION:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END ELEVATOR;
ARCHITECTURE BEHAV OF ELEVATOR IS
TYPE STATES IS (S0,S1,S2,S3,S4,S5,S6,S7,S8);
ATTRIBUTE ENUM_ENCODING:STRING;
ATTRIBUTE ENUM_ENCODING OF STATES:TYPE IS "gray";
SIGNAL C_ST,N_ST:STATES:=S0;
SIGNAL UP_DOWN,UD:STD_LOGIC:='0'; --0上升,1下降
BEGIN
COM:PROCESS(C_ST,FlOOR,UP_DOWN,RST)
VARIABLE P:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF RST='1' THEN P:="0001";
END IF;
CASE C_ST IS
WHEN S0 =>
IF FLOOR="0000000000" THEN N_ST<=S0;
ELSIF UP_DOWN='0' THEN
IF P="0001" THEN
IF (FLOOR(2) OR FLOOR(3) OR FLOOR(4) OR FLOOR(5) OR FLOOR(6)
OR FLOOR(7) OR FLOOR(8) OR FLOOR(9) OR FLOOR(10))='0' THEN UD<='1';
END IF;
ELSIF P="0010" THEN
IF (FLOOR(3) OR FLOOR(4) OR FLOOR(5) OR FLOOR(6)
OR FLOOR(7) OR FLOOR(8) OR FLOOR(9) OR FLOOR(10))='0' THEN UD<='1';
END IF;
ELSIF P="0011" THEN
IF (FLOOR(4) OR FLOOR(5) OR FLOOR(6)
OR FLOOR(7) OR FLOOR(8) OR FLOOR(9) OR FLOOR(10))='0' THEN UD<='1';
END IF;
ELSIF P="0100" THEN
IF (FLOOR(5) OR FLOOR(6)
OR FLOOR(7) OR FLOOR(8) OR FLOOR(9) OR FLOOR(10))='0' THEN UD<='1';
END IF;
ELSIF P="0101" THEN
IF (FLOOR(6) OR FLOOR(7) OR FLOOR(8) OR FLOOR(9) OR FLOOR(10))='0' THEN UD<='1';
END IF;
ELSIF P="0110" THEN
IF (FLOOR(7) OR FLOOR(8) OR FLOOR(9) OR FLOOR(10))='0' THEN UD<='1';
END IF;
ELSIF P="0111" THEN
IF (FLOOR(8) OR FLOOR(9) OR FLOOR(10))='0' THEN UD<='1';
END IF;
ELSIF P="1000" THEN
IF (FLOOR(9) OR FLOOR(10))='0' THEN UD<='1';
END IF;
ELSIF P="1001" THEN
IF FLOOR(10)='0' THEN UD<='1';
END IF;
ELSIF P="1010" THEN UD<='1';
END IF;
N_ST<=S3;
ELSIF UP_DOWN='1' THEN
IF P="1010" THEN
IF (FLOOR(9) OR FLOOR(8) OR FLOOR(7) OR FLOOR(6) OR FLOOR(5)
OR FLOOR(4) OR FLOOR(3) OR FLOOR(2) OR FLOOR(1))='0' THEN UD<='0';
END IF;
ELSIF P="1001" THEN
IF (FLOOR(8) OR FLOOR(7) OR FLOOR(6) OR FLOOR(5)
OR FLOOR(4) OR FLOOR(3) OR FLOOR(2) OR FLOOR(1))='0' THEN UD<='0';
END IF;
ELSIF P="1000" THEN
IF (FLOOR(7) OR FLOOR(6) OR FLOOR(5)
OR FLOOR(4) OR FLOOR(3) OR FLOOR(2) OR FLOOR(1))='0' THEN UD<='0';
END IF;
ELSIF P="0111" THEN
IF (FLOOR(6) OR FLOOR(5)
OR FLOOR(4) OR FLOOR(3) OR FLOOR(2) OR FLOOR(1))='0' THEN UD<='0';
END IF;
ELSIF P="0110" THEN
IF (FLOOR(5) OR FLOOR(4) OR FLOOR(3) OR FLOOR(2) OR FLOOR(1))='0' THEN UD<='0';
END IF;
ELSIF P="0101" THEN
IF (FLOOR(4) OR FLOOR(3) OR FLOOR(2) OR FLOOR(1))='0' THEN UD<='0';
END IF;
ELSIF P="0100" THEN
IF (FLOOR(3) OR FLOOR(2) OR FLOOR(1))='0' THEN UD<='0';
END IF;
ELSIF P="0011" THEN
IF (FLOOR(2) OR FLOOR(1))='0' THEN UD<='0';
END IF;
ELSIF P="0010" THEN
IF FLOOR(1)='0' THEN UD<='0';
END IF;
ELSIF P="0001" THEN UD<='0';
END IF;
N_ST<=S3;
END IF;
POSITION<=P;
WHEN S1 =>
IF FLOOR="0000000000" THEN N_ST<=S0;
ELSE
P:=P+1;
IF FLOOR(CONV_INTEGER(P))='1' THEN N_ST<=S0;
ELSE N_ST<=S7;
END IF;
END IF;
WHEN S2 =>
IF FLOOR="0000000000" THEN N_ST<=S0;
ELSE
P:=P-1;
IF FLOOR(CONV_INTEGER(P))='1' THEN N_ST<=S0;
ELSE N_ST<=S8;
END IF;
END IF;
WHEN S3 => N_ST<=S4;
WHEN S4 => N_ST<=S5;
WHEN S5 => N_ST<=S6;
WHEN S6 =>
IF UP_DOWN='0' THEN N_ST<=S1;
ELSIF UP_DOWN='1' THEN N_ST<=S2;
END IF;
WHEN S7 => N_ST<=S1;
WHEN S8 => N_ST<=S2;
END CASE;
END PROCESS COM;
REG:PROCESS(CLK,UD,RST)
BEGIN
IF RST='1' THEN C_ST<=S0;
ELSIF CLK'EVENT AND CLK='1' THEN UP_DOWN<=UD;C_ST<=N_ST;
END IF;
END PROCESS REG;
END BEHAV;
Test Bench:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ELEVATOR_vhd_tst IS
END ELEVATOR_vhd_tst;
ARCHITECTURE ELEVATOR_arch OF ELEVATOR_vhd_tst IS
SIGNAL CLK1,RST1 : STD_LOGIC;
SIGNAL FLOOR1 : STD_LOGIC_VECTOR(10 DOWNTO 1);
SIGNAL POSITION1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
CONSTANT CLK_P:TIME:=1 us;
COMPONENT ELEVATOR
PORT(CLK,RST:IN STD_LOGIC;
FLOOR:IN STD_LOGIC_VECTOR(10 DOWNTO 1);
POSITION:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
BEGIN
i1 : ELEVATOR PORT MAP(CLK => CLK1, RST => RST1, FLOOR => FLOOR1, POSITION => POSITION1);
PROCESS
BEGIN
CLK1<='0'; WAIT FOR CLK_P;
CLK1<='1'; WAIT FOR CLK_P;
END PROCESS;
RST1<='1','0' AFTER 2 us;
FLOOR1<="1010000110","0000000000" AFTER 72 us,"0010000011" AFTER 90 us,"0000000000" AFTER 152 us;
END ELEVATOR_arch;
仿真波形图: