library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity buffered_line_generator is
	port(
		signal clock : in std_logic := '0';
		
		signal row : in signed (8 downto 0) := (others => '0');
		signal camera_x, camera_y, camera_z : in unsigned (8 downto 0) := (others => '0');
		
		signal rect_memory_address : out unsigned (7 downto 0) := (others => '0');
		signal rect_memory_data : in unsigned (7 downto 0) := (others => '0');
		
		-- Access to line buffer
		signal screen_col : in unsigned(8 downto 0) := (others => '0');
		signal screen_col_color : out std_logic_vector (17 downto 0) := (others => '0');
		
		-- unit testing signals
		signal done : out std_logic := '0'
	);
end buffered_line_generator;

architecture caster of buffered_line_generator is
	signal write_col_offset : unsigned (3 downto 0) := (others => '0');
	constant MAX_COL_OFFSET : unsigned (3 downto 0) := "1111";
	signal current_row : signed (8 downto 0) := (others => '0');
	
	-- rectangle memory
	signal rec_read_x0, rec_read_y0, rec_read_z0, rec_read_x1, rec_read_y1, rec_read_z1,
		rec_read_color : unsigned (7 downto 0) := (others => '0');
	signal rec_write_x0, rec_write_y0, rec_write_z0,
		rec_write_x1, rec_write_y1, rec_write_z1 : unsigned (8 downto 0) := (others => '0');
	signal rec_write_color : unsigned (5 downto 0) := (others => '0');
	signal read_rect_address : unsigned (7 downto 0) := (others => '0');
	constant MAX_REC_MEM_PLUS_1 : unsigned (7 downto 0) := "00101010";
	
	-- ray control signals
	type read_states is (zero, one, two, three, four, five, six, seven, eight);
	signal read_state : read_states := zero;
	type control_states is (c_zero, c_one, c_two_almost, c_two, c_three_almost,
		c_three, c_four, c_five, c_six);
	signal control_state : control_states := c_zero;
	signal ray_count : unsigned (0 downto 0) := "0";
	
	-- ray units
	signal new_pixel : std_logic := '0';
	signal new_rectangle : std_logic := '0';
	signal ray_units_done : std_logic := '0';
	signal done_rectangles : std_logic := '0';
	signal col_base0, col_base1, col_base2, col_base3, col_base4, col_base5, col_base6,
		col_base7, col_base8, col_base9, col_base10, col_base11, col_base12, col_base13,
		col_base14, col_base15 , col_base16, col_base17, col_base18, col_base19
		: signed (8 downto 0) := (others => '0');
	signal ru_done_0, ru_done_1, ru_done_2, ru_done_3, ru_done_4, ru_done_5, ru_done_6,
		ru_done_7, ru_done_8, ru_done_9, ru_done_10, ru_done_11, ru_done_12, ru_done_13,
		ru_done_14, ru_done_15 , ru_done_16, ru_done_17, ru_done_18, ru_done_19
		: std_logic := '0';
	signal ru_rgb_0, ru_rgb_1, ru_rgb_2, ru_rgb_3, ru_rgb_4, ru_rgb_5, ru_rgb_6, ru_rgb_7,
		ru_rgb_8, ru_rgb_9, ru_rgb_10, ru_rgb_11, ru_rgb_12, ru_rgb_13, ru_rgb_14, ru_rgb_15,
		ru_rgb_16, ru_rgb_17, ru_rgb_18, ru_rgb_19
		: unsigned (17 downto 0) := (others => '0');
	signal read_0, read_1, read_2, read_3, read_4, read_5, read_6, read_7, read_8, read_9,
		read_10, read_11, read_12, read_13, read_14, read_15, read_16, read_17, read_18, read_19
		: unsigned (17 downto 0) := (others => '0');
	
	-- pixel memory
	signal pixel_write_address, pixel_read_address : unsigned(4 downto 0) := "00000";
	signal write_pixels : std_logic := '0';
	
	constant MAX_PIXEL_BLOCK : unsigned(4 downto 0) := "10011";
	signal pixel_block : unsigned(4 downto 0) := "00000";
	signal read_col_offset : unsigned(3 downto 0) := "0000";
	signal last_screen_col : unsigned(8 downto 0) := (others => '0');
begin
	rect_memory_address <= read_rect_address;
	
	-- If you comment out ray units to improve compile time for debugging,
	-- make sure you update this value as well. Otherwise your architecture
	-- will just get optimized away and nothing will happen.
	ray_units_done <= ru_done_0 and ru_done_1 and ru_done_2 and ru_done_3 and 
	                  ru_done_4 and ru_done_5 and ru_done_6 and ru_done_7 and
	                  ru_done_8 and ru_done_9 and ru_done_10 and ru_done_11 and
	                  ru_done_12 and ru_done_13 and ru_done_14 and ru_done_15 and
	                  ru_done_16 and ru_done_17 and ru_done_18 and ru_done_19;
	
	double_buffering_addresses : process(current_row, write_col_offset, read_col_offset)
		variable even_row, odd_row : unsigned(0 downto 0) := "0";
	begin
		even_row := unsigned(current_row(0 downto 0));
		if even_row = 0 then
			pixel_write_address <= "0" & write_col_offset;
			pixel_read_address <= "1" & read_col_offset;
		else
			pixel_write_address <= "1" & write_col_offset;
			pixel_read_address <= "0" & read_col_offset;
		end if;
	end process;
	
	read_line_buffer : process(screen_col, read_0, read_1, read_2, read_3, read_4, read_5, read_6,
			read_7, read_8, read_9, read_10, read_11, read_12, read_13, read_14, read_15, read_16,
			read_17, read_18, read_19)
		variable color : unsigned(17 downto 0) := (others => '0');
		variable block_from_col : unsigned(4 downto 0) := (others => '0');
	begin
		block_from_col := screen_col(8 downto 4);
		if block_from_col = "00000" then
			color := read_0;
		elsif block_from_col = "00001" then
			color := read_1;
		elsif block_from_col = "00010" then
			color := read_2;
		elsif block_from_col = "00011" then
			color := read_3;
		elsif block_from_col = "00100" then
			color := read_4;
		elsif block_from_col = "00101" then
			color := read_5;
		elsif block_from_col = "00110" then
			color := read_6;
		elsif block_from_col = "00111" then
			color := read_7;
		elsif block_from_col = "01000" then
			color := read_8;
		elsif block_from_col = "01001" then
			color := read_9;
		elsif block_from_col = "01010" then
			color := read_10;
		elsif block_from_col = "01011" then
			color := read_11;
		elsif block_from_col = "01100" then
			color := read_12;
		elsif block_from_col = "01101" then
			color := read_13;
		elsif block_from_col = "01110" then
			color := read_14;
		elsif block_from_col = "01111" then
			color := read_15;
		elsif block_from_col = "10000" then
			color := read_16;
		elsif block_from_col = "10001" then
			color := read_17;
		elsif block_from_col = "10010" then
			color := read_18;
		elsif block_from_col = "10011" then
			color := read_19;
		else
			color := "000000000000000000";
		end if;
		screen_col_color <= std_logic_vector(color);
		read_col_offset <= screen_col(3 downto 0);
	end process read_line_buffer;
	
	depending_on_control : process(clock)
	begin
		if rising_edge(clock) then
			case read_state is
			when zero =>
				read_state <= one;
			when one =>
				rec_read_x0 <= rect_memory_data;
				read_state <= two;
			when two =>
				rec_read_y0 <= rect_memory_data;
				read_state <= three;
			when three =>
				rec_read_z0 <= rect_memory_data;
				read_state <= four;
			when four =>
				rec_read_x1 <= rect_memory_data;
				read_state <= five;
			when five =>
				rec_read_y1 <= rect_memory_data;
				read_state <= six;
			when six =>
				rec_read_z1 <= rect_memory_data;
				read_state <= seven;
			when seven =>
				rec_read_color <= rect_memory_data;
				read_state <= eight;
			when eight =>
				-- hang out for a while.
			end case;
			if read_state /= seven and read_state /= eight then
				read_rect_address <= read_rect_address + 1;
			end if;
			
			case control_state is
			when c_zero =>
				if read_state = eight then
					control_state <= c_one;
					new_pixel <= '1';
				end if;
			when c_one => -- new rectangle ready
				new_pixel <= '0';
				done_rectangles <= '0';
				rec_write_x0 <= "0" & rec_read_x0;
				rec_write_y0 <= "0" & rec_read_y0;
				rec_write_z0 <= "0" & rec_read_z0;
				rec_write_x1 <= "0" & rec_read_x1;
				rec_write_y1 <= "0" & rec_read_y1;
				rec_write_z1 <= "0" & rec_read_z1;
				rec_write_color <= rec_read_color(5 downto 0);
				new_rectangle <= '1';
				read_state <= zero;
				if read_rect_address = MAX_REC_MEM_PLUS_1 then
					read_rect_address <= "00000000";
					control_state <= c_three_almost;
				else
					control_state <= c_two_almost;
				end if;
			when c_two_almost => -- just started. Don't want to check done yet, wait a cycle.
				new_rectangle <= '0';
				control_state <= c_two;
			when c_two => -- done a rectangle
				if ray_units_done = '1' and read_state = eight then
					control_state <= c_one;
				end if;
			when c_three_almost =>
				new_rectangle <= '0';
				control_state <= c_three;
			when c_three => -- done all rectangles
				if ray_units_done = '1' then
					done_rectangles <= '1';
					if ray_count = "1" then
						ray_count <= "0";
						control_state <= c_four;
					else
						ray_count <= ray_count + 1;
						control_state <= c_one;
					end if;
				end if;
			when c_four => -- done reflections
				done_rectangles <= '0';
				write_pixels <= '1';
				control_state <= c_five;
			when c_five =>
				write_pixels <= '0';
				if write_col_offset = MAX_COL_OFFSET then
					control_state <= c_six;
				else
					new_pixel <= '1';
					write_col_offset <= write_col_offset + 1;
					control_state <= c_one;
				end if;
			when c_six => -- done row
				done <= '1';
			end case;
			-- reset when the row changes
			if current_row /= row then
				current_row <= row;
				new_pixel <= '1';
				if control_state /= c_zero then
					control_state <= c_one;
				end if;
				write_col_offset <= "0000";
				done <= '0';
			end if;
		end if;
	end process;
	
	-- Obviously I couldn't get loop generate figured out.
	ray_unit_0 : entity work.ray_unit
	port map (clk => clock, col_base => col_base0, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_0, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_0);
	pixel_ram_0 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_0, do => read_0);
	ray_unit_1 : entity work.ray_unit
	port map (clk => clock, col_base => col_base1, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_1, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_1);
	pixel_ram_1 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_1, do => read_1);
	ray_unit_2 : entity work.ray_unit
	port map (clk => clock, col_base => col_base2, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_2, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_2);
	pixel_ram_2 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_2, do => read_2);
	ray_unit_3 : entity work.ray_unit
	port map (clk => clock, col_base => col_base3, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_3, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_3);
	pixel_ram_3 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_3, do => read_3);
	ray_unit_4 : entity work.ray_unit
	port map (clk => clock, col_base => col_base4, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_4, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_4);
	pixel_ram_4 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_4, do => read_4);
	ray_unit_5 : entity work.ray_unit
	port map (clk => clock, col_base => col_base5, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_5, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_5);
	pixel_ram_5 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_5, do => read_5);
	ray_unit_6 : entity work.ray_unit
	port map (clk => clock, col_base => col_base6, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_6, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_6);
	pixel_ram_6 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_6, do => read_6);
	ray_unit_7 : entity work.ray_unit
	port map (clk => clock, col_base => col_base7, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_7, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_7);
	pixel_ram_7 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_7, do => read_7);
	ray_unit_8 : entity work.ray_unit
	port map (clk => clock, col_base => col_base8, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_8, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_8);
	pixel_ram_8 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_8, do => read_8);
	ray_unit_9 : entity work.ray_unit
	port map (clk => clock, col_base => col_base9, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_9, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_9);
	pixel_ram_9 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_9, do => read_9);
	ray_unit_10 : entity work.ray_unit
	port map (clk => clock, col_base => col_base10, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_10, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_10);
	pixel_ram_10 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_10, do => read_10);
	ray_unit_11 : entity work.ray_unit
	port map (clk => clock, col_base => col_base11, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_11, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_11);
	pixel_ram_11 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_11, do => read_11);
	ray_unit_12 : entity work.ray_unit
	port map (clk => clock, col_base => col_base12, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_12, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_12);
	pixel_ram_12 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_12, do => read_12);
	ray_unit_13 : entity work.ray_unit
	port map (clk => clock, col_base => col_base13, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_13, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_13);
	pixel_ram_13 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_13, do => read_13);
	ray_unit_14 : entity work.ray_unit
	port map (clk => clock, col_base => col_base14, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_14, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_14);
	pixel_ram_14 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_14, do => read_14);
	ray_unit_15 : entity work.ray_unit
	port map (clk => clock, col_base => col_base15, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_15, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_15);
	pixel_ram_15 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_15, do => read_15);
	ray_unit_16 : entity work.ray_unit
	port map (clk => clock, col_base => col_base16, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_16, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_16);
	pixel_ram_16 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_16, do => read_16);
	ray_unit_17 : entity work.ray_unit
	port map (clk => clock, col_base => col_base17, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_17, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_17);
	pixel_ram_17 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_17, do => read_17);
	ray_unit_18 : entity work.ray_unit
	port map (clk => clock, col_base => col_base18, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_18, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_18);
	pixel_ram_18 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_18, do => read_18);
	ray_unit_19 : entity work.ray_unit
	port map (clk => clock, col_base => col_base19, row => current_row, col_offset => write_col_offset, cam_co_ord_x => camera_x, cam_co_ord_y => camera_y, cam_co_ord_z => camera_z, new_pixel => new_pixel, new_rectangle => new_rectangle, done => ru_done_19, done_rectangles => done_rectangles, rec_x0 => rec_write_x0, rec_y0 => rec_write_y0, rec_z0 => rec_write_z0, rec_x1 => rec_write_x1, rec_y1 => rec_write_y1, rec_z1 => rec_write_z1, color => rec_write_color, rgb => ru_rgb_19);
	pixel_ram_19 : entity work.pixel_ram
	port map (clk => clock, we => write_pixels, write_a => pixel_write_address, read_a => pixel_read_address, di => ru_rgb_19, do => read_19);
	
	col_base0 <= "101100000"; col_base1 <= "101110000"; col_base2 <= "110000000";
	col_base3 <= "110010000"; col_base4 <= "110100000"; col_base5 <= "110110000";
	col_base6 <= "111000000"; col_base7 <= "111010000"; col_base8 <= "111100000";
	col_base9 <= "111110000"; col_base10 <= "000000000"; col_base11 <= "000010000";
	col_base12 <= "000100000"; col_base13 <= "000110000"; col_base14 <= "001000000";
	col_base15 <= "001010000"; col_base16 <= "001100000"; col_base17 <= "001110000";
	col_base18 <= "010000000"; col_base19 <= "010010000";
end caster;