- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
Link Copied
0 Replies

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page