Hola, he estado escribiendo un código en VHDL para el procesamiento de algunas imágenes. Sin embargo, debido a algunas razones que todavía no he determinado, la síntesis no se detiene. Sospecho que la eficiencia del código no es tanto como lo necesito, lo que ralentiza el proceso de síntesis. Soy nuevo en el mundo del hardware y todavía estoy aprendiendo. Estoy usando la placa Basys3 y el entorno Vivado2017.2. Mi computadora no es vieja y funciona bien en términos de velocidad / potencia. ¿Cómo puedo reducir el tiempo de síntesis y alcanzar un resultado?
El código es complejo, pero estoy más complejo porque se agregarán funciones adicionales. Lo que hago es mover un marco en la imagen y, según la operación elegida, cambiar los píxeles dentro del marco.
Aquí está el código que escribí
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use IEEE.std_logic_unsigned.all;
use std.textio.all;
entity vga_core is
generic (
PICTURE_WIDTH_HEIGHT : integer := 250;
COLOR_BIT : integer := 4);
port (
default_clk : in std_logic := '0';
rst : in std_logic:= '0';
data_r : out std_logic_vector(COLOR_BIT-1 downto 0);
data_g : out std_logic_vector(COLOR_BIT-1 downto 0);
data_b : out std_logic_vector(COLOR_BIT-1 downto 0);
hs_out : out std_logic;
vs_out : out std_logic;
operation : in std_logic_vector(1 downto 0);
mode: in std_logic;
go_left : in std_logic;
go_right: in std_logic;
go_down: in std_logic;
go_up: in std_logic;
enable : in std_logic;
cursor_mode : in std_logic_vector(1 downto 0)
);
end vga_core;
architecture VGA of vga_core is
---------------------------------------------------------
---------CONSTANTS FOR VGA-------------------------------
---------------------------------------------------------
constant RES_H : integer := 640;
constant RES_V : integer := 480;
constant H_FRONT_PORCH : integer := 16;
constant H_SYNC_TIME : integer := 96;
constant H_BACK_PORCH : integer := 48;
constant V_FRONT_PORCH : integer := 11;
constant V_SYNC_TIME : integer := 2;
constant V_BACK_PORCH : integer := 31;
constant TOTAL_H : integer := RES_H + H_FRONT_PORCH + H_SYNC_TIME + H_BACK_PORCH; -- 800
constant TOTAL_V : integer := RES_V + V_FRONT_PORCH + V_SYNC_TIME + V_BACK_PORCH; -- 524
---------------------------------------------------------
constant LENGTH_1 : integer := PICTURE_WIDTH_HEIGHT;
constant LENGTH_2 : integer := 10;
constant LENGTH_3 : integer := 25;
constant LENGTH_4 : integer := 50;
signal length : integer range 0 to PICTURE_WIDTH_HEIGHT := LENGTH_1;
---------------------------------------------------------
----------------Signals used for VGA operations ---------
---------------------------------------------------------
signal COUNTER_H : integer range 0 to TOTAL_H := 0; -- 0 to 800
signal COUNTER_V : integer range 0 to TOTAL_V := 0; -- 0 to 524
signal NEW_LINE : std_logic := '0';
signal h_visible : std_logic := '0';
signal v_visible : std_logic := '0';
signal visible : std_logic := '0';
---------------------------------------------------------
------------------Clock things---------------------------
---------------------------------------------------------
signal clk : std_logic := '0';
signal temporal: std_logic := '0';
signal counter : integer range 0 to 1 := 0;
---------------------------------------------------------
--------Upper-left positions of the frame----------------
---------------------------------------------------------
signal cursor_pos_x : integer range 0 to PICTURE_WIDTH_HEIGHT := 0;
signal cursor_pos_y : integer range 0 to PICTURE_WIDTH_HEIGHT := 0;
---------------------------------------------------------
----------Positions of the pixels on the screen----------
---------------------------------------------------------
signal pos_x : integer range 0 to 2047 := 0;
signal pos_y : integer range 0 to 2047 := 0;
---------------------------------------------------------
signal vgaData : std_logic_vector(3*COLOR_BIT-1 downto 0) := "000000000000";
type RamType is array(0 to PICTURE_WIDTH_HEIGHT - 1, 0 to PICTURE_WIDTH_HEIGHT - 1) of bit_vector(11 downto 0);
--My ram is 2-dimensional by the way
impure function InitRamFromFile (RamFileName : in string) return RamType is
FILE RamFile : text is in RamFileName;
variable RamFileLine : line;
variable RAM : RamType;
begin
for y in 0 to 249 loop
for x in 0 to 249 loop
readline (RamFile, RamFileLine);
read (RamFileLine, RAM(x,y));
end loop;
end loop;
return RAM;
end function;
signal RAM : RamType := InitRamFromFile("\ASUS\Users\AsusPc\Desktop\project_son\pictureData.data");
begin
-- according to cursor mode, length is adjusted
with cursor_mode select length <=
LENGTH_1 when "00",
LENGTH_2 when "01",
LENGTH_3 when "10",
LENGTH_4 when "11";
--I obtain a clock signal with 25Mhz frequency
CLOCK_DIVIDER: process (default_clk) begin
if rising_edge(default_clk) then
if (counter = 1) then
temporal <= NOT(temporal);
counter <= 0;
else
counter <= counter + 1;
end if;
end if;
end process;
clk <= temporal;
---------------------------------------------------------
--------------VGA THINGS---------------------------------
---------------------------------------------------------
CNT_H : process (clk) is
begin
if clk'event and clk = '1' then
if (COUNTER_H = TOTAL_H-1) then
COUNTER_H <= 0;
NEW_LINE <= '1';
else
COUNTER_H <= COUNTER_H + 1;
NEW_LINE <= '0';
end if;
end if;
end process CNT_H;
CNT_V : process (clk) is
begin
if clk'event and clk = '1' then
if (NEW_LINE = '1') then
if (COUNTER_V = TOTAL_V-1) then
COUNTER_V <= 0;
else
COUNTER_V <= COUNTER_V + 1;
end if;
end if;
end if;
end process CNT_V;
SYNC_H : process (clk) is
begin
if clk'event and clk = '1' then
if (COUNTER_H < H_SYNC_TIME) then
hs_out <= '0';
else
hs_out <= '1';
end if;
end if;
end process SYNC_H;
SYNC_V : process (clk) is
begin
if clk'event and clk = '1' then
if (COUNTER_V < V_SYNC_TIME) then
vs_out <= '0';
else
vs_out <= '1';
end if;
end if;
end process SYNC_V;
AREA_H : process (clk, rst) is
begin
if clk'event and clk = '1' then
if (COUNTER_H > H_SYNC_TIME + H_BACK_PORCH - 1) and (COUNTER_H < TOTAL_H - H_FRONT_PORCH) then
h_visible <= '1';
if ((COUNTER_H - (H_SYNC_TIME + H_BACK_PORCH)) <641) then
pos_x <= COUNTER_H - (H_SYNC_TIME + H_BACK_PORCH);
end if;
else
h_visible <= '0';
end if;
end if;
end process AREA_H;
AREA_V : process (clk) is
begin
if clk'event and clk = '1' then
if (COUNTER_V > V_SYNC_TIME + V_BACK_PORCH - 1) and (COUNTER_V < TOTAL_V - V_FRONT_PORCH) then
v_visible <= '1';
if ((COUNTER_V - (V_SYNC_TIME + V_BACK_PORCH)) < 481) then
pos_y <= COUNTER_V - (V_SYNC_TIME + V_BACK_PORCH);
end if;
else
v_visible <= '0';
end if;
end if;
end process AREA_V;
visible <= h_visible and v_visible;
--------------------------------------------------------------
--------------------------------------------------------------
--------------------------------------------------------------
--Used to move the frame to left
GOING_LEFT: process (go_left, clk) is
begin
if rising_edge(clk) then
if go_left = '1' then
if (cursor_pos_x - length - 1 > 0) then
cursor_pos_x <= cursor_pos_x - length - 1;
else
cursor_pos_x <= 0;
end if;
end if;
end if;
end process GOING_LEFT;
--Used to move the frame to right
GOING_RIGHT: process (go_right, clk) is
begin
if rising_edge(clk) then
if go_right = '1' then
if (cursor_pos_x + length - 1 < PICTURE_WIDTH_HEIGHT) then
cursor_pos_x <= cursor_pos_x + length - 1;
else
cursor_pos_x <= PICTURE_WIDTH_HEIGHT - 1;
end if;
end if;
end if;
end process GOING_RIGHT;
--Used to move the frame up
GOING_UP: process (go_up, clk) is
begin
if rising_edge(clk) then
if go_up = '1' then
if (cursor_pos_y - length -1 > 0) then
cursor_pos_y <= cursor_pos_y - length - 1;
else
cursor_pos_y <= 0;
end if;
end if;
end if;
end process GOING_UP;
--Used to move the frame down
GOING_DOWN: process (go_down,clk) is
begin
if rising_edge(clk) then
if go_down = '1' then
if (cursor_pos_y + length - 1 < PICTURE_WIDTH_HEIGHT) then
cursor_pos_y <= cursor_pos_y + length - 1;
else
cursor_pos_y <= PICTURE_WIDTH_HEIGHT - length ;
end if;
end if;
end if;
end process GOING_DOWN;
--------------------------------------------------------------
--------------Most important part----------------------------
--------------------------------------------------------------
SHOW : process (clk, rst) is
begin
if rising_edge(clk) then --clk
if rst = '1' then --rst
RAM <= InitRamFromFile("\ASUS\Users\AsusPc\Desktop\project_son\pictureData.data");
cursor_pos_x <= 0;
cursor_pos_y <= 0;
elsif (visible = '1') and ( pos_x < PICTURE_WIDTH_HEIGHT) and (pos_y <PICTURE_WIDTH_HEIGHT) and (pos_x > -1) and (pos_y > -1) then
if((pos_y = cursor_pos_y) and ((pos_x > cursor_pos_x -1) or (pos_x < cursor_pos_x + length ))) or ((pos_y = cursor_pos_y + length -1) and ((pos_x > cursor_pos_x -1) or (pos_x < cursor_pos_x + length))) then --drawing the frame part 1
vgaData <= "000000000000"; --black
data_r <= vgaData(3*COLOR_BIT-1 downto 2*COLOR_BIT);
data_g <= vgaData(2*COLOR_BIT-1 downto COLOR_BIT);
data_b <= vgaData(COLOR_BIT-1 downto 0);
elsif ((pos_x = cursor_pos_x) and ((pos_y > cursor_pos_y - 1) or (pos_y < cursor_pos_y + length))) or ((pos_x = cursor_pos_x + length -1) and ((pos_y > cursor_pos_y - 1) or (pos_y < cursor_pos_y + length))) then --drawing the frame part 2
vgaData <= "000000000000"; --black
data_r <= vgaData(3*COLOR_BIT-1 downto 2*COLOR_BIT);
data_g <= vgaData(2*COLOR_BIT-1 downto COLOR_BIT);
data_b <= vgaData(COLOR_BIT-1 downto 0);
else
vgaData <= to_stdlogicvector(RAM(pos_x,pos_y));
data_r <= vgaData(3*COLOR_BIT-1 downto 2*COLOR_BIT);
data_g <= vgaData(2*COLOR_BIT-1 downto COLOR_BIT);
data_b <= vgaData(COLOR_BIT-1 downto 0);
end if;
if ((pos_x > PICTURE_WIDTH_HEIGHT - 1) and (pos_y > -1)) or ((pos_y > PICTURE_WIDTH_HEIGHT - 1) and ((pos_x > -1) or (pos_x < PICTURE_WIDTH_HEIGHT))) then
vgaData <= "000000001111"; -- blue
data_r <= vgaData(3*COLOR_BIT-1 downto 2*COLOR_BIT);
data_g <= vgaData(2*COLOR_BIT-1 downto COLOR_BIT);
data_b <= vgaData(COLOR_BIT-1 downto 0);
end if;
end if;
end if;
end process SHOW;
--Whenever cursor_mode changes, cursor positions are reset
ADJUSTING_cpx_and_cpy: process(cursor_mode) is
begin
cursor_pos_x <= 0;
cursor_pos_y <= 0;
end process;
BRIGHTNESS: process(enable,clk) is
begin
if rising_edge(clk) then
if enable = '1' then
if operation = "00" then
if ( pos_x > cursor_pos_x - 1) and (pos_x < cursor_pos_x + length) and ( pos_y > cursor_pos_y - 1) and (pos_y < cursor_pos_y + length) then -- condition
if mode = '0' then
if to_stdlogicvector(RAM(pos_x, pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) < 14 then
RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) + 2);
end if;
if to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) < 14 then
RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) + 2);
end if;
if to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) < 14 then
RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) + 2);
end if;
elsif mode = '1' then
if to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) > 1 then
RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) - 2);
end if;
if to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) > 1 then
RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) - 2);
end if;
if to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) > 1 then
RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) - 2);
end if;
end if; --mode
end if; --condition
end if; --operation
end if; --enable
end if; --clock
end process BRIGHTNESS;
CONTRAST: process(enable, clk) is
begin
if rising_edge(clk) then
if enable = '1' then
if operation = "01" then
if (pos_x > cursor_pos_x - 1) and (pos_x < cursor_pos_x + length) and ( pos_y > cursor_pos_y - 1) and (pos_y < cursor_pos_y + length) then -- condition
if mode = '0' then
if to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) < 8 and to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) > 1 then
RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) - 2);
elsif to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) > 7 and to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) < 14 then
RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) +2) ;
end if;
if to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) < 8 and to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) > 1 then
RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) - 2);
elsif to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) > 7 and to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) < 14 then
RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) +2) ;
end if;
if to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) < 8 and to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) > 1 then
RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) - 2);
elsif to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) > 7 and to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) < 14 then
RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) +2) ;
end if;
elsif mode = '1' then
if to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) < 8 and to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) > 2 then
RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) - 3);
elsif to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) > 7 and to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) < 13 then
RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(3*COLOR_BIT-1 downto 2*COLOR_BIT)) +3) ;
end if;
if to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) < 8 and to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) > 2 then
RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) - 3);
elsif to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) > 7 and to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) < 13 then
RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(2*COLOR_BIT-1 downto COLOR_BIT)) +3) ;
end if;
if to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) < 8 and to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) > 2 then
RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) - 3);
elsif to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) > 7 and to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) < 13 then
RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0) <= to_bitvector(to_stdlogicvector(RAM(pos_x,pos_y)(COLOR_BIT-1 downto 0)) + 3) ;
end if;
end if; --mode
end if; --condition
end if; --OPERATION
end if; --ENABLE
end if; --CLK
end process CONTRAST;
end VGA;
Lamentablemente, este código no me llevó a ningún lado.