Generieren Sie Videos mit ZYNQ unter Verwendung des IP-Blockdesigns?

Ich versuche, einen Video-Streamer auf einem Digilent ZYBO-Board mit Xilinx ZYNQ 7010 zu implementieren. Der Grund dafür ist übrigens, die Qualität eines Encoder-Boards zu testen. Was ich möchte ist:

  • Generieren Sie einen RAM- Block, um vordefinierte Videodaten zu speichern.
  • Streamen Sie den Inhalt von Pmod-Anschlüssen (wahrscheinlich mit dem Block AXI4-Stream Video Out ) mit DMA .

Videofunktionen sind: 1024 x 768, 720p, 30fps vorerst. Eventuell muss ich sie später ändern.

Ich habe ein Design im Internet gefunden ( siehe Abbildung unten ). Aber da es ein zufälliges Video generiert, muss ich den Test Pattern Generator-Block ändern (ich meine, ihn durch einige andere Blöcke ersetzen), aber ich habe keine Ahnung, wie. Welche Art von Designprozess sollte ich befolgen? Ich habe nur begrenzte Zeit und Kenntnisse über Blockdesign und HDLs, daher ist jede Hilfe willkommen.

Geben Sie hier die Bildbeschreibung ein

Die einfache Antwort ist, den Video-Sample-Generator durch Ihr eigenes Modul zu ersetzen, das ein einfaches Bild generiert, dafür müssen Sie das Format des Streaming-Videos kennen, das gut dokumentiert ist. Ich fürchte, es gibt keinen anderen Weg, als ein anderes Modul zu finden, das genau dasselbe tut, was Sie tun möchten.
Schauen Sie sich xilinx.com/products/intellectual-property/tpg.html an , dort finden Sie genau das, wonach Sie suchen
@ FarhadA Ich habe gerade überprüft, was Sie vorgeschlagen haben. Aber ich habe keine Volllizenz und es scheint, dass es obligatorisch ist, den Video Test Pattern Generator zu verwenden.
Verwenden Sie WebPack? denn so steht es im Lizenzabschnitt des IP: Lizenzierungs- und Bestellinformationen Dieses Xilinx® LogiCORE™ IP-Modul wird gemäß den Bedingungen der Xilinx Core-Lizenzvereinbarung kostenlos zur Verfügung gestellt. Das Modul wird als Teil der Vivado Design Suite ausgeliefert. Für vollen Zugriff auf alle Kernfunktionalitäten in der Simulation und in der Hardware müssen Sie eine kostenlose Lizenz für den Kern anfordern. Wenden Sie sich an Ihren örtlichen Xilinx-Vertriebsmitarbeiter, um Informationen zu Preisen und Verfügbarkeit zu erhalten.
Ich habe gerade mein WEBPACK Vivado 2015.01 überprüft und es hat das Modul "Test Pattern Generator" (das Sie in Ihrem Block haben) in der Lizenz enthalten. Wenn Sie auf die IP doppelklicken, können Sie die Parameter der IP ändern und erhalten, wonach Sie suchen.

Antworten (1)

Ich habe dieses TPG für ein Projekt von mir geschrieben. Vielleicht kann es dir helfen. Erstellen Sie ein neues Vivado-Projekt. Importieren Sie den Code und generieren Sie eine IP. Jetzt können Sie es in unser Projekt importieren.

Die Ausgabe ist Roh-Bayer, kann aber problemlos zur Ausgabe von RBG oder YUV übernommen werden.

-------------------------------------------------------------------------------
-- 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;