All pastes #274535 Raw Edit

Mine

public text v1 · immutable
·published 2006-12-10 19:55 UTC
rendered paste body
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity game is
	port (
		clk : in std_logic;
		rst : in std_logic;
		run : in std_logic;
		
		psData : in std_logic;
		psClock : in std_logic;
		
		Red : out std_logic;
		Green : out std_logic;
		Blue : out std_logic;
		vs : out std_logic;
		hs : out std_logic;
		
		LED : out std_logic_vector(7 downto 0)
		
	);
end game;

architecture Behavioral of game is

component raminfr is
	port (
		clk : in std_logic;
		we : in std_logic;
		addr : in integer range 0 to 199;
		saddr : in integer range 0 to 199;
		di : in std_logic_vector(2 downto 0);
		sdo  : out std_logic_vector(2 downto 0)   
	);
end component;

component keyboardVhdl is
	Port (	
		CLK, RST, KD, KC: in std_logic;
		keyboard : out std_logic_vector(2 downto 0)
		);
end component;

component vga_controller is
  Port ( clk       : in  std_logic;
         reset     : in  std_logic;
         hs        : out std_logic;
         vs        : out std_logic;
         blank     : out std_logic;
         hpix      : out std_logic_vector(9 downto 0);
         vpix      : out std_logic_vector(9 downto 0)
			);
end component;

component board is
    Port ( Clk : in std_logic;
			 Blank : in std_logic;
          DrawH : in std_logic_vector(9 downto 0);
          DrawV : in std_logic_vector(9 downto 0);
			 address : out integer range 0 to 199;
			 do : in std_logic_vector(2 downto 0);
			 Red : out std_logic;
          Blue : out std_logic;
          Green : out std_logic;
			 
			 currentPiece0 : in integer range 0 to 199;
			 currentPiece1 : in integer range 0 to 199;
			 currentPiece2 : in integer range 0 to 199;
			 currentPiece3 : in integer range 0 to 199;
			 
			 currentColor : in std_logic_vector(2 downto 0)
			 );
end component;

--Keycodes
constant key_nothing : std_logic_vector(2 downto 0) := "000";
constant key_left : std_logic_vector(2 downto 0) := "001";
constant key_right : std_logic_vector(2 downto 0) := "010";
constant key_down : std_logic_vector(2 downto 0) := "011";

--Not implemented, but maybe it will become so.
--constant key_drop : std_logic_vector(2 downto 0) := "100";


type state_of_anarchy is (reset, adding_new_piece,
waiting, GAME_OVER, move_left_or_right,
 turn_action, --Like.. move the block down and see if it hit anything
 action_done, --Reset counters and go back to waiting state
 plant_0, plant_1, plant_2, plant_3, --Plant the four pieces in PieceLoactions into memory
 line_break, -- Check if they completed any lines and, if so, remove them.
 start_state -- Before "run" is pressed :)
);
signal State, Next_State : state_of_anarchy;

signal resetting : bit;

subtype row is integer range 0 to 19;
subtype boardSize is integer range 0 to 199;
type boardArray is array (natural range <>) of bit;
type boardLocation is array (natural range <>) of boardSize;
type rowArray is array (natural range <>) of row;
signal boardState : boardArray(boardSize);
signal pieceLocations : boardLocation(0 to 3) := (0,0,0,0);
signal next_pieceLocations : boardLocation(0 to 3) := (0,0,0,0);

subtype numPieces is integer range 0 to 27;
subtype pieceRelative is integer range -30 to 30;
subtype color is std_logic_vector(2 downto 0);
type colorArray is array (natural range<>) of color;
type piece is array (0 to 3) of pieceRelative;
type piecesArray is array (natural range <>) of piece;

signal boardStateAddr : integer range 0 to 200; -- 200 = special
signal boardStateInput : bit;

signal currentColor : color;


constant getRow : rowArray (boardSize) := (
	0,0,0,0,0,0,0,0,0,0,
	1,1,1,1,1,1,1,1,1,1,
	2,2,2,2,2,2,2,2,2,2,
	3,3,3,3,3,3,3,3,3,3,
	4,4,4,4,4,4,4,4,4,4,
	5,5,5,5,5,5,5,5,5,5,
	6,6,6,6,6,6,6,6,6,6,
	7,7,7,7,7,7,7,7,7,7,
	8,8,8,8,8,8,8,8,8,8,
	9,9,9,9,9,9,9,9,9,9,
	10,10,10,10,10,10,10,10,10,10,
	11,11,11,11,11,11,11,11,11,11,
	12,12,12,12,12,12,12,12,12,12,
	13,13,13,13,13,13,13,13,13,13,
	14,14,14,14,14,14,14,14,14,14,
	15,15,15,15,15,15,15,15,15,15,
	16,16,16,16,16,16,16,16,16,16,
	17,17,17,17,17,17,17,17,17,17,
	18,18,18,18,18,18,18,18,18,18,
	19,19,19,19,19,19,19,19,19,19
	);

constant pieces : piecesArray (numPieces) := (
	(0,-1,1,10), -- Hat
	(0,-2, -1, 1), -- pipe
	(0, -1, 1, 11), -- "L"
	(0, 1, 10, 11), -- Cube
	(0, 9, -1, 1), -- Reverse "L"
	(0, 10, 1, -9), -- Zig
	(0, 10, -1, -11), -- Zag
	(0,-1,1,10), -- Hat
	(0,-2, -1, 1), -- pipe
	(0, -1, 1, 11), -- "L"
	(0, 1, 10, 11), -- Cube
	(0, 9, -1, 1), -- Reverse "L"
	(0, 10, 1, -9), -- Zig
	(0, 10, -1, -11), -- Zag
	(0,-1,1,10), -- Hat
	(0,-2, -1, 1), -- pipe
	(0, -1, 1, 11), -- "L"
	(0, 1, 10, 11), -- Cube
	(0, 9, -1, 1), -- Reverse "L"
	(0, 10, 1, -9), -- Zig
	(0, 10, -1, -11), -- Zag
	(0,-1,1,10), -- Hat
	(0,-2, -1, 1), -- pipe
	(0, -1, 1, 11), -- "L"
	(0, 1, 10, 11), -- Cube
	(0, 9, -1, 1), -- Reverse "L"
	(0, 10, 1, -9), -- Zig
	(0, 10, -1, -11) -- Zag
	);
	
constant pieceColors : colorArray (numPieces) := (
	('1','0','0'),
	('0','1','0'),
	('0','0','1'),
	('1','1','0'),
	('0','1','1'),
	('1','0','1'),
	('0','0','0'),
	('1','0','0'),
	('0','1','0'),
	('0','0','1'),
	('1','1','0'),
	('0','1','1'),
	('1','0','1'),
	('0','0','0'),
	('1','0','0'),
	('0','1','0'),
	('0','0','1'),
	('1','1','0'),
	('0','1','1'),
	('1','0','1'),
	('0','0','0'),
	('1','0','0'),
	('0','1','0'),
	('0','0','1'),
	('1','1','0'),
	('0','1','1'),
	('1','0','1'),
	('0','0','0')
	);
	
signal nextPiece : numPieces;
signal currentPiece : numPieces;
signal nextCurrentPiece : numPieces;

signal sigAddr : boardSize;
signal cur_sigAddr : boardSize;
signal sigAddr2 : boardSize;
signal sigDi : std_logic_vector(2 downto 0);
signal sigSdo : std_logic_vector(2 downto 0);
signal sigWe : std_logic;

signal sigKeyboard, lastSigKeyboard : std_logic_vector(2 downto 0);
signal sigPsData : std_logic;
signal sigPsClk : std_logic;

signal sigHs : std_logic;
signal sigVs : std_logic;
signal sigBlank : std_logic;
signal sigHpix : std_logic_vector(9 downto 0);
signal sigVpix : std_logic_vector(9 downto 0);

signal sigRed : std_logic;
signal sigGreen : std_logic;
signal sigBlue : std_logic;

signal clockCounter : std_logic_vector(24 downto 0);
constant clock_zero : std_logic_vector(24 downto 0) := "0000000000000000000000000";

begin

bram_unit : raminfr
	Port Map ( 
		clk => clk,
		we => sigWe,
		addr => sigAddr,
		saddr => sigAddr2,
		di => sigDi,
		sdo => sigSdo
	);
	
keyboard_input : keyboardVhdl
	Port Map (
		CLK => clk,
		RST => Rst,
		KD => sigPsData,
		KC => sigPsClk,
		keyboard => sigKeyboard
	);
	
vga_controller_instance : vga_controller 
	Port Map (
		Clk => clk,
      reset => Rst,
      hs => sigHs,
      vs => sigVs,
      blank => sigBlank,
      hpix => sigHpix,
      vpix => sigVpix
	);

board_mapper : board
	Port Map(
		Clk => Clk,
		Blank => sigBlank,
      DrawH => sigHpix,
      DrawV => sigVpix,
		address => sigAddr2,
		do => sigSdo,
		Red => sigRed,
      Blue => sigBlue,
      Green => sigGreen,
		currentPiece0 => pieceLocations(0),
		currentPiece1 => pieceLocations(1),
		currentPiece2 => pieceLocations(2),
		currentPiece3 => pieceLocations(3),
		currentColor => currentColor
	);

currentColor <= pieceColors(currentPiece);

sigPsData <= psData;
sigPsClk <= psClock;

Red <= sigRed;
Blue <= sigBlue;
Green <= sigGreen;
hs <= sigHs;
vs <= sigVs;

set_leds_here : process (State)
begin
	case State is
		when reset =>
			LED <= "10000001";
		when start_state =>
			LED <= "01000000";
		when waiting =>
			LED <= "00100000";
		when GAME_OVER =>
			LED <= "01010101";
		when others =>
			LED <= "11111111";
	end case;
end process;

assign_state : process (Clk, Rst)
begin
	if (Rst = '1') then
		State <= reset;
	elsif (clk'Event and clk = '1') then
		if (State = reset) then
			resetting <= '1';
		else
			resetting <= '0';
		end if;
		State <= Next_State;
	end if;
end process;

asssign_next_piece_Locations : process (Clk)
begin
	if (Clk'Event and clk = '1') then
		pieceLocations <= next_pieceLocations;
	end if;
end process;

random_number_imaginer_and_clock : process (Clk, State, resetting)
begin
	if (State = reset) then
		if (resetting = '0') then
			clockCounter <= clock_zero;
		else
			clockCounter <= clockCounter + 1;
		end if;
		nextPiece <= 0;
	elsif (State = action_done) then
		clockCounter <= clock_zero;
		nextPiece <= nextPiece;
	elsif (clk'event and clk = '1') then
		clockCounter <= clockCounter + 1;
		if (nextPiece = 27) then
			nextPiece <= 0;
		else
			nextPiece <= nextPiece + 1;
		end if;
	end if;
end process;

maintain_sigaddr_blah : process (Clk)
begin
	if (clk'event and clk = '1') then
		cur_sigAddr <= sigAddr;
	end if;
end process;

the_crazyness : process (Clk, boardStateAddr, boardStateInput)
begin
	if (Clk'event and clk = '1') then
		for i in 0 to 199 loop
			if (i = boardStateAddr) then
				boardState(i) <= boardStateInput;
			else
				boardState(i) <= boardState(i);
			end if;
		end loop;
	end if;	
end process;

setnextCurrentPiece : process (Clk, State)
begin
	if (state = reset) then
		currentPiece <= 0;
	elsif (Clk'event and clk = '1') then
		currentPiece <= nextCurrentPiece;
	end if;
end process;

fabsdfhasdfuhasd : process (Clk, SigKeyboard)
begin
	if (clk'event and clk='1') then
		lastSigKeyboard <= sigKeyboard;
		--sigMyKeyCount <= nextsigMyKeyCount;
	end if;
end process;

		
do_awesome_stuff : process (Clk, sigKeyboard, Rst, Run, currentPiece, pieceLocations, State, resetting, cur_sigAddr, nextPiece, clockCounter, lastSigKeyboard)
	variable Shift : pieceRelative;
	variable can_insert : bit;
begin
		sigDi <= "000";
		sigWe <= '0';
		sigAddr <= 0;

		Shift := 0;
		can_insert := '0';
		
		boardStateAddr <= 200;
		boardStateInput <= '0';
		
		nextCurrentPiece <= currentPiece;
		
		next_pieceLocations <= pieceLocations;
		
		--nextsigMyKeyCount <= sigMyKeyCount;
		
		case State is				
			when reset=>
				if (resetting = '0') then --Just started resetting then
					sigAddr <= 0;
				else
					sigAddr <= cur_sigAddr + 1;
				end if;
			
				sigDi <= "111";
				
				--nextsigMyKeyCount <= sigKeyCount;
				
				--sigDi <= clockCounter(2 downto 0);
				sigWe <= '1';
		
				boardStateAddr <= cur_sigAddr;
				boardStateInput <= '0';
						
				next_pieceLocations(0) <= 0;
				next_pieceLocations(1) <= 0; 
				next_pieceLocations(2) <= 0;
				next_pieceLocations(3) <= 0;
				
				if (cur_sigAddr = 198) then
					Next_State <= start_state;
				else
					Next_State <= reset;
				end if;
				
			when start_state =>
				--Clock Counter is COUNTING :D
				if (run = '1') then
					Next_State <= adding_new_piece;
				else
					Next_State <= start_state;
				end if;
			when adding_new_piece =>
				
				Shift := 4; --Insert at middle of top row
				
				-- Step One: Determine if new piece will *fit* on the board.
					--	Remember to update this if any pieces are stored that go 
					-- more than one row up from the insertion point
				if (pieces(nextPiece)(0) < -5) then
					Shift := Shift + 10;
				elsif (pieces(nextPiece)(1) < -5) then
					Shift := Shift + 10;
				elsif (pieces(nextPiece)(2) < -5) then
					Shift := Shift + 10;
				elsif (pieces(nextPiece)(3) < -5) then
					Shift := Shift + 10;
				end if;
				
				-- Step TWO: Check if we CAN insert that piece without conflict.
				can_insert := '1';
				if (boardState(pieces(nextPiece)(0) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieces(nextPiece)(1) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieces(nextPiece)(2) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieces(nextPiece)(3) + Shift) = '1') then
					can_insert := '0';
				end if;
				
				--Step THREE-A: SET THE NEW PIECE!
				if (can_insert = '1') then
					next_pieceLocations(0) <= pieces(nextPiece)(0) + Shift;
					next_pieceLocations(1) <= pieces(nextPiece)(1) + Shift;
					next_pieceLocations(2) <= pieces(nextPiece)(2) + Shift;
					next_pieceLocations(3) <= pieces(nextPiece)(3) + Shift;
					Next_State <= waiting;
					nextcurrentPiece <= nextPiece;
				--Step THREE-B: BOOO GAME OVER MUAHAHAHAHAHA
				else
					Next_State <= GAME_OVER;
				end if;
			when waiting =>
				if (clockCounter > "1000000000000000000000" and sigKeyboard /= key_nothing) then
					--nextsigMyKeyCount <= sigKeyCount;
					--We've waited long enough to allow the player to move or something
					if (sigKeyboard = key_left or sigKeyboard = key_right) then
						Next_State <= move_left_or_right;
					--elsif (sigKeyboard = key_down) then
					else --Same as above since no key_drop
						Next_State <= turn_action;
					end if;
				elsif (clockCounter > "100000000000000000000000") then
					--Turn's up!
					Next_State <= turn_action;
				else
					Next_State <= waiting;
				end if;
			when move_left_or_right =>
				if (LastSigKeyboard = key_left) then
					Shift := -1;
				else
					Shift := 1;
				end if;
				
				--Step One: Check if we can move without hitting a block.
				can_insert := '1';
				if (boardState(pieceLocations(0) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieceLocations(1) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieceLocations(2) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieceLocations(3) + Shift) = '1') then
					can_insert := '0';

				
				--Step Two - Check if doing that would cause us to wrap between rows.
				elsif (shift = 1 and pieceLocations(0) = 199) then
					can_insert := '0';
				elsif (shift = 1 and pieceLocations(1) = 199) then
					can_insert := '0';
				elsif (shift = 1 and pieceLocations(2) = 199) then
					can_insert := '0';
				elsif (shift = 1 and pieceLocations(3) = 199) then
					can_insert := '0';
				elsif (getRow(pieceLocations(0)) /= getRow(pieceLocations(0) + Shift)) then
					can_insert := '0';
				elsif (getRow(pieceLocations(1)) /= getRow(pieceLocations(1) + Shift)) then
					can_insert := '0';
				elsif (getRow(pieceLocations(2)) /= getRow(pieceLocations(2) + Shift)) then
					can_insert := '0';
				elsif (getRow(pieceLocations(3)) /= getRow(pieceLocations(3) + Shift)) then
					can_insert := '0';
				end if;

				--Step Three-A: We cannot! Screw that, we're going back to waiting.
				if (can_insert = '0') then
					Next_State <= waiting;
				else
				--Step Three-B: We Can! Move it!
					next_pieceLocations(0) <= PieceLocations(0) + Shift;
					next_pieceLocations(1) <= PieceLocations(1) + Shift;
					next_pieceLocations(2) <= PieceLocations(2) + Shift;
					next_pieceLocations(3) <= PieceLocations(3) + Shift;
					Next_State <= action_done;
				end if;
			when action_done =>
				--Clock resets here.
				Next_State <= waiting;
			when turn_action =>
				can_insert := '1';
				Shift := 10;
				
				--Step One: Check if we're at the bottom of the board
					--Seperate from checking room so we never add shift and go out of bounds
					
				if (pieceLocations(0) > 189) then
					can_insert := '0';
				elsif (pieceLocations(1) > 189) then
					can_insert := '0';
				elsif (pieceLocations(2) > 189) then
					can_insert := '0';
				elsif (pieceLocations(3) > 189) then
					can_insert := '0';
				--Step Two: Check if there is room to move the piece down
				elsif (boardState(pieceLocations(0) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieceLocations(1) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieceLocations(2) + Shift) = '1') then
					can_insert := '0';
				elsif (boardState(pieceLocations(3) + Shift) = '1') then
					can_insert := '0';
				end if;
				
				--Step Three-A: We cannot move, plant and new piece
				if (can_insert = '0') then
					Next_State <= plant_0;
				--Step Three-B: Move.
				else
					next_pieceLocations(0) <= PieceLocations(0) + Shift;
					next_pieceLocations(1) <= PieceLocations(1) + Shift;
					next_pieceLocations(2) <= PieceLocations(2) + Shift;
					next_pieceLocations(3) <= PieceLocations(3) + Shift;
					Next_State <= action_done;
				end if;
				
			when plant_0 =>
				boardStateInput <= '1';
				boardStateAddr <= pieceLocations(0);
				sigAddr <= PieceLocations(0);
				sigDi <= pieceColors(currentPiece);
				sigWe <= '1';
				Next_State <= plant_1;			
			when plant_1 =>
				boardStateInput <= '1';
				boardStateAddr <= pieceLocations(1);
				sigAddr <= PieceLocations(1);
				sigDi <= pieceColors(currentPiece);
				sigWe <= '1';
				Next_State <= plant_2;		
			when plant_2 =>
				boardStateInput <= '1';
				boardStateAddr <= pieceLocations(2);
				sigAddr <= PieceLocations(2);
				sigDi <= pieceColors(currentPiece);
				sigWe <= '1';
				Next_State <= plant_3;	
			when plant_3 =>
				boardStateInput <= '1';
				boardStateAddr <= pieceLocations(3);
				sigAddr <= PieceLocations(3);
				sigDi <= pieceColors(currentPiece);
				sigWe <= '1';
				Next_State <= line_break;		
			when line_break =>
				next_state <= adding_new_piece;
			--adding_new_piece;
			when GAME_OVER =>
				next_state <= GAME_OVER;
			when others =>
				next_state <= GAME_OVER;
		end case;
end process;

end Behavioral;