📄 vgamem.vhd
字号:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity vgamem is
port
(
reset: in std_logic; -- reset
clock: in std_logic; -- VGA dot clock
hsyncb: buffer std_logic; -- horizontal (line) sync
vsyncb: buffer std_logic; -- vertical (frame) sync
addr: out std_logic_vector(19 downto 0); -- address into video RAM
oeb: out std_logic; -- video RAM output enable
web: out std_logic; -- video RAM write enable
pixelclk : out std_logic;
pblank : out std_logic;
imwidth, imheight : in std_logic_vector(9 downto 0)
);
end vgamem;
architecture vgamem_arch of vgamem is
signal hcnt: std_logic_vector(9 downto 0); -- horizontal pixel counter
signal vcnt: std_logic_vector(9 downto 0); -- vertical line counter
signal blank: std_logic; -- pipelined video blanking signal
signal blankwidth, blankheight, leftedge, rightedge,
topedge, bottomedge : std_logic_vector(9 downto 0);
signal curraddr : std_logic_vector(19 downto 0);
signal outofbound : std_logic;
begin
pixelclk <= clock;
A: process(clock,reset)
begin
-- reset asynchronously clears pixel counter
if reset='1' then
hcnt <= (others => '0');
-- horiz. pixel counter increments on rising edge of dot clock
elsif (clock'event and clock='1') then
if hcnt < 800 then
hcnt <= hcnt + 1;
else
hcnt <= (others => '0');
end if;
end if;
end process;
B: process(hsyncb,reset)
begin
-- reset asynchronously clears line counter
if reset='1' then
vcnt <= (others => '0');
-- vert. line counter increments after every horiz. line
elsif (hsyncb'event and hsyncb='1') then
if vcnt < 525 then
vcnt <= vcnt + 1;
else
vcnt <= (others => '0');
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 >= 659 and hcnt < 755) 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 >= 493 and vcnt < 495) then
vsyncb <= '0';
else
vsyncb <= '1';
end if;
end if;
end process;
-- blank video outside of visible region: (0,0) -> (479,639)
E: blank <= '1' when (hcnt >= 640 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 <= not blank;
end if;
end process;
-- video RAM control signals
G:
web <= '1'; -- disable writing to the RAM
oeb <= '0'; -- always enable the RAM outputs
H:
blankwidth <= 640 - imwidth;
leftedge <= "0" & blankwidth(9 downto 1);
rightedge <= leftedge + imwidth - 1;
blankheight <= 480 - imheight;
topedge <= "0" & blankheight(9 downto 1);
bottomedge <= topedge + imheight - 1;
process (hcnt, vcnt, reset)
begin
if (reset = '1') then
outofbound <= '1';
elsif (hcnt < leftedge or hcnt > rightedge or
vcnt < topedge or vcnt > bottomedge) then
outofbound <= '1';
else
outofbound <= '0';
end if;
end process;
with outofbound select
addr <= x"80000" when '1',
curraddr when others;
process(hcnt, reset)
begin
if (reset = '1' or vsyncb = '0') then
curraddr <= x"80000";
elsif (outofbound = '0') then
curraddr <= curraddr + 1;
end if;
end process;
end vgamem_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -