📄 anc_insert.vhd
字号:
end if;
when others =>
next_state <= S_WAIT;
end case;
end process;
--
-- FSM: outputs
--
-- This block decodes the current state to generate the various outputs of
-- the FSM.
--
process(current_state, overwrite)
begin
-- Unless specifically assigned in the case statement, all FSM outputs
-- default to the values here.
send_pkt_int <= '0';
abort_pkt_int <= '0';
ld_udw_cntr <= '0';
set_hanc <= '0';
set_vanc <= '0';
mod_space_avail <= '0';
case current_state is
when S_EAV1 =>
set_hanc <= '1';
when S_SAV1 =>
set_vanc <= '1';
when S_SND1 =>
send_pkt_int <= '1';
when S_ABRT =>
abort_pkt_int <= '1';
when S_ADF1 =>
send_pkt_int <= '1';
when S_DC =>
ld_udw_cntr <= '1';
when S_DID =>
abort_pkt_int <= not overwrite;
mod_space_avail <= '1';
when others =>
end case;
end process;
--
-- hanc flip-flop
--
-- The hanc flip-flop is asserted at the beginning of each HANC space and
-- negated at the beginning of each VANC space by the FSM. The space_avail
-- calculations use the hanc signal to determine the amount of available
-- space left.
--
process(clk,rst)
begin
if (rst = '1') then
hanc <= '0';
elsif (clk'event and clk = '1') then
if (ce = '1') then
if (set_hanc = '1') then
hanc <= '1';
elsif (set_vanc = '1') then
hanc <= '0';
end if;
end if;
end if;
end process;
--
-- UDW counter
--
-- The FSM uses the UDW counter to find the end of each ANC packet in the
-- input video stream. The FSM loads the UDW counter from the DC word of the
-- packet. A MUX feeds the decrement circuit which, in turn, feeds the
-- counter register. The MUX selects between the DC word from the input
-- video stream or the current contents of the UDW counter register. The
-- output of the MUX is also connected to a comparator that asserts the
-- udw_cntr_eq_0 when either the DC word or the UDW counter, depending on
-- which the MUX selects, is equal to zero.
--
-- This structure allows the use of one decrementer and one comparator for
-- both the DC word and the UDW counter itself.
--
udw_cntr_mux <= vid_in(7 downto 0) when ld_udw_cntr = '1' else udw_cntr;
udw_cntr_eq_0 <= '1' when udw_cntr_mux = UBYTE_ZERO else '0';
process(clk, rst)
begin
if (rst = '1') then
udw_cntr <= (others => '0');
elsif (clk'event and clk = '1') then
if (ce = '1') then
udw_cntr <= ubyte_type(std_logic_vector(udw_cntr_mux) - 1);
end if;
end if;
end process;
--
-- switching signal generator
--
-- The switching signal indicates when the current area is part of the keep-
-- out area where ANC packets should not be inserted in order to avoid
-- interference from synchronous switching events. The keep-out area begins
-- with the SAV starting the active portion of the switching line and ends
-- with the SAV on the next line.
--
-- The video decoder provides a signal called switch_line that becomes
-- asserted on the first word of the active portion of a switching line.
-- However, the switch_line signal from the video_decoder doesn't negate
-- soon enough for the purposes of this module. So, a done_switching signal
-- is generated that negates the switching signal even when switch_line is
-- still asserted. The done_switching signal becomes asserted at the
-- beginning of an SAV symbol when switch_line is also asserted.
--
-- Note that the en_sync_switch input to the video decoder disables the
-- switch_line output. Thus, if synchronous switching support is disabled in
-- the video decoder, ANC packets may be inserted in the sync switching
-- keep-outarea.
--
process(clk, rst)
begin
if (rst = '1') then
done_switching <= '0';
elsif (clk'event and clk = '1') then
if (ce = '1') then
if (sav_next = '1') then
done_switching <= switch_line;
end if;
end if;
end if;
end process;
switching <= switch_line and not done_switching;
--
-- space_avail signal generator
--
-- The space_avail signal is asserted if the space remaining in the current
-- ANC space is sufficient to allow a packet of the size specified by
-- pkt_size to be inserted.
--
-- The calculation takes into account the current video standard as
-- specified by the std code. The sizes of the ANC spaces are dictated by
-- the video standard.
--
-- The hanc signal indicates whether the current ANC space is HANC or VANC.
--
-- If the hanc signal is asserted, the calculation must also consider
-- whether the current line should have an EDH packet at the end of the HANC
-- space. If so, the space available for insertion of a new packet must be
-- reduced by the size of an EDH packet.
--
-- Finally, when overwriting an end marker packet, the space available
-- calculations are altered slightly. Since the decision about whether to
-- insert the packet during overwrites doesn't occur until the DID word, the
-- first three words of the packet have already been sent, so the packet
-- size is reduced by 3.
--
--
-- This code determines the size of HANC and VANC space for the current
-- video standard. It also determines the the line number in each field
-- where the EDH packet occurs.
--
process(std)
begin
case std is
when NTSC_422 =>
hanc_end <= SAV_NTSC_422;
vanc_end <= EAV_LOC_NTSC_422;
f1_edh_line <= NTSC_FLD1_EDH_LINE;
f2_edh_line <= NTSC_FLD2_EDH_LINE;
when NTSC_422_WIDE =>
hanc_end <= SAV_NTSC_422_WIDE;
vanc_end <= EAV_LOC_NTSC_422_WIDE;
f1_edh_line <= NTSC_FLD1_EDH_LINE;
f2_edh_line <= NTSC_FLD2_EDH_LINE;
when NTSC_4444 =>
hanc_end <= SAV_NTSC_4444;
vanc_end <= EAV_LOC_NTSC_4444;
f1_edh_line <= NTSC_FLD1_EDH_LINE;
f2_edh_line <= NTSC_FLD2_EDH_LINE;
when PAL_422 =>
hanc_end <= SAV_PAL_422;
vanc_end <= EAV_LOC_PAL_422;
f1_edh_line <= NTSC_FLD1_EDH_LINE;
f2_edh_line <= NTSC_FLD2_EDH_LINE;
when PAL_422_WIDE =>
hanc_end <= SAV_PAL_422_WIDE;
vanc_end <= EAV_LOC_PAL_422_WIDE;
f1_edh_line <= NTSC_FLD1_EDH_LINE;
f2_edh_line <= NTSC_FLD2_EDH_LINE;
when PAL_4444 =>
hanc_end <= SAV_PAL_4444;
vanc_end <= EAV_LOC_PAL_4444;
f1_edh_line <= NTSC_FLD1_EDH_LINE;
f2_edh_line <= NTSC_FLD2_EDH_LINE;
when others =>
hanc_end <= SAV_NTSC_422;
vanc_end <= EAV_LOC_NTSC_422;
f1_edh_line <= NTSC_FLD1_EDH_LINE;
f2_edh_line <= NTSC_FLD2_EDH_LINE;
end case;
end process;
--
-- This code block generates the space_end value. This value gives the
-- position of the end of the current ANC space. The space_end value is
-- assigned to the hanc_end or vanc_end values generated above. If an EDH
-- packet occurs on the current line and the HANC space is the current
-- space, the end of the HANC space is moved up by the size of the EDH
-- packet to prevent overwritting the EDH packet space.
--
process(edh_line, hanc, hanc_end, vanc_end)
begin
if (hanc = '1') then
if (edh_line = '1') then
space_end <= hanc_end - EDH_PKT_LENGTH;
else
space_end <= hanc_end;
end if;
else
space_end <= vanc_end;
end if;
end process;
--
-- These two statements generate the edh_line signal. This signal is
-- asserted when the current line contains the locatino of an EDH packet.
--
fx_edh_line <= f1_edh_line when field = '1' else f2_edh_line;
edh_line <= '1' when vert_count = fx_edh_line else '0';
--
-- These statements do the actual space_avail calculations. The free_space
-- value always reflects the amount of space from the current position to
-- the end of the current ANC space. The mod_pkt_size value is normally
-- equal to the pkt_size, but will be three less if the FSM indicates that
-- an end-marker overwrite is potentially occuring (by sasserteing
-- mod_space_avail). The pad_pkt_size is the mod_pkt_size value padded with
-- zeros on the MSBs to make it the same width as the horizontal position
-- value. Finally, the space_avail signal is generated by comparing the
-- pad_pkt_size value to the free_space value.
--
process(pkt_size, mod_space_avail)
begin
if (mod_space_avail = '1') then
mod_pkt_size <= pktsize_type(std_logic_vector(pkt_size) - 3);
else
mod_pkt_size <= pkt_size;
end if;
end process;
free_space <= space_end - horz_count;
pad_pkt_size <= hpos_type(("000" & mod_pkt_size));
space_avail <= '1' when pad_pkt_size <= free_space else '0';
--
-- start_marker and end_marker decoders
--
-- These statements decode the DID word of ANC packets in the video stream
-- to determine if they are start-marker or end-marker packets.
--
start_marker <= '1' when vid_in(7 downto 0) = START_MARKER_DID else '0';
end_marker <= '1' when vid_in(7 downto 0) = END_MARKER_DID else '0';
--
-- overwrite signal
--
-- This signal is asserted when the DID word of the ANC packet in the video
-- stream is an end_marker and there is enough space available to insert the
-- new packet (space_avail asserted). This signal tells the FSM to overwrite
-- the end-marker packet.
--
overwrite <= end_marker and space_avail;
--
-- video output MUX
--
-- This statement generates a MUX to drive the vid_out port. This MUX
-- selects between the input video stream (vid_in) or the new ANC packet
-- (anc_in). The MUX, by default, selects the vid_in data to send to
-- vid_out. However, when the FSM assertst the send_pkt signal (only
-- asserted for one state), the MUX outputs the anc_in data. The send_pkt
-- signal is captured in a flip-flop called pkt_out. The pkt_out signal
-- remains asserted until the end of the new ANC packet is reached, or the
-- packet send is aborted. Because the pkt_out signal is synchronous to the
-- clock signal, the MUX is controlled not only by pkt_out but also directly
-- by the various signals that affect the pkt_out signal so that the MUX
-- will switch the cycle before pkt_out changes.
--
process(switching, abort_pkt_int, pkt_out, send_pkt_int, anc_in, vid_in)
begin
if (switching = '0' and abort_pkt_int = '0' and
(pkt_out = '1' or send_pkt_int = '1')) then
vid_out <= anc_in;
else
vid_out <= vid_in;
end if;
end process;
process(clk, rst)
begin
if (rst = '1') then
pkt_out <= '0';
elsif (clk'event and clk = '1') then
if (ce = '1') then
if (send_pkt_int = '1') then
pkt_out <= '1';
elsif (pkt_end = '1' or switching = '1' or abort_pkt_int = '1') then
pkt_out <= '0';
end if;
end if;
end if;
end process;
abort_pkt <= abort_pkt_int;
send_pkt <= send_pkt_int;
end synth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -