====== LAB 7: A State Machine for the Display ====== ===== Synopsis ===== In order to control the 7-segment display a simple state machine is necessary. In addition to the buttons for the desired exposure time another special button is present on the camera panel that allows the user to switch between the current exposure time and the number of pictures that have already been taken. If one of the exposure time buttons is pressed the display will have to show the corresponding exposure time immediately. Otherwise, the display should toggle between exposure time and number of pictures whenever the SWITCH button is pressed. The figure below shows the module interface: {{:vhdl_workshop:workshop_displaycontroller.svg?nolink&450|The display controller module}} ==== Behaviour ==== Valid selections of a new exposure time are signaled by KEY values other than (0, 0, 0). Illegal combinations are filtered out by the keypad decoder module. Thus, SHOW_TIME has to be set to ’1’ if KEY is not equal (0,0,0). The SWITCH signal can not be used directly to toggle the display as the button will be pressed down for much longer than the clock period. If the signal level is used for the decision, the display will flicker as it switches between picture count and exposure time every 100 microseconds. Therefore, a register is needed that stores the last value of the SWITCH signal. The button has just been pressed when the SWITCH signal is ’1’ and has been ’0’ during the last clock cycle. Then the SHOW_TIME signal is inverted. Due to the fact that signals declared as out can not be read by processes within the entity, an additional display state signal is also needed. ==== Data types ==== All control signals shall be of type **std_ulogic**, as usual. Thus, only the KEY signal has a different data type, namely **T_DIGITS** from the P_DISPLAY package. ==== To do ==== * Write a new file with the VHDL description of the exposure latch. * Write the corresponding testbench. * Compile and simulate the design. * Synthesize the module. ===== Implementation ===== library ieee; use ieee.std_logic_1164.all; use work.P_DISPLAY.all; entity DISP_CTRL is -- system signals: CLK, RESET -- control signals: SWITCH, KEY -- output signal: SHOW_TIME end DISP_CTRL; architecture RTL of DISP_CTRL is -- Internal signal for SHOW_TIME output begin -- Output assignment -- Clocked process with asynchronous reset process variable LAST_SWITCH: std_ulogic; begin if (RESET = '1') then -- Reset all registers elsif (CLK'event and CLK = '1') then if KEY /= (0,0,0) then SHOW_STATE <= '1'; else if LAST_SWITCH = '0' and SWITCH = '1' then -- Toggle output signal end if; end if; -- Store the SWITCH value to allow a rising edge detection LAST_SWITCH := SWITCH; end if; -- end of clocked process end process; end RTL; ===== Testbench ===== library ieee; use std.textio.all; use ieee.std_logic_1164.all; use work.P_DISPLAY.all; entity TB_DISP_CTRL is end TB_DISP_CTRL; architecture TEST of TB_DISP_CTRL is component DISP_CTRL port(CLK : in std_ulogic; RESET : in std_ulogic; SWITCH : in std_ulogic; KEY : in T_DIGITS; SHOW_TIME : out std_ulogic); end component; signal W_CLK : std_ulogic := '0'; signal W_RESET : std_ulogic; signal W_SWITCH : std_ulogic; signal W_KEY : T_DIGITS; signal W_SHOW_TIME : std_ulogic; begin DUT : DISP_CTRL port map( CLK => W_CLK, RESET => W_RESET, SWITCH => W_SWITCH, KEY => W_KEY, SHOW_TIME => W_SHOW_TIME); W_CLK <= not W_CLK after 10 ns; STIMULI : process begin W_KEY <= (0,0,0); W_SWITCH <= '0'; W_RESET <= '1'; -- SHOW_TIME = '0' wait for 5 ns; W_KEY <= (1,0,0); -- no changes wait for 20 ns; W_SWITCH <= '1'; -- no changes wait for 20 ns; W_SWITCH <= '0'; -- no changes wait for 20 ns; W_RESET <= '0'; -- SHOW_TIME = '1' wait for 60 ns; W_SWITCH <= '1'; -- no changes wait for 20 ns; W_SWITCH <= '0'; -- no changes wait for 20 ns; W_KEY <= (0,0,0); -- no changes wait for 20 ns; W_SWITCH <= '1'; -- SHOW_TIME = '0' wait for 60 ns; W_SWITCH <= '0'; -- no changes wait for 20 ns; W_SWITCH <= '1'; -- SHOW_TIME = '1' wait for 20 ns; W_SWITCH <= '0'; -- no changes wait for 20 ns; assert false report "End of stimuli reached" severity failure; end process STIMULI; SAMPLE : process(W_SHOW_TIME) constant SPACE : string := " "; variable FILE_LINE : line; FILE OUT_FILE : text IS OUT "lab_7.trace"; begin write(FILE_LINE, to_bit(W_SHOW_TIME)); writeline(OUT_FILE, FILE_LINE); end process SAMPLE; end TEST; configuration CFG_TB_DISP_CTRL of TB_DISP_CTRL is for TEST end for; end CFG_TB_DISP_CTRL; ===== Package ===== {{page>.:package}}