-- Erster Teil: Vervollstaendigen des Codes der FSM SECTIMER: PROCESS(clk,reset) VARIABLE timer_msb_to_zero : STD_LOGIC_VECTOR(timer'RANGE); BEGIN IF reset='1' THEN timer <= (OTHERS => '0'); ELSIF clk'EVENT AND clk='1' THEN timer_msb_to_zero := timer; -- set msb to zero, the msb will be our overflow bit timer_msb_to_zero(timer'LENGTH-1) := '0'; timer <= timer_msb_to_zero + 1; END IF; END PROCESS SECTIMER; sectrigger <= timer(timer'LENGTH-1); FSM: PROCESS (clk,reset,current_state,secs,mins,hours,wmins,whours, S) VARIABLE next_state: state_type; BEGIN IF reset = '1' THEN hours <= 0; mins <= 0; secs <= 0; whours <= 0; wmins <= 0; alarm <= '0'; current_state <= ntime; ELSIF (clk'event AND clk='1') THEN IF (NOT (current_state = set_time) AND (sectrigger='1')) THEN -- Zähle Uhr hoch IF secs = 59 THEN secs <= 0; IF mins = 59 THEN mins <= 0; IF hours = 23 THEN hours <= 0; ELSE hours <= hours+1; END IF; ELSE mins <= mins+1; END IF; ELSE secs <= secs+1; END IF; END IF; CASE current_state IS WHEN ntime => -- prüfe, ob Alarm ausgelöst wird -- setze nächsten Zustand -- Zustand Set_time -- setze Minute und Stunde mit S(3) bzw. S(4) -- setze nächsten Zustand -- Zustand set_alarm -- setze nächsten Zustand ........; END PROCESS FSM; -- Zweiter Teil: Verschieben des Codes der Prozesse in die architecture, -- Vervollstaendigung der PORTMAP LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY controller IS PORT ( S: IN STD_LOGIC_VECTOR (1 TO 5); DISPLAY0, DISPLAY1, DISPLAY2, DISPLAY3: OUT INTEGER RANGE 0 TO 9 ; alarm: OUT STD_LOGIC; clk: IN STD_LOGIC; reset: IN STD_LOGIC ); END controller; ARCHITECTURE Behavioral OF controller IS COMPONENT Display60 IS PORT ( number : IN INTEGER RANGE 0 to 59; position1, position0: OUT INTEGER RANGE 0 to 9); END COMPONENT; COMPONENT Display24 IS PORT ( number : IN INTEGER RANGE 0 TO 23; position1, position0: OUT INTEGER RANGE 0 TO 9); END COMPONENT; SIGNAL timer: STD_LOGIC_VECTOR (13 DOWNTO 0); SIGNAL sectrigger : STD_LOGIC; -- '1' für einen Takt wenn eine Sekunde -- vergangen ist, sonst '0' SIGNAL DISPLAY10, DISPLAY11, DISPLAY20, DISPLAY21: INTEGER RANGE 0 TO 9 ; SIGNAL DISPLAY30, DISPLAY31, DISPLAY40, DISPLAY41: INTEGER RANGE 0 TO 9 ; SIGNAL hours, whours: INTEGER RANGE 0 TO 23; SIGNAL secs, mins, wmins: INTEGER RANGE 0 TO 59; TYPE state_type IS (ntime, set_time, set_alarm); SIGNAL current_state: state_type; BEGIN -- Hier kommt der Code eines Sekunden-Triggers ........; -- Hier kommt der Code auf der FSM. ........; -- MINUTENANZEIGE (ZEIT) MIN_CONVERT: Display60 PORT MAP (number => ........, position1 => DISPLAY11, position0 => DISPLAY10); -- STUNDENANZEIGE (ZEIT) HR_CONVERT: Display24 PORT MAP (number => ........, position1 => DISPLAY21, position0 => DISPLAY20); -- MINUTENANZEIGE (WECKZEIT) WMIN_CONVERT: Display60 PORT MAP (number => ........, position1 => DISPLAY31, position0 => DISPLAY30); -- STUNDENANZEIGE (WECKZEIT) WHR_CONVERT: Display24 PORT MAP (number => ........, position1 => DISPLAY41, position0 => DISPLAY40); -- Beschreibung, wie die DISPLAY-Variablen gesetzt werden Switch_Display: PROCESS (current_state, DISPLAY10, DISPLAY11, DISPLAY20, DISPLAY21, DISPLAY30, DISPLAY31, DISPLAY40, DISPLAY41 ) IS BEGIN IF current_state /= set_alarm THEN DISPLAY0 <= DISPLAY10 ; DISPLAY1 <= DISPLAY11; DISPLAY2 <= DISPLAY20 ; DISPLAY3 <= DISPLAY21 ; ELSE DISPLAY0 <= DISPLAY30; DISPLAY1 <= DISPLAY31; DISPLAY2 <= DISPLAY40; DISPLAY3 <= DISPLAY41; END IF; END PROCESS Switch_Display; END Behavioral;