⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 altera_avalon_nec_tft_lcd_controller.vhd

📁 quartus II-sopc builder avalon总线LCD控制IPCORE
💻 VHD
📖 第 1 页 / 共 2 页
字号:
palette_mode <= cr(2 downto 1);
vert_scan_dir <= cr(3);
interrupt_enable <= cr(4);

BL_EN <= cr(5);
PS_EN <= cr(6);


-- create irq 

read_isr <= '1' when chipselect = '1' and address(8) = '0' and address(1 downto 0) = ISR_ADDR and read = '1' else
			'0';
			
irq <= irq_int and interrupt_enable;

gen_irq: process(clk, reset, read_isr, end_of_frame, irq_int, updated_enable_dma)

	begin
		
		irq_int <= irq_int;
	
		if reset = '1' then
			irq_int <= '0';
		elsif (clk'EVENT AND clk = '1') then
			if (updated_enable_dma = '1') then
				if (end_of_frame = '1') then
					irq_int <= '1';
				elsif (read_isr = '1') then 
					irq_int <= '0';
				else
					irq_int <= irq_int;
				end if;
			else
				irq_int <= irq_int;
			end if;
		end if;
	end process;

------------------------------------------------------------------------------------------------------------------------------------------------
--
--												Dual Video Buffer DMA
--
------------------------------------------------------------------------------------------------------------------------------------------------

-- define dma controller avalon signals

address_mp <= dma_current_address;
	
-- create dma controller that will fetch data from an address in memory and write it to the fifo

gen_dma : process(clk_mp, reset, dma_next_state, dma_count, current_burst_count, end_of_frame, fifo_ready_for_data, readdatavalid,
				  dma_current_address)

	begin
	
		if reset = '1' then
			dma_current_address <= (others => '0');	
			dma_count <= 0;	
			current_burst_count <= 0;
		elsif (clk_mp'EVENT and clk_mp = '1') then
		
			if dma_next_state = idle then												-- initialise dma controller pointers after eof
				dma_current_address <= nba;											
				current_burst_count <= MAX_BURST_COUNT;			
				dma_count <= 0;	
			elsif (dma_next_state = data_phase) and (readdatavalid = '1') then
				dma_current_address <= dma_current_address;
				dma_count <= dma_count;
				current_burst_count <= current_burst_count -1;												
			elsif (dma_next_state = data_phase) and current_burst_count = 0 and end_of_frame = '0' and fifo_ready_for_data = '1' then	
				dma_current_address <= dma_current_address + "00100000";					
				dma_count <= dma_count + MAX_BURST_COUNT;
				current_burst_count <= MAX_BURST_COUNT;			
			else
				dma_current_address <= dma_current_address;
				dma_count <= dma_count;
				current_burst_count <= current_burst_count;			
			end if;
		end if;
	end process;
		
-- create dma state machine to track read cycle progress 

dma_transitions: process (clk_mp, reset, waitrequest, updated_enable_dma, fifo_ready_for_data, dma_next_state, 
						  current_burst_count, end_of_frame)

	begin
	
		dma_next_state <= dma_next_state;
	
		if reset = '1' then
			dma_next_state <= idle;	
				
		elsif (clk_mp'EVENT AND clk_mp = '1') then
		
			dma_next_state <= dma_next_state;

			case dma_next_state is																		
				when idle => 
					if updated_enable_dma = '1' and fifo_ready_for_data = '1' then 						-- wait for the dma to be enabled
						dma_next_state <= address_phase;												-- and the fifo to have emptied
					else
						dma_next_state <= idle;
					end if;
				when address_phase =>
					if waitrequest = '0' then															-- avalon fabric accepted the cycle
						dma_next_state <= data_phase;
					else
						dma_next_state <= address_phase;
					end if;
				when data_phase =>													
					if current_burst_count = 0 and end_of_frame = '0' and fifo_ready_for_data = '1' then	-- current burst done?
						dma_next_state <= address_phase;
					elsif current_burst_count = 0 and end_of_frame = '1' then								-- end of frame ?
						dma_next_state <= idle;
					else
						dma_next_state <= data_phase;
					end if;
				when others =>
					dma_next_state <= idle;
			end case;
		end if;
	end process;
	
read_mp <= '1' when (dma_next_state = address_phase) else
		   '0';
	
burstcount <= "1000";	
	
end_of_frame <= '1' when (updated_palette_mode = BPP_18 and dma_count = 76792 and current_burst_count = 0) or			
				 		 (updated_palette_mode = BPP_16 and dma_count = 38392 and current_burst_count = 0) or				
				 		 (updated_palette_mode = BPP_8 and dma_count = 19192 and current_burst_count = 0) else
				'0';
				
-- only allow palette mode that feeds the tc unit to be updated when the dma is idle. user may wish to change csr palette mode bits while the
-- dma was still active. we can only only this derived signal to be updated once the frame is complete. it is used to control the rgb fifo
-- output mux. 

gen_updated_palette_mode : process (clk, reset, dma_next_state, palette_mode, updated_palette_mode, enable_dma, updated_enable_dma )				

	begin
	
		if reset = '1' then
		
			updated_palette_mode <= "00";
			updated_enable_dma <= '0';
			
		elsif (clk'EVENT and clk = '1') then
		
			if (dma_next_state = idle) then													-- update when we turn on engine
				updated_palette_mode <= palette_mode;
				updated_enable_dma <= enable_dma;
			elsif (dma_next_state = data_phase) and end_of_frame = '1' then					-- also update at the eof, but only enable_dma
				updated_palette_mode <= updated_palette_mode;
				updated_enable_dma <= enable_dma;
			else
				updated_palette_mode <= updated_palette_mode;
				updated_enable_dma <= updated_enable_dma;

			end if;
		else
			updated_palette_mode <= updated_palette_mode;
			updated_enable_dma <= updated_enable_dma;
			
		end if;
			
	end process;
				

------------------------------------------------------------------------------------------------------------------------------------------------
--
--												RGB FIFO
--
------------------------------------------------------------------------------------------------------------------------------------------------
	
-- fifo flow control & avalon streaming signals

fifo_ready_for_data <= '1' when fifo_usedw < "11101111" else
					   '0';
					
fifo_wrreq <= '1' when (dma_next_state = data_phase) and (readdatavalid = '1') else			-- write to fifo while burst cycle active
			  '0';

-- define fifo data paths

fifo_data_in <= readdata_mp(31 downto 0);


-- instantiate the video fifo

fifo_256x32_inst : fifo_256x32 

PORT MAP 
	(
		data	=> fifo_data_in,
		wrreq	=> fifo_wrreq,
		rdreq	=> fifo_rdreq,
		rdclk	=> tclk,
		wrclk	=> clk,
		aclr	=> reset,
		q		=> fifo_data_out,
		rdempty	=> fifo_empty,
		wrusedw	=> fifo_usedw
	);
	
------------------------------------------------------------------------------------------------------------------------------------------------
--
--												Palette Translator
--
------------------------------------------------------------------------------------------------------------------------------------------------
	
-- instantiate the 256 color palette LUT

palette_wren <= '1' when chipselect = '1' and address(8) = '1' and write = '1' else
				'0';		   
				
palette_memory_inst : palette_memory 

PORT MAP
	(
		data		=>	writedata(17 downto 0),
		wren		=>	palette_wren,
		wraddress	=>	address(7 downto 0),
		rdaddress	=>	lut_data(7 downto 0),
		clock		=>	clk,
		q			=>	palette_q
	);
	


-- 5:6:5: mode					

bpp_16_data_out(17 downto 0) <= fifo_data_out(15 downto 11) & '0' & fifo_data_out(10 downto 5) & fifo_data_out(4 downto 0) & '0' when video_lane_select = "00" else
								fifo_data_out(31 downto 27) & '0' & fifo_data_out(26 downto 21) & fifo_data_out(20 downto 16) & '0';
								
-- 256 color palette mode								
								
lut_data(7 downto 0) <= fifo_data_out(7 downto 0) when	video_lane_select = "00" else
						fifo_data_out(15 downto 8) when video_lane_select = "01" else							
						fifo_data_out(23 downto 16) when video_lane_select = "10" else					
						fifo_data_out(31 downto 24) when video_lane_select = "11";							
					
bpp_8_data_out(17 downto 0) <= palette_q(17 downto 0);						

-- custom mode for mandelbrot demo

bpp_mandel_data_out(17 downto 0) <= "110011" & "000000" & "000000" when lut_data = "00000000" else		-- 0x00 red
									"000000" & "110011" & "000000" when lut_data = "00000001" else		-- 0x01 green								
									"000000" & "000000" & "110011" when lut_data = "00000010" else		-- 0x02 blue
									"111111" & "000000" & "100110" when lut_data = "00000011" else		-- 0x03 pink
									"000000" & "111111" & "100110" when lut_data = "00000100" else		-- 0x04 aqua
									"100110" & "000000" & "111111" when lut_data = "00000101" else		-- 0x05 violet
									"111111" & "100110" & "000000" when lut_data = "00000110" else		-- 0x06 orange
									"100110" & "111111" & "000000" when lut_data = "00000111" else		-- 0x07 lime green
									"000000" & "100110" & "111111" when lut_data = "00001000" else		-- 0x08 sky blue
									"110011" & "000000" & "100110" when lut_data = "00001001" else		-- 0x09 magenta
									"000000" & "110011" & "100110" when lut_data = "00001010" else		-- 0x0a pale green
									"100110" & "000000" & "110011" when lut_data = "00001011" else		-- 0x0b purple
									"110011" & "100110" & "000000" when lut_data = "00001100" else		-- 0x0c golden yellow
									"100110" & "110011" & "000000" when lut_data = "00001101" else		-- 0x0d yellowish green
									"000000" & "100110" & "110011" when lut_data = "00001110" else		-- 0x0e light blue
									"110011" & "000000" & "110011" when lut_data = "00001111" else		-- 0x0f pinkish purple  
									"111111" & "111111" & "111111" when lut_data = "00010000" else		-- 0x10 white
									"000000" & "000000" & "000000" when lut_data = "00010001" else		-- 0x11 black
									"000000000000000000";
									
-- palette tranlator mux

RGB(17 downto 0) <= fifo_data_out(17 downto 0) when palette_mode_lock = BPP_18 and fifo_data_available = '1' else				-- 6:6:6 mode
					bpp_16_data_out(17 downto 0) when palette_mode_lock = BPP_16 and fifo_data_available = '1' else				-- 5:6:5 mode
					bpp_8_data_out(17 downto 0) when palette_mode_lock = BPP_8 and fifo_data_available = '1' else				-- 8 bit mode
					bpp_mandel_data_out(17 downto 0) when palette_mode_lock = BPP_MANDEL and fifo_data_available = '1' else		-- mandelbrot mode
					"111111111111111111" when fifo_data_available = '0';
									

									
------------------------------------------------------------------------------------------------------------------------------------------------
--
--												Timing Control
--
------------------------------------------------------------------------------------------------------------------------------------------------

-- synch back to tclk domain from clk domain

sync_from_clk_to_tclk: process(tclk, reset, palette_mode, updated_palette_mode, palette_mode_tclk)

	begin
		
		if reset = '1' then
			palette_mode_tclk <= "00";
			
		elsif (tclk'EVENT AND tclk = '1') then
			palette_mode_tclk <= updated_palette_mode;
		else
			palette_mode_tclk <= palette_mode_tclk;
		end if;
		
	end process;



timing_control_inst : timing_control 

GENERIC MAP
	(
		HORIZ_RES				=>	HORIZ_RES,
		VERT_RES				=>	VERT_RES
	)
PORT MAP
	(

		clk						=>	tclk,
		reset					=>	reset,
		palette_mode			=>	palette_mode_tclk,			
		vert_scan_dir			=>	vert_scan_dir,			
		video_lane_select_ext	=>	video_lane_select,	
		fifo_rdreq_ext			=>	fifo_rdreq,		
		fifo_empty				=>	fifo_empty,	
		fifo_data_available_ext	=>	fifo_data_available,
		palette_mode_lock_ext	=>	palette_mode_lock,
		HCK						=>	HCK,										
		STB						=>	STB,										
		HSP						=>	HSP,											
		AP						=>	AP,										
		POL						=>	POL,											
		VCK						=>	VCK,											
		VOE						=>	VOE,				
		VSP						=>	VSP,				
		INV						=>	INV											
	);


-- define pixel bus data sources. sources vary depending on the color palette mode

R(5 downto 0) <= RGB(17 downto 12); 
G(5 downto 0) <= RGB(11 downto 6);
B(5 downto 0) <= RGB(5 downto 0);
				
	
end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -