eficiencia y velocidad en el procesamiento de imágenes con FPGA

0

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.

    
pregunta OnurTR

1 respuesta

2

Antes de embarcarme en algo como la salida VGA y el "procesamiento de imágenes", le recomiendo encarecidamente comenzar con cosas simples primero, para asegurarse de que sus relojes entren en bloques lógicos y que las salidas estén conectadas correctamente y configuradas / asignadas. p>

Comience con un simple contador de n bits, de modo que el MSB esté alternando a 1 segundo. Y conecte esta salida a cualquier LED disponible en la placa del desarrollador. De esta manera, aprenderá el proceso de síntesis-enrutamiento de mapas, si funciona y cómo funciona.

Para un proyecto VGA, proceda con un búfer simple, rellénelo con algún patrón y haga que su proceso de escaneo VGA de filas / columnas emita las señales adecuadas al puerto VGA, asegurando toda la sincronización necesaria. Sin "procesamiento de imagen" o generación / movimiento del cursor.

Solo si dominas estas cosas básicas, puedes comenzar a desarrollar bloques de "procesamiento de imágenes" en la parte superior de este búfer.

    
respondido por el Ale..chenski

Lea otras preguntas en las etiquetas