Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

VGA output from SDRAM

Altera_Forum
Honored Contributor II
1,536 Views

Hello, 

 

I am working on a system that can output data from the SDRAM of a DE2 board to a VGA display. I am currently able to read 16-bits of data, and output these to the entire display. I would like split the display into smaller tiles, that gets their data from different locations in the SDRAM, but I am unsure of how to implement this. If anyone has any ideas it would be greatly appreciated :) 

 

My current code for the VGA module is shown below, it consists of four processes. One for vertical sync, one for horzontal sync, one for drawing to the display, and one for reading the SDRAM. 

 

library ieee;use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity mm_bus_vga is port ( -- Avalon Master interface csi_clockreset_clk : in std_logic; -- Avalon Clk csi_clockreset_reset_n : in std_logic; -- Avalon Reset -- read master avm_read_master_read : out std_logic; avm_read_master_address : out std_logic_vector (31 downto 0); avm_read_master_readdata : in std_logic_vector (15 downto 0); avm_read_master_waitrequest : in std_logic; avm_read_master_datavalid : in std_logic; -- VGA signals vga_clk_25 : in std_logic; red, green, blue : out std_logic_vector(9 downto 0); hsync, vsync, clockOut, blank, compSync : out std_logic); end mm_bus_vga; architecture testGenerator of mm_bus_vga is -- vga stuff -- horizontal Timing constants for 640 x 480 @ 60Hz constant hFrontPorch : natural := 16; -- units are number of 25 MHz clocks constant hBackPorch : natural := 48; constant hDataLen : natural := 640; constant hSynWidth : natural := 96; -- vertical Timing constants for 640 x 480 @ 60Hz constant vFrontPorch : natural := 10; -- units are number of lines constant vBackPorch : natural := 33; constant vDataLen : natural := 480; constant vSynWidth : natural := 2; -- signal declaration signal hSyncCounter, vSyncCounter : integer range 0 to 1023; -- contrain integer to 10 bit. signal hSyncOut,vSyncOut,vBlank,hBlank : std_logic; -- attributes ensuring the signals defined below are not reduced away before simulation. attribute keep: boolean; -- don't reduce vSyncCounter and hSyncCounter signals away, so we can watch these signals i simulator attribute keep of vSyncCounter : signal is true; -- || -- attribute keep of hSyncCounter : signal is true; -- || -- -- avalon stuff -- state machine states constant sdram_address : std_logic_vector(31 downto 0) := X"00800000"; type read_states_T is (idle, running, stopping); signal read_state : read_states_T; -- extra read master signals signal read_address : std_logic_vector (31 downto 0); -- the current read address signal read_data : std_logic_vector (15 downto 0) := X"FFFF"; -- increment syncCounter, produce blanking and sync output. procedure syncGenerator( signal syncCounter : inout integer range 0 to 1023; signal syncOut : out std_logic; signal blankOut : out std_logic; constant frontPorch : in natural; constant backPorch : in natural; constant dataLen : in natural; constant syncWidth : in natural) is begin if (backPorch + dataLen + frontPorch + syncWidth < syncCounter) then syncCounter <= 0; else syncCounter <= syncCounter + 1; end if; if (backPorch > syncCounter and backPorch + dataLen > syncCounter) then blankOut <= '1'; else blankOut <= '0'; end if; if ( backPorch + dataLen + frontPorch < syncCounter) then syncOut <= '1'; else syncOut <= '0'; end if; end; begin -- horizontal process using the generic syncGenerator function to generate a proper hsync pulse. hsyn: process (csi_clockreset_reset_n,vga_clk_25) -- reacts on reset and 25 MHz clock. begin if csi_clockreset_reset_n = '0' then hSyncCounter <= 0; elsif rising_edge(vga_clk_25) then syncGenerator(hSyncCounter,hSyncOut,hBlank,hFrontPorch,hBackPorch,hDataLen,hSynWidth); -- generates active low pulse after every line end if; end process; -- vertical process using the generic syncGenerator function to generate a proper vsync pulse. vsyn: process (csi_clockreset_reset_n,hSyncOut) -- reacts on reset and hsync (meaning every line). begin if csi_clockreset_reset_n = '0' then vSyncCounter <= 0; elsif rising_edge(hSyncOut) then syncGenerator(vSyncCounter,vSyncOut,vBlank,vFrontPorch,vBackPorch,vDataLen,vSynWidth); -- generates active low pulse after every picture end if; end process; color: process (csi_clockreset_reset_n, hSyncCounter, vSyncCounter) -- draws to display begin red <= std_logic_vector(resize(unsigned(read_data), 10)); green <= std_logic_vector(resize(unsigned(read_data), 10)); blue <= std_logic_vector(resize(unsigned(read_data), 10)); end process; read_sdram: process (csi_clockreset_reset_n, csi_clockreset_clk) begin if csi_clockreset_reset_n = '0' then read_state <= idle; read_address <= (others => '0'); elsif rising_edge(csi_clockreset_clk) then case read_state is when idle => read_address <= sdram_address; read_state <= running; avm_read_master_read <= '1'; when running => if avm_read_master_waitrequest /= '1' then read_state <= stopping; avm_read_master_read <= '0'; end if; when stopping => if avm_read_master_datavalid = '1' then read_data <= avm_read_master_readdata; read_state <= idle; end if; end case; end if; end process; vsync <= vSyncOut; -- connect vsync to entity hsync <= hSyncOut; -- connect hsync to entity clockOut <= vga_clk_25; -- 25 MHz clock for DAC blank <= not (vBlank or hBlank); -- active low blanking compSync <= '1'; -- never perform any composite sync -- map the internal address to the external port avm_read_master_address <= read_address; end testGenerator;
0 Kudos
0 Replies
Reply