DrStrangelove13
Programmer
hello,
I am trying to port the vga controller below to a 128k Ram[16:0] and was hoping someone may have already done this or could direct me towards the right way to do this. When I am having little success getting the controller to read a picture stored in the RAM correctly.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity vgacore is
port
(
reset: in std_logic; -- reset
clock: in std_logic; -- VGA dot clock
hsyncb: buffer std_logic; -- horizontal (line) sync
vsyncb: out std_logic; -- vertical (frame) sync
rgb: out std_logic_vector(5 downto 0); -- red,green,blue colors
addr: out std_logic_vector(14 downto 0); -- address into video RAM
data: in std_logic_vector(7 downto 0); -- data from video RAM
csb: out std_logic; -- video RAM chip enable
oeb: out std_logic; -- video RAM output enable
web: out std_logic -- video RAM write enable
);
end vgacore;
architecture vgacore_arch of vgacore is
signal hcnt: std_logic_vector(8 downto 0); -- horizontal pixel counter
signal vcnt: std_logic_vector(9 downto 0); -- vertical line counter
signal pixrg: std_logic_vector(7 downto 0); -- byte-wide register for 4 pixels
signal blank: std_logic; -- video blanking signal
signal pblank: std_logic; -- pipelined video blanking signal
begin
A: process(clock,reset)
begin
-- reset asynchronously clears pixel counter
if reset='1' then
hcnt <= "000000000";
-- horiz. pixel counter increments on rising edge of dot clock
elsif (clock'event and clock='1') then
-- horiz. pixel counter rolls-over after 381 pixels
if hcnt<380 then
hcnt <= hcnt + 1;
else
hcnt <= "000000000";
end if;
end if;
end process;
B: process(hsyncb,reset)
begin
-- reset asynchronously clears line counter
if reset='1' then
vcnt <= "0000000000";
-- vert. line counter increments after every horiz. line
elsif (hsyncb'event and hsyncb='1') then
-- vert. line counter rolls-over after 528 lines
if vcnt<527 then
vcnt <= vcnt + 1;
else
vcnt <= "0000000000";
end if;
end if;
end process;
C: process(clock,reset)
begin
-- reset asynchronously sets horizontal sync to inactive
if reset='1' then
hsyncb <= '1';
-- horizontal sync is recomputed on the rising edge of every dot clock
elsif (clock'event and clock='1') then
-- horiz. sync is low in this interval to signal start of a new line
if (hcnt>=291 and hcnt<337) then
hsyncb <= '0';
else
hsyncb <= '1';
end if;
end if;
end process;
D: process(hsyncb,reset)
begin
-- reset asynchronously sets vertical sync to inactive
if reset='1' then
vsyncb <= '1';
-- vertical sync is recomputed at the end of every line of pixels
elsif (hsyncb'event and hsyncb='1') then
-- vert. sync is low in this interval to signal start of a new frame
if (vcnt>=490 and vcnt<492) then
vsyncb <= '0';
else
vsyncb <= '1';
end if;
end if;
end process;
-- blank video outside of visible region: (0,0) -> (255,479)
E: blank <= '1' when (hcnt>=256 or vcnt>=480) else '0';
-- store the blanking signal for use in the next pipeline stage
F: process(clock,reset)
begin
if reset='1' then
pblank <= '0';
elsif (clock'event and clock='1') then
pblank <= blank;
end if;
end process;
-- video RAM control signals
G:
csb <= '0'; -- enable the RAM
web <= '1'; -- disable writing to the RAM
oeb <= blank; -- enable the RAM outputs when video is not blanked
-- The video RAM address is built from the lower 9 bits of the vertical
-- line counter and bits 7-2 of the horizontal pixel counter.
-- Each byte of the RAM contains four 2-bit pixels. As an example,
-- the byte at address ^h1234=^b0001,0010,0011,0100 contains the pixels
-- at (row,col) of (^h048,^hD0),(^h048,^hD1),(^h048,^hD2),(^h048,^hD3).
H: addr <= vcnt(8 downto 0) & hcnt(7 downto 2);
I: process(clock,reset)
begin
-- clear the pixel register on reset
if reset='1' then
pixrg <= "00000000";
-- pixel clock controls changes in pixel register
elsif (clock'event and clock='1') then
-- the pixel register is loaded with the contents of the video
-- RAM location when the lower two bits of the horiz. counter
-- are both zero. The active pixel is in the lower two bits
-- of the pixel register. For the next 3 clocks, the pixel
-- register is right-shifted by two bits to bring the other
-- pixels in the register into the active position.
if hcnt(1 downto 0)="00" then
pixrg <= data; -- load 4 pixels from RAM
else
pixrg <= "00" & pixrg(7 downto 2); -- right-shift pixel register
end if;
end if;
end process;
-- the color mapper translates each 2-bit pixel into a 6-bit
-- color value. When the video signal is blanked, the color
-- is forced to zero (black).
J: process(clock,reset)
begin
-- blank the video on reset
if reset='1' then
rgb <= "000000";
-- update the color outputs on every dot clock
elsif (clock'event and clock='1') then
-- map the pixel to a color if the video is not blanked
if pblank='0' then
case pixrg(1 downto 0) is
when "00" => rgb <= "110000"; -- red
when "01" => rgb <= "001100"; -- green
when "10" => rgb <= "000011"; -- blue
when others => rgb <= "111111"; -- white
end case;
-- otherwise, output black if the video is blanked
else
rgb <= "000000"; -- black
end if;
end if;
end process;
end vgacore_arch;
I am trying to port the vga controller below to a 128k Ram[16:0] and was hoping someone may have already done this or could direct me towards the right way to do this. When I am having little success getting the controller to read a picture stored in the RAM correctly.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity vgacore is
port
(
reset: in std_logic; -- reset
clock: in std_logic; -- VGA dot clock
hsyncb: buffer std_logic; -- horizontal (line) sync
vsyncb: out std_logic; -- vertical (frame) sync
rgb: out std_logic_vector(5 downto 0); -- red,green,blue colors
addr: out std_logic_vector(14 downto 0); -- address into video RAM
data: in std_logic_vector(7 downto 0); -- data from video RAM
csb: out std_logic; -- video RAM chip enable
oeb: out std_logic; -- video RAM output enable
web: out std_logic -- video RAM write enable
);
end vgacore;
architecture vgacore_arch of vgacore is
signal hcnt: std_logic_vector(8 downto 0); -- horizontal pixel counter
signal vcnt: std_logic_vector(9 downto 0); -- vertical line counter
signal pixrg: std_logic_vector(7 downto 0); -- byte-wide register for 4 pixels
signal blank: std_logic; -- video blanking signal
signal pblank: std_logic; -- pipelined video blanking signal
begin
A: process(clock,reset)
begin
-- reset asynchronously clears pixel counter
if reset='1' then
hcnt <= "000000000";
-- horiz. pixel counter increments on rising edge of dot clock
elsif (clock'event and clock='1') then
-- horiz. pixel counter rolls-over after 381 pixels
if hcnt<380 then
hcnt <= hcnt + 1;
else
hcnt <= "000000000";
end if;
end if;
end process;
B: process(hsyncb,reset)
begin
-- reset asynchronously clears line counter
if reset='1' then
vcnt <= "0000000000";
-- vert. line counter increments after every horiz. line
elsif (hsyncb'event and hsyncb='1') then
-- vert. line counter rolls-over after 528 lines
if vcnt<527 then
vcnt <= vcnt + 1;
else
vcnt <= "0000000000";
end if;
end if;
end process;
C: process(clock,reset)
begin
-- reset asynchronously sets horizontal sync to inactive
if reset='1' then
hsyncb <= '1';
-- horizontal sync is recomputed on the rising edge of every dot clock
elsif (clock'event and clock='1') then
-- horiz. sync is low in this interval to signal start of a new line
if (hcnt>=291 and hcnt<337) then
hsyncb <= '0';
else
hsyncb <= '1';
end if;
end if;
end process;
D: process(hsyncb,reset)
begin
-- reset asynchronously sets vertical sync to inactive
if reset='1' then
vsyncb <= '1';
-- vertical sync is recomputed at the end of every line of pixels
elsif (hsyncb'event and hsyncb='1') then
-- vert. sync is low in this interval to signal start of a new frame
if (vcnt>=490 and vcnt<492) then
vsyncb <= '0';
else
vsyncb <= '1';
end if;
end if;
end process;
-- blank video outside of visible region: (0,0) -> (255,479)
E: blank <= '1' when (hcnt>=256 or vcnt>=480) else '0';
-- store the blanking signal for use in the next pipeline stage
F: process(clock,reset)
begin
if reset='1' then
pblank <= '0';
elsif (clock'event and clock='1') then
pblank <= blank;
end if;
end process;
-- video RAM control signals
G:
csb <= '0'; -- enable the RAM
web <= '1'; -- disable writing to the RAM
oeb <= blank; -- enable the RAM outputs when video is not blanked
-- The video RAM address is built from the lower 9 bits of the vertical
-- line counter and bits 7-2 of the horizontal pixel counter.
-- Each byte of the RAM contains four 2-bit pixels. As an example,
-- the byte at address ^h1234=^b0001,0010,0011,0100 contains the pixels
-- at (row,col) of (^h048,^hD0),(^h048,^hD1),(^h048,^hD2),(^h048,^hD3).
H: addr <= vcnt(8 downto 0) & hcnt(7 downto 2);
I: process(clock,reset)
begin
-- clear the pixel register on reset
if reset='1' then
pixrg <= "00000000";
-- pixel clock controls changes in pixel register
elsif (clock'event and clock='1') then
-- the pixel register is loaded with the contents of the video
-- RAM location when the lower two bits of the horiz. counter
-- are both zero. The active pixel is in the lower two bits
-- of the pixel register. For the next 3 clocks, the pixel
-- register is right-shifted by two bits to bring the other
-- pixels in the register into the active position.
if hcnt(1 downto 0)="00" then
pixrg <= data; -- load 4 pixels from RAM
else
pixrg <= "00" & pixrg(7 downto 2); -- right-shift pixel register
end if;
end if;
end process;
-- the color mapper translates each 2-bit pixel into a 6-bit
-- color value. When the video signal is blanked, the color
-- is forced to zero (black).
J: process(clock,reset)
begin
-- blank the video on reset
if reset='1' then
rgb <= "000000";
-- update the color outputs on every dot clock
elsif (clock'event and clock='1') then
-- map the pixel to a color if the video is not blanked
if pblank='0' then
case pixrg(1 downto 0) is
when "00" => rgb <= "110000"; -- red
when "01" => rgb <= "001100"; -- green
when "10" => rgb <= "000011"; -- blue
when others => rgb <= "111111"; -- white
end case;
-- otherwise, output black if the video is blanked
else
rgb <= "000000"; -- black
end if;
end if;
end process;
end vgacore_arch;