📄 altera_avalon_nec_tft_lcd_controller.vhd
字号:
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 + -