Estoy intentando leer desde la ROM y mostrar los datos en el monitor VGA. He verificado que la ROM es funcional y funciona bien. Pero lo que obtengo en la pantalla es un patrón repetido de RGB. No son esos datos que están en la ROM.
Aquí está mi ROM:
------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
library work;
------------------------------------------------------------------
ENTITY rom IS
PORT (clk: IN STD_LOGIC;
address: IN INTEGER RANGE 0 to 2**15;
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END rom;
------------------------------------------------------------------
ARCHITECTURE rom OF rom IS
SIGNAL reg_address: INTEGER RANGE 0 to 2**15;
TYPE memory IS ARRAY (0 TO 15) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
CONSTANT myrom: memory := (
0=> "00000000", -- 0
1=> "00000000", -- 1
2=> "00010000", -- 2 *
3=> "00111000", -- 3 ***
4=> "01101100", -- 4 ** **
5=> "11000110", -- 5 ** **
6=> "11000110", -- 6 ** **
7=> "11111110", -- 7 *******
8=> "11000110", -- 8 ** **
9=> "11000110", -- 9 ** **
10=> "11000110", -- a ** **
11=> "11000110", -- b ** **
12=> "00000000", -- c
13=> "00000000", -- d
14=> "00000000", -- e
15=> "00000000", -- f
OTHERS => "00000000");
BEGIN
--Register the address:----------
PROCESS (clk)
BEGIN IF (clk'EVENT AND clk='1') THEN
reg_address <= address;
END IF;
END PROCESS;
--Get unregistered output:-------
data_out <= myrom(reg_address);
END rom;
PANTALLA VGA
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity VGA_display is
port (
-- Assuming 50MHz clock.If the clock is reduced then it might give the unexpected output.
clock: in std_logic;
-- The counter tells whether the correct position on the screen is reached where the data is to be displayed.
hcounter: in integer range 0 to 1023;
vcounter: in integer range 0 to 1023;
-- Output the colour that should appear on the screen.
pixels : out std_logic_vector(7 downto 0)
);
end VGA_display;
architecture Behavioral of VGA_display is
-- Intermediate register telling the exact position on display on screen.
signal x : integer range 0 to 1023 := 100;
signal y : integer range 0 to 1023 := 80;
signal addr: INTEGER RANGE 0 TO 15;
signal pix: STD_LOGIC_VECTOR(7 DOWNTO 0);
-- Clock period definitions
constant Clk_period : time := 10 ns;
begin
rom1: entity work.rom port map(address => addr, data_out => pix, clk => clock);
-- On every positive edge of the clock counter condition is checked,
output1: process(clock)
begin
if rising_edge (clock) then
-- If the counter satisfy the condition, then output the colour that should appear.
if (hcounter >= 1) and (hcounter < 128) and (vcounter >= 1) and (vcounter < 128
) then
addr <= vcounter * 128 + hcounter;
pixels <= pix;
-- If the condition is not satisfied then the output colour will be black.
else
pixels <= x"00";
end if;
end if;
end process;
end Behavioral;
Entidad TOP
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library work;
entity VGA_sync is
Port ( Clk : in STD_LOGIC;
hsync : out STD_LOGIC;
vsync : out STD_LOGIC;
Red : out STD_LOGIC_VECTOR (2 downto 0);
Green : out STD_LOGIC_VECTOR (2 downto 0);
Blue : out STD_LOGIC_VECTOR (2 downto 1)
);
end VGA_sync;
architecture Behavioral of VGA_sync is
-- Intermediate register used internally
signal clock: std_logic := '0';
-- Internal register to store the colour required
signal rgb: std_logic_vector(7 downto 0);
-- Set the resolution of the frame - 640 x 480
signal hCount: integer range 0 to 1023 := 640;
signal vCount: integer range 0 to 1023 := 480;
-- Set the count from where it should start
signal nextHCount: integer range 0 to 1023 := 641;
signal nextVCount: integer range 0 to 1023 := 480;
begin
-- Divide the clock from 100 MHz to 50 MHz
divideClock: process(Clk)
begin
if rising_edge (Clk) then
clock <= not clock;
end if;
end process;
-- create a file which contains the code which causes something to be displayed.
-- The clock which should be given here is 50MHz
VGA_display: entity work.VGA_display
port map(
clock => clock,
hcounter => nextHCount,
vcounter => nextVCount,
pixels => rgb
);
-- The process is carried out for every positive edge of the clock i.e, 50 MHz clock(clock).
vgasignal: process(clock)
variable divide_by_2 : std_logic := '0';
begin
-- Make sure the process begins at the correct point between sync pulses
if rising_edge(clock) then
-- Further divide down the clock from 50 MHz to 25 MHz
if divide_by_2 = '1' then
-- Has an entire scanline been displayed?
if(hCount = 799) then
hCount <= 0;
-- Has an entire frame been displayed?
if(vCount = 524) then
vCount <= 0;
else
vCount <= vCount + 1;
end if;
else
hCount <= hCount + 1;
end if;
-- Once the Hcounter has reached the end of the line we reset it to zero
if (nextHCount = 799) then
nextHCount <= 0;
-- Once the frame has been displayed then reset the Vcounter to zero
if (nextVCount = 524) then
nextVCount <= 0;
else
nextVCount <= vCount + 1;
end if;
else
nextHCount <= hCount + 1;
end if;
-- Check if the Vcount is within the minimum and maximum value for the vertical sync signal
if (vCount >= 490 and vCount < 492) then
vsync <= '0';
else
vsync <= '1';
end if;
-- Check if the Hcount is within the minimum and maximum value for the horizontal sync signal
if (hCount >= 656 and hCount < 752) then
hsync <= '0';
else
hsync <= '1';
end if;
-- If the Vcounter and Hcounter are within 640 and 480 then display the pixels.
if (hCount < 640 and vCount < 480) then
--this section of code will cause the display to be Red
Red <= rgb (7 downto 5);
Green <= rgb (4 downto 2);
Blue <= rgb (1 downto 0);
end if;
end if;
-- Set divide_by_2 to zero
divide_by_2 := not divide_by_2;
end if;
end process;
end Behavioral;