📄 edh_rx.vhd
字号:
when S_RSV6 =>
next_state <= S_RSV7;
when S_RSV7 =>
next_state <= S_CHK;
when S_CHK =>
if (checksum = vid_in(8 downto 0) and checksum(8) = not vid_in(9)) then
next_state <= S_WAIT;
else
next_state <= S_ERRC;
end if;
when S_ERRM =>
next_state <= S_WAIT;
when S_ERRF =>
next_state <= S_WAIT;
when S_ERRC =>
next_state <= S_WAIT;
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)
begin
-- Unless specifically assigned in the case statement, all FSM outputs
-- default to the values below.
ld_ap1 <='0';
ld_ap2 <='0';
ld_ap3 <='0';
ld_ff1 <='0';
ld_ff2 <='0';
ld_ff3 <='0';
ld_ap_flags <='0';
ld_ff_flags <='0';
ld_anc_flags <='0';
clr_checksum <='0';
clr_errors <='0';
missing_err <='0';
format_err <='0';
check_parity <='0';
checksum_err <='0';
case current_state is
when S_ADF1 => clr_errors <= '1';
when S_ADF3 => clr_checksum <= '1';
when S_AP1 => ld_ap1 <= '1';
check_parity <= '1';
when S_AP2 => ld_ap2 <= '1';
check_parity <= '1';
when S_AP3 => ld_ap3 <= '1';
check_parity <= '1';
when S_FF1 => ld_ff1 <= '1';
check_parity <= '1';
when S_FF2 => ld_ff2 <= '1';
check_parity <= '1';
when S_FF3 => ld_ff3 <= '1';
check_parity <= '1';
when S_ANCFLG => ld_anc_flags <= '1';
check_parity <= '1';
when S_APFLG => ld_ap_flags <= '1';
check_parity <= '1';
when S_FFFLG => ld_ff_flags <= '1';
check_parity <= '1';
when S_ERRM => missing_err <= '1';
when S_ERRF => format_err <= '1';
when S_ERRC => checksum_err <= '1';
when others =>
end case;
end process;
--
-- parity error detection
--
-- This code calculates the parity of bits 7:0 of the video word. The
-- calculated parity bit is compared to bit 8 and the complement of bit 9 to
-- determine if a parity error has occured. If a parity error is detected,
-- the parity_err signal is asserted. Parity is only valid on the payload
-- portion of the EDH packet (user data words).
--
parity <= vid_in(7) xor vid_in(6) xor vid_in(5) xor vid_in(4) xor
vid_in(3) xor vid_in(2) xor vid_in(1) xor vid_in(0);
parity_err <= (parity xor vid_in(8)) or (parity xor not vid_in(9));
--
-- checksum calculator
--
-- This code generates a checksum for the EDH packet. The checksum is
-- cleared to zero prior to beginning the checksum calculation by the FSM
-- asserting the clr_checksum signal. The vid_in word is added to the
-- current checksum when the FSM asserts the do_checksum signal. The
-- checksum is a 9-bit value and is computed by summing all but the MSB of
-- the vid_in word with the current checksum value and ignoring any carry
-- bits.
--
process(clk, rst)
begin
if (rst = '1') then
checksum <= (others => '0');
elsif (clk'event and clk = '1') then
if (ce = '1') then
if (clr_checksum = '1') then
checksum <= (others => '0');
else
checksum <= cksum_type(std_logic_vector(checksum) +
std_logic_vector(vid_in(8 downto 0)));
end if;
end if;
end if;
end process;
--
-- Active-picture CRC and valid bit register
--
-- This code captures the AP CRC word and valid bit. The CRC word is carried
-- in three different words in the EDH packet and is assembled into a
-- complete 16-bit checkword plus a valid bit by this logic.
--
process(clk, rst)
begin
if (rst = '1') then
ap_crc_valid <= '0';
ap_crc_reg <= (others => '0');
elsif (clk'event and clk = '1') then
if (ce = '1') then
if (ld_ap1 = '1') then
ap_crc_reg <= (ap_crc_reg(15 downto 6) & vid_in(7 downto 2));
elsif (ld_ap2 = '1') then
ap_crc_reg <= (ap_crc_reg(15 downto 12) & vid_in(7 downto 2) &
ap_crc_reg(5 downto 0));
elsif (ld_ap3 = '1') then
ap_crc_reg <= (vid_in(5 downto 2) & ap_crc_reg(11 downto 0));
ap_crc_valid <= vid_in(7);
end if;
end if;
end if;
end process;
--
-- Full-field CRC and valid bit register
--
-- This code captures the FF CRC word and valid bit. The CRC word is carried
-- in three different words in the EDH packet and is assembled into a
-- complete 16-bit checkword plus a valid bit by this logic.
--
process(clk, rst)
begin
if (rst = '1') then
ff_crc_valid <= '0';
ff_crc_reg <= (others => '0');
elsif (clk'event and clk = '1') then
if (ce = '1') then
if (ld_ff1 = '1') then
ff_crc_reg <= (ff_crc_reg(15 downto 6) & vid_in(7 downto 2));
elsif (ld_ff2 = '1') then
ff_crc_reg <= (ff_crc_reg(15 downto 12) & vid_in(7 downto 2) &
ff_crc_reg(5 downto 0));
elsif (ld_ff3 = '1') then
ff_crc_reg <= (vid_in(5 downto 2) & ff_crc_reg(11 downto 0));
ff_crc_valid <= vid_in(7);
end if;
end if;
end if;
end process;
--
-- EDH packet error flags
--
-- This code implements registers for each of the four different EDH packet
-- error flags. These flags are captured as an EDH packet is received and
-- remain asserted until the start of the next EDH packet.
--
process(clk, rst)
begin
if (rst = '1') then
edh_missing <= '0';
edh_parity_err <= '0';
edh_chksum_err <= '0';
edh_format_err <= '0';
elsif (clk'event and clk = '1') then
if (ce = '1') then
if (clr_errors = '1') then
edh_missing <= '0';
edh_parity_err <= '0';
edh_chksum_err <= '0';
edh_format_err <= '0';
else
if (missing_err = '1') then
edh_missing <= '1';
end if;
if (format_err = '1') then
edh_format_err <= '1';
end if;
if (checksum_err = '1') then
edh_chksum_err <= '1';
end if;
if (check_parity = '1' and parity_err = '1') then
edh_parity_err <= '1';
end if;
end if;
end if;
end if;
end process;
--
-- received flags registers
--
-- These registers capture the three sets of error status flags (ap, ff, and
-- anc) from the received EDH packet. These flags remain in the registers
-- until overwritten by the next EDH packet.
--
process(clk, rst)
begin
if (rst = '1') then
rx_ap_flg_reg <= (others => '0');
elsif (clk'event and clk = '1') then
if (ce = '1' and ld_ap_flags = '1') then
rx_ap_flg_reg <= vid_in(6 downto 2);
end if;
end if;
end process;
in_ap_flags <= rx_ap_flg_reg when reg_flags = '1' else vid_in(6 downto 2);
process(clk, rst)
begin
if (rst = '1') then
rx_ff_flg_reg <= (others => '0');
elsif (clk'event and clk = '1') then
if (ce = '1' and ld_ff_flags = '1') then
rx_ff_flg_reg <= vid_in(6 downto 2);
end if;
end if;
end process;
in_ff_flags <= rx_ff_flg_reg when reg_flags = '1' else vid_in(6 downto 2);
process(clk, rst)
begin
if (rst = '1') then
rx_anc_flg_reg <= (others => '0');
elsif (clk'event and clk = '1') then
if (ce = '1' and ld_anc_flags = '1') then
rx_anc_flg_reg <= vid_in(6 downto 2);
end if;
end if;
end process;
in_anc_flags <= rx_anc_flg_reg when reg_flags = '1' else vid_in(6 downto 2);
--
-- outputs assignments
--
ap_crc <= ap_crc_reg;
ff_crc <= ff_crc_reg;
rx_ap_flags <= rx_ap_flg_reg;
rx_ff_flags <= rx_ff_flg_reg;
rx_anc_flags <= rx_anc_flg_reg;
end synth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -