--********************************************************** -- Game Pal development Team -- -- Top level chip controller -- Revision 0.1 -- 1998/03/06 --********************************************************** LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_arith.all; use IEEE.STD_LOGIC_UNSIGNED.all; ENTITY GAMEPAL IS -- total inputs and outputs of system port( clock :IN STD_LOGIC; -- The LED Display Signals signal LSB_a, LSB_b, LSB_c, LSB_d, LSB_e, LSB_f, LSB_g, LSB_dp, MSB_a, MSB_b, MSB_c, MSB_d, MSB_e, MSB_f, MSB_g, MSB_dp : out std_logic; -- Keyboard Input and OutPut signal pinA, pinB, pinG, pinH : OUT STD_LOGIC; -- output pins on keypad signal pinC, pinD, pinE, pinF: IN STD_LOGIC; -- input pins on keypad -- The Video Display Signals signal Red,Green,Blue : out std_logic; signal Horiz_sync,Vert_sync : out std_logic; signal Flex_Switch_1, Flex_Switch_2, Flex_Switch_3, Flex_Switch_4: in std_logic; signal Flex_Switch_5, Flex_Switch_6, Flex_Switch_7, Flex_Switch_8: in std_logic); END GAMEPAL; ARCHITECTURE mixed OF GAMEPAL IS -- Video Data BUS signal Dice_VectorA : std_logic_vector(17 downto 0); signal Dice_VectorB : std_logic_vector(17 downto 0); signal Timer_Vector : std_logic_vector(17 downto 0); -- signal NUM_LSB, NUM_MSB: std_logic_vector(3 downto 0); -- keypad signals SIGNAL reset, key1, key2, key3, key4, key5, key6, key7, key8, key9, key_enter, key_roll : STD_LOGIC; SIGNAL n_reset, n_key1, n_key2, n_key3, n_key4, n_key5, n_key6, n_key7, n_key8, n_key9, n_key_enter, n_key_roll : STD_LOGIC; -- dice signals SIGNAL dice1, dice2, dice3, dice4, dice5, dice6 :INTEGER RANGE 0 to 6; -- timer signals SIGNAL sec1_out1, sec1_out3, sec1_out5 : INTEGER RANGE 0 to 6; SIGNAL min_out1, min_out3, min_out5 : INTEGER RANGE 0 to 6; SIGNAL sec2_out1, sec2_out3, sec2_out5 : INTEGER RANGE 0 to 9; SIGNAL enable: STD_LOGIC; -- display signals SIGNAL Current_Function: STD_LOGIC_VECTOR (1 DOWNTO 0);-- 2 bit vector to tell the output -- which screen to display SIGNAL upd_ok: bit; -- handshaking -- state signals TYPE state_type IS (reset_state,main,dice_enable1, dice_enable, one_mintime, one_mintime_enable, three_mintime, three_mintime_enable, five_mintime, five_mintime_enable); -- state machine states SIGNAL state : state_type; --current state the circuit is in SIGNAL next_state : state_type; --next state circuit will go to (on next clock rising edge) -- other signals SIGNAL intermediate: STD_LOGIC_VECTOR(1 DOWNTO 0); SIGNAL time_clock : STD_LOGIC; SIGNAL master_reset : STD_LOGIC; -- Below are the components of the project -- dice roller COMPONENT dice IS port( clock : IN STD_LOGIC; --system clock reset, key1, key2, key3, key4, key5, key6, key7, key8, key9, key_enter, key_roll : IN STD_LOGIC; -- possible keypresses dice1, dice2, dice3, dice4, dice5, dice6 : OUT INTEGER RANGE 0 to 6 ); END COMPONENT dice; COMPONENT video IS port( signal Clock : in std_logic; signal LSB_a, LSB_b, LSB_c, LSB_d, LSB_e, LSB_f, LSB_g, LSB_dp, MSB_a, MSB_b, MSB_c, MSB_d, MSB_e, MSB_f, MSB_g, MSB_dp : out std_logic; signal Red,Green,Blue : out std_logic; signal Horiz_sync,Vert_sync : out std_logic; signal Flex_Switch_1, Flex_Switch_2, Flex_Switch_3, Flex_Switch_4: in std_logic; signal Flex_Switch_5, Flex_Switch_6, Flex_Switch_7, Flex_Switch_8: in std_logic; signal Current_Function: in std_logic_vector(1 downto 0); signal Dice_VectorA : in std_logic_vector(17 downto 0); signal Dice_VectorB : in std_logic_vector(17 downto 0); signal Timer_Vector : in std_logic_vector(17 downto 0) ); END COMPONENT video; --countdown timer COMPONENT mintime IS port( reset : IN STD_LOGIC; enable : IN STD_LOGIC; clk : IN STD_LOGIC; min_out1, sec2_out1 : OUT INTEGER RANGE 0 to 9; --output the minutes and seconds (2 digits for seconds) sec1_out1 : OUT INTEGER RANGE 0 to 5 ); END COMPONENT mintime; COMPONENT min3time IS port( reset : IN STD_LOGIC; enable : IN STD_LOGIC; clk : IN STD_LOGIC; min_out3, sec2_out3 : OUT INTEGER RANGE 0 to 9; --output the minutes and seconds (2 digits for seconds) sec1_out3 : OUT INTEGER RANGE 0 to 5 ); END COMPONENT min3time; COMPONENT min5time IS port( reset : IN STD_LOGIC; enable : IN STD_LOGIC; clk : IN STD_LOGIC; min_out5, sec2_out5 : OUT INTEGER RANGE 0 to 9; --output the minutes and seconds (2 digits for seconds) sec1_out5 : OUT INTEGER RANGE 0 to 5 ); END COMPONENT min5time; --display This code will have to change, but I left it in to keep the compiler happy COMPONENT keypad IS PORT( clock : IN STD_LOGIC; --system clock reset : OUT STD_LOGIC; --system reset (key from keypad to reset rest of system) key1, key2, key3, key4, key5, key6, key7, key8, key9, key_enter, key_roll : OUT STD_LOGIC; -- keys on the keypad pinA, pinB, pinG, pinH : OUT STD_LOGIC; -- output pins on keypad pinC, pinD, pinE, pinF: IN STD_LOGIC -- input pins on keypad ); END COMPONENT keypad; BEGIN Key_Conversion : Process BEGIN key1 <= NOT n_Key1; key2 <= NOT n_Key2; key3 <= NOT n_Key3; key4 <= NOT n_Key4; key5 <= NOT n_Key5; key6 <= NOT n_Key6; key7 <= NOT n_Key7; key8 <= NOT n_Key8; key9 <= NOT n_Key9; reset <= NOT n_reset; key_enter <= n_key_enter; key_roll <= n_key_roll; END PROCESS Key_Conversion; state_machine : process --(clock) BEGIN CASE state IS WHEN reset_state => -- when reset is pressed this state will be entered next_state <= main; -- unconditionally moves to next state enable <= '0'; WHEN main => enable <= '0'; -- disables counters Current_Function <= "00"; IF key1 = '1' THEN -- if key1 is pressed next_state <= dice_enable1; -- advance to next state(dice_enable1) ELSIF key2 = '1' THEN -- if key2 is pressed next_state <= one_mintime; -- advance to next state(one_mintime) ELSIF key3 = '1' THEN -- if key3 is pressed next_state <= three_mintime; -- advance to next state(one_mintime) ELSIF key4 = '1' THEN -- if key4 is pressed next_state <= five_mintime; -- advance to next state(one_mintime) ELSE next_state <= main; END IF; WHEN dice_enable1 => enable <= '0'; -- disables counters Current_Function <= "01"; IF key1 = '0' THEN -- if key1 is released next_state <= dice_enable; -- advance to next state(dice_enable) ELSE next_state <= dice_enable1; END IF; WHEN dice_enable => enable <= '0'; -- disables counters -- one minute timer WHEN one_mintime => enable <= '0'; -- disables counters Current_Function <= "10"; IF key2 = '0' THEN -- if key0 is released next_state <= one_mintime_enable; -- advance to next state(one_mintime_enable) ELSE next_state <= one_mintime; END IF; WHEN one_mintime_enable => enable <= '1'; -- three minute timer WHEN three_mintime => enable <= '0'; -- disables counters Current_Function <= "10"; IF key3 = '0' THEN -- if key0 is released next_state <= three_mintime_enable; -- advance to next state(one_mintime_enable) ELSE next_state <= three_mintime; END IF; WHEN three_mintime_enable => enable <= '1'; -- five minute timer WHEN five_mintime => enable <= '0'; -- disables counters Current_Function <= "10"; IF key4 = '0' THEN -- if key0 is released next_state <= five_mintime_enable; -- advance to next state(one_mintime_enable) ELSE next_state <= five_mintime; END IF; WHEN five_mintime_enable => enable <= '1'; WHEN OTHERS => enable <= '0'; -- disables counters next_state <= reset_state;-- if an unknown state is encountered, go to reset state END CASE; END PROCESS state_machine; -- ***************** total_reset : PROCESS BEGIN IF reset = '1' THEN master_reset <= '1'; ELSE master_reset <= '0'; END IF; END PROCESS total_reset; -- ******************* state_register : PROCESS (clock)-- advances the state machine on the clock pulse BEGIN IF reset = '1' THEN -- asynch reset input synchronously resets state machine at next clock pulse state <= reset_state; ELSIF rising_edge(clock) THEN -- rising edge of clock triggers transition to next state of state machine state <= next_state; END IF; END PROCESS state_register; -- ***************** KeyBoardInput:keypad PORT MAP( Clock => Clock, reset => n_reset, key1 => n_key1, key2 => n_key2, key3 => n_key3, key4 => n_key4, key5 => n_key5, key6 => n_key6, key7 => n_key7, key8 => n_key8, key9 => n_key9, key_enter => n_key_enter, key_roll => n_key_roll, pinA => pinA, pinB => pinB, pinG => pinG, pinH => pinH, pinC => pinC, pinD => pinD, pinE => pinE, pinF => pinF); dice_roller:dice PORT MAP ( clock => clock, reset => master_reset, key1 => key1, key2 => key2, key3 => key3, key4 => key4, key5 => key5, key6 => key6, key7 =>key7, key8 => key8, key9 => key9, key_enter => key_enter, key_roll => key_roll, dice1 => dice1, dice2 => dice2, dice3 => dice3, dice4 => dice4, dice5 => dice5, dice6 => dice6 ); countdown_timer1: mintime PORT MAP( reset => master_reset, enable => enable, clk => time_clock, min_out1 => min_out1, sec2_out1 => sec2_out1, sec1_out1 => sec1_out1 ); countdown_timer3: min3time PORT MAP( reset => master_reset, enable => enable, clk => time_clock, min_out3 => min_out3, sec2_out3 => sec2_out3, sec1_out3 => sec1_out3 ); countdown_timer5: min5time PORT MAP( reset => master_reset, enable => enable, clk => time_clock, min_out5 => min_out5, sec2_out5 => sec2_out5, sec1_out5 => sec1_out5 ); display:video PORT MAP ( Clock => Clock, LSB_a => LSB_a, LSB_b => LSB_b, LSB_c => LSB_c, LSB_d => LSB_d, LSB_e => LSB_e, LSB_f => LSB_f, LSB_g => LSB_g, LSB_dp => LSB_dp, MSB_a => MSB_a, MSB_b => MSB_b, MSB_c => MSB_c, MSB_d => MSB_d, MSB_e => MSB_e, MSB_f => MSB_f, MSB_g => MSB_g, MSB_dp => MSB_dp, Red => Red, Green => Green, Blue => Blue, Horiz_sync => Horiz_sync, Vert_sync => Vert_sync, Flex_Switch_1 => Flex_Switch_1, Flex_Switch_2 => Flex_Switch_2, Flex_Switch_3 => Flex_Switch_3, Flex_Switch_4 => Flex_Switch_4, Flex_Switch_5 => Flex_Switch_5, Flex_Switch_6 => Flex_Switch_6, Flex_Switch_7 => Flex_Switch_7, Flex_Switch_8 => Flex_Switch_8, Current_Function => Current_Function, Dice_VectorA => Dice_VectorA, Dice_VectorB => Dice_VectorB, Timer_Vector => Timer_Vector ); dice_output : PROCESS IS BEGIN Dice_VectorA(17 downto 15) <= O"6"; Dice_VectorA(5 downto 3) <= O"6"; Dice_VectorA(11 downto 9) <= O"6"; Dice_VectorA(14 downto 12) <= CONV_STD_LOGIC_VECTOR(dice3,3); Dice_VectorA(8 downto 6) <= CONV_STD_LOGIC_VECTOR(dice2,3); Dice_VectorA(2 downto 0) <= CONV_STD_LOGIC_VECTOR(dice1,3); Dice_VectorB(17 downto 15) <= O"6"; Dice_VectorB(5 downto 3) <= O"6"; Dice_VectorB(11 downto 9) <= O"6"; Dice_VectorB(14 downto 12) <= CONV_STD_LOGIC_VECTOR(dice6,3); Dice_VectorB(8 downto 6) <= CONV_STD_LOGIC_VECTOR(dice5,3); Dice_VectorB(2 downto 0) <= CONV_STD_LOGIC_VECTOR(dice4,3); END PROCESS dice_output; counter_output : PROCESS IS BEGIN CASE state IS WHEN one_mintime_enable => Timer_Vector(17 downto 15) <= O"6"; Timer_Vector(14 downto 12) <= CONV_STD_LOGIC_VECTOR(min_out1,3); Timer_Vector(11 downto 9) <= O"6"; Timer_Vector(8 downto 6) <= CONV_STD_LOGIC_VECTOR(sec1_out1,3); CASE sec2_out1 IS WHEN 9 => Timer_Vector(5 downto 3) <= O"7"; Timer_Vector(2 downto 0) <= O"1"; WHEN 8 => Timer_Vector(5 downto 3) <= O"7"; Timer_Vector(2 downto 0) <= O"0"; WHEN OTHERS => Timer_Vector(5 downto 3) <= O"6"; Timer_Vector(2 downto 0) <= CONV_STD_LOGIC_VECTOR(sec2_out1,3); END CASE; WHEN three_mintime_enable => Timer_Vector(17 downto 15) <= O"6"; Timer_Vector(14 downto 12) <= CONV_STD_LOGIC_VECTOR(min_out3,3); Timer_Vector(11 downto 9) <= O"6"; Timer_Vector(8 downto 6) <= CONV_STD_LOGIC_VECTOR(sec1_out3,3); CASE sec2_out3 IS WHEN 9 => Timer_Vector(5 downto 3) <= O"7"; Timer_Vector(2 downto 0) <= O"1"; WHEN 8 => Timer_Vector(5 downto 3) <= O"7"; Timer_Vector(2 downto 0) <= O"0"; WHEN OTHERS => Timer_Vector(5 downto 3) <= O"6"; Timer_Vector(2 downto 0) <= CONV_STD_LOGIC_VECTOR(sec2_out3,3); END CASE; WHEN five_mintime_enable => Timer_Vector(17 downto 15) <= O"6"; Timer_Vector(14 downto 12) <= CONV_STD_LOGIC_VECTOR(min_out5,3); Timer_Vector(11 downto 9) <= O"6"; Timer_Vector(8 downto 6) <= CONV_STD_LOGIC_VECTOR(sec1_out5,3); CASE sec2_out5 IS WHEN 9 => Timer_Vector(5 downto 3) <= O"7"; Timer_Vector(2 downto 0) <= O"1"; WHEN 8 => Timer_Vector(5 downto 3) <= O"7"; Timer_Vector(2 downto 0) <= O"0"; WHEN OTHERS => Timer_Vector(5 downto 3) <= O"6"; Timer_Vector(2 downto 0) <= CONV_STD_LOGIC_VECTOR(sec2_out5,3); END CASE; WHEN OTHERS => END CASE; END PROCESS counter_output; -- 1 second clock period required for countdown timer -- calculated for a clock frequency of 25.175 MHz -- stepdown = clock frequency /2 clock_divider: PROCESS (clock) IS CONSTANT stepdown: integer := 943000; --0; --to give a 1 second clock TYPE stepdown_type IS RANGE 0 TO stepdown; VARIABLE c :stepdown_type; BEGIN WAIT UNTIL RISING_EDGE(clock); IF reset = '1' THEN c:= 0; time_clock <= '0'; ELSE c:= c + 1; IF c = 0 THEN time_clock <= NOT time_clock; END IF; END IF; END PROCESS clock_divider; eight_seg: PROCESS IS -- gives 8 segment display output for keypresses BEGIN -- IF NOT( (reset= '1') OR (key_enter = '1') OR (key_roll = '1') ) THEN -- LSB_a <= '0'; -- LSB_b <= '0'; -- LSB_c <= '0'; -- LSB_d <= '0'; -- LSB_e <= '0'; -- LSB_f <= '0'; -- LSB_g <= '0'; -- LSB_dp <= '0'; -- END IF; -- IF key1 = '0' THEN -- NUM_LSB <= "1000"; -- NUM_MSB <= "1111"; -- ELSIF key2 = '0' THEN -- NUM_LSB <= "1001"; -- NUM_MSB <= "1111"; -- ELSIF key3 = '0'THEN -- NUM_LSB <= "0000"; -- NUM_MSB <= "1111"; -- ELSIF key4 = '0' THEN -- NUM_LSB <= "0000"; -- NUM_MSB <= "1111"; -- ELSIF key5 = '0'THEN -- NUM_LSB <= "0000"; -- NUM_MSB <= "1111"; -- ELSIF key6 = '0'THEN -- NUM_LSB <= "0000"; -- NUM_MSB <= "1111"; -- ELSIF key7 = '0'THEN -- NUM_LSB <= "0000"; -- NUM_MSB <= "1111"; -- ELSIF key8 = '0' THEN -- NUM_LSB <= "0000"; -- NUM_MSB <= "1111"; -- ELSIF key9 = '0' THEN -- NUM_LSB <= "0000"; -- NUM_MSB <= "1111"; -- ELSIF reset = '0' THEN -- NUM_LSB <= "1111"; -- NUM_MSB <= "1111"; -- ELSIF key_enter = '0' THEN -- NUM_LSB <= "0001"; -- NUM_MSB <= "0001"; -- ELSIF key_roll = '0' THEN -- NUM_LSB <= "0010"; -- NUM_MSB <= "0010"; -- ELSE -- NUM_LSB <= "0001"; -- NUM_MSB <= "0011"; -- END IF; END PROCESS eight_seg; END mixed;