📄 imagexlib_arch.vhd
字号:
end rtl;
-- ************************************************************************
-- *********************************************
-- *0003* Based 2D Line Buffer Macro
-- based_2d_linebuffer
--
-- *********************************************
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
use work.imagexlib_utils.all;
entity base_2d_linebuffer is
generic
(
data_width : integer := 8;
samples_per_line : integer := 1000;
no_of_lines : integer := 2 -- In order to make 2D filter....
);
port
(
ce : in std_logic;
wr_clk : in std_logic;
wr_en : in std_logic;
wr_rst : in std_logic;
data_in : in std_logic_vector((data_width - 1) downto 0);
rd_en : in std_logic;
rd_clk : in std_logic;
rd_rst : in std_logic;
data_out : out std_logic_vector_array((no_of_lines - 1) downto 0)
);
end base_2d_linebuffer;
architecture rtl of base_2d_linebuffer is
signal hi : std_logic := '1';
signal lo : std_logic := '0';
begin
lb1 : entity work.linebuffer
generic map
(
data_width => data_width,
samples_per_line => samples_per_line,
no_of_lines => no_of_lines,
feather_outputs => false
)
port map
(
ce => ce,
wr_clk => wr_clk,
wr_rst => wr_rst,
wr_en => wr_en,
data_in => data_in,
write_h_pointer => open,
last_wr_location => open,
rd_clk => rd_clk,
rd_rst => rd_rst,
rd_en => rd_en,
cascade_en => hi,
read_h_pointer => open,
last_rd_location => open,
data_out => data_out
);
end rtl;
-- ************************************************************************
-- *********************************************
-- *0004* Horizontal Pipe Macro
-- h_pipe
--
-- *********************************************
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
use work.imagexlib_utils.all;
entity h_pipe is
generic
(
num_h_taps : integer := 2; -- coefs must be an array of at least this length. Extra values in array are ignored.
data_width : integer := 8 -- input width = output width
);
port
(
ce : in std_logic;
clk : in std_logic;
data_in : in std_logic_vector((data_width - 1) downto 0);
shift_en : in std_logic;
data_out : out std_logic_vector_array((num_h_taps - 1) downto 0)
);
end h_pipe;
architecture rtl of h_pipe is
signal logic1 : std_logic := '1';
signal logic0 : std_logic := '0';
type hpipe_type is array(0 to (2*(num_h_taps - 1))) of std_logic_vector((data_width - 1) downto 0);
signal hpipe : hpipe_type;
signal d_h_pipe_enable : std_logic_vector(num_h_taps downto 0);
begin
d_h_pipe_enable(0) <= shift_en;
cascade_pipeline_enable : for i in 1 to num_h_taps generate
d_h_pipe_enable_line : process(clk)
begin
if (clk'event and clk = '1') then
if (ce = '1') then
d_h_pipe_enable(i) <= d_h_pipe_enable(i-1);
end if;
end if;
end process;
end generate;
-- Define location 0 as first input sample (or output of linebuffer).
hpipe(0) <= data_in;
data_out(0)((data_width - 1) downto 0) <= hpipe(0);
-- Every instance of '2' in this loop should really be a generic parameter.
pipe_shift : for i in 1 to (num_h_taps - 1) generate
pipes : process(clk)
begin
if (clk'event and clk = '1') then
if (ce = '1') then
hpipe((2*i)-1) <= hpipe((2*i) - 2);
if (d_h_pipe_enable(i+1) = '0') then
hpipe(2*i) <= hpipe((2*i)-1);
end if;
end if;
end if;
end process;
data_out(i)((data_width - 1) downto 0) <= hpipe(2*i);
end generate;
end rtl;
-- ************************************************************************
-- *0005* Multi-channel (interleaved) h-pipe Marco
-- mc_h_pipe
--
-- ************************************************************************
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
use work.imagexlib_utils.all;
entity mc_h_pipe is
generic
(
num_channels : integer := 2;
num_h_taps : integer := 2;
data_width : integer := 8
);
port
(
ce : in std_logic;
clk : in std_logic;
data_in : in std_logic_vector((data_width - 1) downto 0);
shift_en : in std_logic;
data_out : out std_logic_vector_array((num_h_taps - 1) downto 0)
);
end mc_h_pipe;
architecture rtl of mc_h_pipe is
signal logic1 : std_logic := '1';
signal logic0 : std_logic := '0';
type hpipe_type is array(((num_h_taps - 1)*(num_channels + 1)) downto 0) of std_logic_vector((data_width - 1) downto 0);
signal hpipe : hpipe_type;
signal d_h_pipe_enable : std_logic_vector(num_h_taps downto 0);
begin
d_h_pipe_enable(0) <= shift_en;
cascade_pipeline_enable : for i in 1 to num_h_taps generate
d_h_pipe_enable_line : process(clk)
begin
if (clk'event and clk = '1') then
if (ce = '1') then
d_h_pipe_enable(i) <= d_h_pipe_enable(i-1);
end if;
end if;
end process;
end generate;
-- Define location 0 as first input sample (or output of linebuffer).
hpipe(0) <= data_in;
data_out(0)((data_width - 1) downto 0) <= hpipe(0);
pipe_shift : for i in 0 to (num_h_taps - 2) generate
data_out(i+1)((data_width - 1) downto 0) <= hpipe((num_channels + 1)*(i+1)); -- Work from this principle.
-- Clock enable all but last location in pipe for each tap
enabled_pipeline_locations : for j in 0 to (num_channels - 1) generate
enabled_pipes : process(clk)
begin
if (clk'event and clk = '1') then
if (ce = '1') then
if (d_h_pipe_enable(i) = '1') then
hpipe((i*(num_channels + 1)) + j + 1) <= hpipe((i*(num_channels + 1)) + j);
end if;
end if;
end if;
end process;
end generate;
final_pipe_register : process(clk)
begin
if (clk'event and clk = '1') then
if (ce = '1') then
-- Final register in pipe is not enabled. This is effectively the pipeline register for each tap.
hpipe((num_channels + 1) * (i+1)) <= hpipe(((num_channels + 1) * (i+1)) - 1);
end if;
end if;
end process;
end generate;
end rtl;
-- ************************************************************************
-- *0006* Active picture timing delay unit
-- active_delay
--
--
-- For modules that take in standard form chroma, it is assumed that the din_valid
-- signal will always be aligned with a h_sync signal.
-- H-sync must be continuous, but din_valid must mark only the active lines.
-- All active lines must be contiguous within a field.
-- Even for 4:2:0, all active lines are marked with din_valid = 1
--
-- :
-- __________ __________ __________ :__________ __________
-- HS_IN | | | | | | | | | |
-- -- ---- ---- ---- ---- --
-- __________ __________ :__________
-- DIN_VALID | first | | | | last |
-- ---------------- ---- ----: -----------------
-- :
-- ************************************************************************
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
use work.imagexlib_utils.all;
entity active_delay is
generic
(
active_input_samples_per_line : integer := 1920;
v_delay : integer := 0;
h_delay : integer := 0;
input_chroma_format : integer := 0; -- 0 : 4:4:4; 1 : 4:2:2; 2 : 4:2:0
output_chroma_format : integer := 0
);
port
(
ce : in std_logic;
clk : in std_logic;
vs_in : in std_logic;
hs_in : in std_logic;
din_valid : in std_logic;
v_reset_out : out std_logic;
hs_out : out std_logic;
vs_out : out std_logic;
dout_valid : out std_logic;
chroma_420_line_valid : out std_logic
);
end active_delay;
architecture rtl of active_delay is
signal d_din_valid : std_logic;
signal d_hs_in : std_logic;
signal d_vs_in : std_logic;
signal d2_vs_in : std_logic;
signal vs_r_edge : std_logic;
constant h_count_width : integer := LOG2_BASE(2*active_input_samples_per_line);
signal input_sample_count : std_logic_vector((h_count_width-1) downto 0);
signal early_dout_valid : std_logic;
signal dout_valid_420_mask : std_logic;
signal dout_valid_mask : std_logic;
signal d_h_count_en : std_logic;
signal d_h_count : std_logic_vector((h_count_width-1) downto 0);
signal d_valid_data_window : std_logic_vector(v_delay downto 0);
signal d_vs : std_logic_vector(v_delay downto 0);
signal early_vs_out : std_logic;
begin
main_proc : process (clk)
begin
if (clk'event) and (clk = '1') then
if (ce = '1') then
d_din_valid <= din_valid;
d_hs_in <= hs_in;
d_vs_in <= vs_in;
d2_vs_in <= d_vs_in;
vs_r_edge <= d_vs_in and not(d2_vs_in);
v_reset_out <= d_vs_in and not(d2_vs_in);
-- Need to create a flag which acts as a window indicating the valid data in OUTPUT space,
-- but based upon what we see in the INPUT.
-- The window 'opens' when first high din_valid is found on hs_in rising edge.
-- For 4:4:4 and 4:2:2, the window 'closes' din_valid is low on a hs_in rising edge
-- This flag is generated in UNDELAYED space.
if (vs_r_edge = '1') then
d_valid_data_window(0) <= '0';
elsif ((hs_in = '1') and (d_hs_in = '0')) then -- rising edge of h_sync
if (din_valid = '1') then
d_valid_data_window(0) <= '1';
else
d_valid_data_window(0) <= '0';
end if;
end if;
-- Generate an un-offset h-sample count
if (vs_r_edge = '1') then
input_sample_count <= (others => '0');
elsif ((hs_in = '1') and (d_hs_in = '0')) then -- rising edge of h_sync
input_sample_count <= (others => '0');
else
input_sample_count <= input_sample_count + 1;
end if;
end if;
end if;
end process;
-- Delay the valid_data_window by the appropriate number of lines.
-- Also delay vs_in accordingly to give vs_out (horizontally undelayed).
d_vs(0) <= d_vs_in;
delay_valid_data_window : for i in 1 to (v_delay) generate
delay_line_count_proc : process (clk)
begin
if (clk'event) and (clk = '1') then
if (ce = '1') then
if ((hs_in = '0') and (d_hs_in = '1')) then
d_valid_data_window(i) <= d_valid_data_window(i-1);
d_vs(i) <= d_vs(i-1);
end if;
end if;
end if;
end process;
end generate;
decode_proc : process (clk)
begin
if (clk'event) and (clk = '1') then
if (ce = '1') then
if (vs_r_edge = '1') then
dout_valid <= '0';
early_dout_valid <= '0';
dout_valid_420_mask <= '1';
dout_valid_mask <= '1';
d_h_count <= (others => '0');
d_h_count_en <= '0';
vs_out <= '0';
else
if (input_sample_count = conv_std_logic_vector(h_delay-3, h_count_width)) then
early_dout_valid <= '1';
if (d_valid_data_window(v_delay) = '1') then
dout_valid_420_mask <= not(dout_valid_420_mask);
dout_valid_mask <= '0';
end if;
early_vs_out <= d_vs(v_delay);
d_h_count_en <= '1';
elsif (d_h_count = conv_std_logic_vector((active_input_samples_per_line - 1), h_count_width)) then
early_dout_valid <= '0';
dout_valid_mask <= '1';
d_h_count_en <= '0';
d_h_count <= (others => '0');
else
if (d_h_count_en = '1') then
d_h_count <= d_h_count + 1;
end if;
end if;
vs_out <= early_vs_out;
hs_out <= early_dout_valid;
chroma_420_line_valid <= early_dout_valid and not(dout_valid_mask) and not(dout_valid_420_mask);
dout_valid <= early_dout_valid and not(dout_valid_mask);
end if;
end if;
end if;
end process;
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -