📄 hdsdi_autodetect_ln.vhd
字号:
-- trs_to_counter
--
-- This timer will timeout if TRS symbols are not received on a periodic
-- basis, causing the trs_timeout signal to be asserted.
--
process(clk, reset)
begin
if reset = '1' then
trs_to_counter <= (others => '0');
elsif clk'event and clk = '1' then
if ce = '1' then
if eav = '1' or sav = '1' then
trs_to_counter <= (others => '0');
else
trs_to_counter <= trs_to_counter + 1;
end if;
end if;
end if;
end process;
trs_tc <= (others => '1');
trs_timeout <= '1' when trs_to_counter = trs_tc else '0';
--
-- line counter
--
-- The line counter counts the number of lines in a field or frame. The
-- first_timeout signal will be asserted if the line counter reaches terminal
-- count before the FSM clears the counter at the beginning of a new field or
-- frame.
--
process(clk, reset)
begin
if reset = '1' then
line_counter <= (others => '0');
elsif clk'event and clk = '1' then
if ce = '1' then
if clr_lcnt = '1' then
line_counter <= (others => '0');
elsif en_lcnt = '1' and eav = '1' then
line_counter <= line_counter + 1;
end if;
end if;
end if;
end process;
line_tc <= (others => '1');
first_timeout <= '1' when line_counter = line_tc else '0';
--
-- The timeout signal will be asserted if either trs_timeout or first_timeout
-- are asserted.
--
timeout <= trs_timeout or first_timeout;
--
-- error counter
--
-- The error counter is incremented by the FSM when an error is detected. When
-- the error counter reaches MAX_ERRCNT, the maxerrs signal will be asserted.
--
process(clk, reset)
begin
if reset = '1' then
errcnt <= (others => '0');
elsif clk'event and clk = '1' then
if ce = '1' then
if clr_errcnt = '1' then
errcnt <= (others => '0');
elsif inc_errcnt = '1' then
errcnt <= errcnt + 1;
end if;
end if;
end if;
end process;
maxerrs <= '1' when errcnt = MAX_ERRCNT else '0';
--
-- loop counter
--
-- The loop counter is a 4-bit binary up counter used by the FSM. It is used to
-- cycle through the word & line count values for each of the supported video
-- standards so that they can be compared to the values found in the input
-- video stream. The loops_tc signal is asserted when the loop counter reaches
-- its terminal count.
--
process(clk, reset)
begin
if reset = '1' then
loops <= (others => '0');
elsif clk'event and clk = '1' then
if ce = '1' then
if clr_loops = '1' then
loops <= (others => '0');
elsif inc_loops = '1' then
loops <= loops + 1;
end if;
end if;
end if;
end process;
loops_tc <= '1' when loops = LAST_VIDEO_FORMAT_CODE else '0';
--
-- std_int register
--
-- This register holds the detected video standard code.
--
process(clk, reset)
begin
if reset = '1' then
std_int <= (others => '0');
elsif clk'event and clk = '1' then
if ce = '1' then
if ld_std = '1' then
std_int <= loops;
end if;
end if;
end if;
end process;
std <= std_int;
--
-- video timing logic
--
-- The following logic generates various video timing signals:
--
-- v is the vertical blanking indicator bit and is only valid when eav or sav
-- are asserted. v is really just the vid_in[7] bit, but is reassigned to the
-- more descriptive v signal.
--
-- f is the field indicator bit and is only valid when eav or sav are asserted.
-- f is really just the vid_in[8] bit, but is reassigned to the more descriptive
-- f signal.
--
-- last_v is a register that holds the value of v from the last line. This
-- register loads whenever eav is asserted. It is used to detect the rising
-- edge of the V signal to generate the first_act signal.
--
-- first_act indicates the first active line of a field or frame.
--
v <= vid_in(7);
f <= vid_in(8);
process(clk, reset)
begin
if reset = '1' then
last_v <= '0';
elsif clk'event and clk = '1' then
if ce = '1' then
if eav = '1' then
last_v <= v;
end if;
end if;
end if;
end process;
process(clk, reset)
begin
if reset = '1' then
first_act <= '0';
elsif clk'event and clk = '1' then
if ce = '1' then
if eav = '1' then
first_act <= last_v and not v;
end if;
end if;
end if;
end process;
--
-- locked flip-flop
--
-- This flip flop is controlled by the finite state machine.
--
process(clk, reset)
begin
if reset = '1' then
locked_q <= '0';
elsif clk'event and clk = '1' then
if ce = '1' then
if clr_locked = '1' then
locked_q <= '0';
elsif set_locked = '1' then
locked_q <= '1';
end if;
end if;
end if;
end process;
locked <= locked_q;
--
-- comparison logic
--
-- The comparison logic is used to compare the word and line counts found in
-- the video stream against the known values for the various video standards.
-- To reduce the size of the implementation, the word and line counts are
-- compared sequentially against the known word and line counts using one
-- comparator for the words and one for the lines, rather than doing a parallel
-- comparison against all known values. The FSM controls this sequential search.
--
process(cmp_mux)
begin
case cmp_mux is
when HD_FMT_1035i_30 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2200, HD_HCNT_WIDTH));
when HD_FMT_1080i_25b => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2376, HD_HCNT_WIDTH));
when HD_FMT_1080i_30 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2200, HD_HCNT_WIDTH));
when HD_FMT_1080i_25 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2640, HD_HCNT_WIDTH));
when HD_FMT_1080p_30 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2200, HD_HCNT_WIDTH));
when HD_FMT_1080p_25 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2640, HD_HCNT_WIDTH));
when HD_FMT_1080p_24 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2750, HD_HCNT_WIDTH));
when HD_FMT_720p_60 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(1650, HD_HCNT_WIDTH));
when HD_FMT_1080sF_24 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2750, HD_HCNT_WIDTH));
when HD_FMT_720p_50 => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(1980, HD_HCNT_WIDTH));
when others => cmp_wcnt <= std_logic_vector(TO_UNSIGNED(2200, HD_HCNT_WIDTH));
end case;
end process;
process(cmp_mux)
begin
case cmp_mux is
when HD_FMT_1035i_30 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(517, HD_VCNT_WIDTH));
when HD_FMT_1080i_25b => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(540, HD_VCNT_WIDTH));
when HD_FMT_1080i_30 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(540, HD_VCNT_WIDTH));
when HD_FMT_1080i_25 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(540, HD_VCNT_WIDTH));
when HD_FMT_1080p_30 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(1080, HD_VCNT_WIDTH));
when HD_FMT_1080p_25 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(1080, HD_VCNT_WIDTH));
when HD_FMT_1080p_24 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(1080, HD_VCNT_WIDTH));
when HD_FMT_720p_60 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(720, HD_VCNT_WIDTH));
when HD_FMT_1080sF_24 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(540, HD_VCNT_WIDTH));
when HD_FMT_720p_50 => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(720, HD_VCNT_WIDTH));
when others => cmp_lcnt <= std_logic_vector(TO_UNSIGNED(540, HD_VCNT_WIDTH));
end case;
end process;
cmp_mux <= std_int when compare_sel = '1' else loops;
match_words <= '1' when word_counter = cmp_wcnt else '0';
match_lines <= '1' when line_counter = cmp_lcnt else '0';
match <= match_words and match_lines;
--
-- Finite state machine
--
process(clk, reset)
begin
if reset = '1' then
current_state <= ACQ0;
elsif clk'event and clk = '1' then
if ce = '1' then
if reacquire_sync = '1' then
current_state <= ACQ0;
else
current_state <= next_state;
end if;
end if;
end if;
end process;
process(current_state, sav, first_act, v, loops_tc, match, maxerrs, timeout, f)
begin
case current_state is
when ACQ0 =>
if sav = '1' and first_act = '1' then
next_state <= ACQ1;
else
next_state <= ACQ0;
end if;
when ACQ1 =>
if sav = '1' then
next_state <= ACQ2;
else
next_state <= ACQ1;
end if;
when ACQ2 =>
if sav = '1' and v = '1' then
next_state <= ACQ3;
else
next_state <= ACQ2;
end if;
when ACQ3 =>
next_state <= ACQ4;
when ACQ4 =>
if match = '1' then
next_state <= LCK0;
elsif loops_tc = '1' then
next_state <= ACQ0;
else
next_state <= ACQ4;
end if;
when LCK0 =>
if timeout = '1' then
next_state <= ERR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -