Escribí este TPG para un proyecto mío.
Puede que esto te ayude. Crea un nuevo proyecto de vivado. Importa el código y genera una IP.
Ahora puedes importarlo en nuestro proyecto.
La salida es Bayer sin formato, pero se puede adoptar fácilmente para generar RBG o YUV.
-------------------------------------------------------------------------------
-- Entity: testpattern_axi
-- Autor: Reto Meier [[email protected]]
-- 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;