¿Generando video con ZYNQ, usando el diseño de bloque de IP?

Estoy tratando de implementar un transmisor de video en la placa Digilent ZYBO que tiene Xilinx ZYNQ 7010. Por cierto, la razón de esto es probar la calidad de una placa codificadora. Lo que quiero es:

  • Genere un bloque de RAM para almacenar datos de video predeterminados.
  • Transmita su contenido desde conectores Pmod (probablemente usando el bloque AXI4-Stream Video Out ), usando DMA .

Las funciones de video son: 1024x768, 720p, 30fps por ahora. Puede que tenga que cambiarlos más tarde.

He encontrado un diseño en la web ( verifique la figura a continuación ). Pero como genera video aleatorio, tengo que modificar (es decir, reemplazarlo con otros bloques) el bloque Test Pattern Generator, pero no tengo idea de cómo. ¿Qué tipo de proceso de diseño debo seguir? Tengo tiempo y conocimiento limitados sobre el diseño de bloques y HDL, por lo que se agradece cualquier ayuda.

ingrese la descripción de la imagen aquí

La respuesta simple es reemplazar el generador de muestra de video con su propio módulo, generando una imagen simple, para eso necesita conocer el formato de transmisión de video que está bien documentado. Me temo que no hay otra forma que encontrar otro módulo que haga exactamente lo mismo que tú quieres hacer.
Visite xilinx.com/products/intellectual-property/tpg.html , tiene exactamente lo que está buscando.
@FarhadA Acabo de verificar lo que sugirió. Pero no tengo una licencia completa y parece que es obligatorio usar Video Test Pattern Generator.
¿Está utilizando WebPack? porque esto es lo que dice en la sección de licencia de la IP: Información sobre licencias y pedidos Este módulo IP de Xilinx® LogiCORE™ se proporciona sin costo bajo los términos del Acuerdo de licencia de Xilinx Core. El módulo se envía como parte de Vivado Design Suite. Para tener acceso completo a todas las funcionalidades básicas en simulación y en hardware, debe solicitar una licencia gratuita para el núcleo. Comuníquese con su representante de ventas local de Xilinx para obtener información sobre precios y disponibilidad.
Acabo de revisar mi WEBPACK Vivado 2015.01 y tiene el módulo "Test Pattern Generator" (que tienes en tu bloque) incluido en la licencia. Si haces doble clic sobre la IP, podrás modificar los parámetros de la IP y obtener lo que buscas.

Respuestas (1)

Escribí este TPG para un proyecto mío. Puede que esto te ayude. Cree un nuevo Proyecto Vivado. Importa el código y genera una IP. Ahora puedes importarlo a nuestro proyecto.

La salida es Bayer sin procesar, pero se puede adoptar fácilmente para generar RBG o YUV.

-------------------------------------------------------------------------------
-- Entity:    testpattern_axi
-- Autor:     Reto Meier [mir3@bfh.ch]
-- Date:      2016.02.03
-- Project:   Gazelle
--
-- Description:
-- This test pattern generator makes a similar pattern as the camera would 
-- generate. It is allmost the same code as camera_testpattern, but as output
-- is not CIF but AXI
-------------------------------------------------------------------------------

library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;   
    use ieee.math_real.all;

package testpattern_axi_pkg is

    component testpattern_axi is
        generic(
            img_height: integer := 480;
            img_width: integer := 640;
            brake_line: integer := 100;
            brake_frame: integer := 500;
            brake_pre_frame: integer := 100;
            data_length: integer := 12
        );

        port(   
            clk: in std_logic;
            o_valid: out std_logic;
            o_user: out std_logic;
            o_last: out std_logic;
            o_ready: in std_logic;
            o_data: out std_logic_vector(data_length-1 downto 0)
        );
    end component testpattern_axi;

end package testpattern_axi_pkg;


-------------------------------------------------------------------------------
library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all; 
    use ieee.math_real.all;   

entity testpattern_axi is
    generic(
        img_height: integer := 480;
        img_width: integer := 640;
        brake_line: integer := 100;
        brake_frame: integer := 500;
        brake_pre_frame: integer := 100;
        data_length: integer := 16
    );

    port(   
        clk: in std_logic;
        o_valid: out std_logic;
        o_user: out std_logic;
        o_last: out std_logic;
        o_ready: in std_logic;
        o_data: out std_logic_vector(data_length-1 downto 0)
    );
end entity testpattern_axi;


-------------------------------------------------------------------------------
architecture rtl of testpattern_axi is

    constant cnt_max: integer := 32000;

    type state_type is (s_frame_brake, s_pre_frame_brake, s_line_brake, s_line);  --type of state machine. 

    type reg_type is record
        cnt: unsigned(integer(floor(log2(real(cnt_max)))) downto 0);
        cnt_lines: unsigned(integer(floor(log2(real(cnt_max)))) downto 0);
        r, g, b: std_logic;
        std_line: std_logic_vector(cnt_lines'range);
        std_cnt: std_logic_vector(cnt'range);
        state: state_type;
    end record reg_type;

    constant init_values: reg_type :=(   
        cnt => (others =>'0'),
        cnt_lines => (others=>'0'),
        r => '0', 
        g => '0',
        b => '0',
        std_line => (others =>'0'),
        std_cnt => (others =>'0'),
        state => s_frame_brake);

    signal r, rin: reg_type := init_values;


begin

    combinational: process(r, o_ready)
        variable v: reg_type;
    begin
        v := r;  

        if o_ready = '1' then
            v.cnt := v.cnt + 1;
        end if;

        -- make the brakes and lines
        case v.state is 
            when s_frame_brake =>
                if v.cnt = to_unsigned(brake_frame, v.cnt'length) then
                    v.state := s_pre_frame_brake;
                    v.cnt := to_unsigned(0, v.cnt'length);
                end if;

            when s_pre_frame_brake => 
                if v.cnt = to_unsigned(brake_pre_frame, v.cnt'length) then
                    v.state := s_line;
                    v.cnt := to_unsigned(0, v.cnt'length); 
                end if;

            when s_line => 
                if v.cnt = to_unsigned(img_width, v.cnt'length) then
                    v.cnt := to_unsigned(0, v.cnt'length);
                    if v.cnt_lines = to_unsigned(img_height-1, v.cnt_lines'length) then
                        v.state := s_frame_brake;
                        v.cnt_lines := to_unsigned(0, v.cnt_lines'length);
                    else
                        v.state := s_line_brake;
                        v.cnt_lines := v.cnt_lines + 1;
                    end if;
                end if;

            when s_line_brake => 
                if v.cnt = to_unsigned(brake_line, v.cnt'length) then
                    v.state := s_line;
                    v.cnt := to_unsigned(0, v.cnt'length);
                end if;

        end case;


        -- generate the color pattern according to the position in the line
        if v.cnt > to_unsigned(img_width/8*7-1,v.cnt'length) then
            v.r := '0';
            v.g := '0';
            v.b := '0';
        elsif v.cnt > to_unsigned(img_width/8*6-1,v.cnt'length) then
            v.r := '0';
            v.g := '0';
            v.b := '1';
        elsif v.cnt > to_unsigned(img_width/8*5-1,v.cnt'length) then
            v.r := '1';
            v.g := '0';
            v.b := '0';
        elsif v.cnt > to_unsigned(img_width/8*4-1,v.cnt'length) then
            v.r := '1';
            v.g := '0';
            v.b := '1';
        elsif v.cnt > to_unsigned(img_width/8*3-1,v.cnt'length) then
            v.r := '0';
            v.g := '1';
            v.b := '0';
        elsif v.cnt > to_unsigned(img_width/8*2-1,v.cnt'length) then
            v.r := '0';
            v.g := '1';
            v.b := '1';
        elsif v.cnt > to_unsigned(img_width/8*1-1,v.cnt'length) then
            v.r := '1';
            v.g := '1';
            v.b := '0';
        else
            v.r := '1';
            v.g := '1';
            v.b := '1';
        end if;

        -- generate the output
        case v.state is 
            when s_line => 
                o_valid <= '1';

                if v.cnt_lines = to_unsigned(0, v.cnt_lines'length) and 
                   v.cnt = to_unsigned(0, v.cnt'length) then
                    o_user <= '1';
                else
                    o_user <= '0';
                end if;

                if v.cnt = to_unsigned(img_width-1, v.cnt'length) then
                    o_last <= '1';
                else
                    o_last <= '0';
                end if;


                v.std_line := std_logic_vector(v.cnt_lines);
                v.std_cnt := std_logic_vector(v.cnt);

                if v.std_line(0) = '0' then
                    if v.std_cnt(0) = '0' then
                        if v.b = '1' then
                            o_data <= (others => '1');
                        else
                            o_data <= (others => '0');
                        end if;
                    else
                        if v.g = '1' then
                            o_data <= (others => '1');
                        else
                            o_data <= (others => '0');
                        end if;
                    end if;
                else
                    if v.std_cnt(0) = '0' then
                        if v.g = '1' then
                            o_data <= (others => '1');
                        else
                            o_data <= (others => '0');
                        end if;
                    else
                        if v.r = '1' then
                            o_data <= (others => '1');
                        else
                            o_data <= (others => '0');
                        end if;
                    end if;                
                end if;

            when others => 
                o_valid <= '0';
                o_user <= '0';
                o_last <= '0';
                o_data <= (others => '0');
        end case;

        rin <= v;
    end process combinational;




    sequential: process(clk) -- sequential process (not need to edit)
    begin
        if rising_edge(clk) then
            r <= rin;
        end if;
    end process sequential;

end architecture rtl;