|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
|
|
entity crc_core is
|
entity crc_core is
|
|
|
generic (
|
generic (
|
C_SR_WIDTH : integer := 32);
|
C_SR_WIDTH : integer := 32);
|
port (
|
port (
|
rst : in std_logic;
|
rst : in std_logic;
|
opb_clk : in std_logic;
|
opb_clk : in std_logic;
|
crc_en : in std_logic;
|
crc_en : in std_logic;
|
crc_clr : in std_logic;
|
crc_clr : in std_logic;
|
opb_m_last_block : in std_logic;
|
opb_m_last_block : in std_logic;
|
-- RX
|
-- RX
|
fifo_rx_en : in std_logic;
|
fifo_rx_en : in std_logic;
|
fifo_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0);
|
fifo_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0);
|
opb_rx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0);
|
opb_rx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0);
|
-- TX
|
-- TX
|
fifo_tx_en : in std_logic;
|
fifo_tx_en : in std_logic;
|
fifo_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0);
|
fifo_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0);
|
tx_crc_insert : out std_logic;
|
tx_crc_insert : out std_logic;
|
opb_tx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0));
|
opb_tx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0));
|
end crc_core;
|
end crc_core;
|
|
|
|
|
architecture behavior of crc_core is
|
architecture behavior of crc_core is
|
component crc_gen
|
component crc_gen
|
generic (
|
generic (
|
C_SR_WIDTH : integer;
|
C_SR_WIDTH : integer;
|
crc_start_value : std_logic_vector(31 downto 0));
|
crc_start_value : std_logic_vector(31 downto 0));
|
port (
|
port (
|
clk : in std_logic;
|
clk : in std_logic;
|
crc_clear : in std_logic;
|
crc_clear : in std_logic;
|
crc_en : in std_logic;
|
crc_en : in std_logic;
|
crc_data_in : in std_logic_vector(C_SR_WIDTH-1 downto 0);
|
crc_data_in : in std_logic_vector(C_SR_WIDTH-1 downto 0);
|
crc_data_out : out std_logic_vector(C_SR_WIDTH-1 downto 0));
|
crc_data_out : out std_logic_vector(C_SR_WIDTH-1 downto 0));
|
end component;
|
end component;
|
|
|
signal rx_crc_en : std_logic;
|
signal rx_crc_en : std_logic;
|
signal tx_crc_en : std_logic;
|
signal tx_crc_en : std_logic;
|
|
|
|
|
type state_define is (idle,
|
type state_define is (idle,
|
tx_insert_crc,
|
tx_insert_crc,
|
wait_done);
|
wait_done);
|
signal state : state_define;
|
signal state : state_define;
|
|
|
begin -- behavior
|
begin -- behavior
|
|
|
--* RX CRC_GEN
|
--* RX CRC_GEN
|
crc_gen_rx : crc_gen
|
crc_gen_rx : crc_gen
|
generic map (
|
generic map (
|
C_SR_WIDTH => C_SR_WIDTH,
|
C_SR_WIDTH => C_SR_WIDTH,
|
crc_start_value => (others => '1'))
|
crc_start_value => (others => '1'))
|
port map (
|
port map (
|
clk => OPB_Clk,
|
clk => OPB_Clk,
|
crc_clear => crc_clr,
|
crc_clear => crc_clr,
|
crc_en => rx_crc_en,
|
crc_en => rx_crc_en,
|
crc_data_in => fifo_rx_data,
|
crc_data_in => fifo_rx_data,
|
crc_data_out => opb_rx_crc_value);
|
crc_data_out => opb_rx_crc_value);
|
|
|
-- disable crc_generation for last data block
|
-- disable crc_generation for last data block
|
rx_crc_en <= '1' when (crc_en = '1' and fifo_rx_en = '1' and opb_m_last_block = '0') else
|
rx_crc_en <= '1' when (crc_en = '1' and fifo_rx_en = '1' and opb_m_last_block = '0') else
|
'0';
|
'0';
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
--* TX CRC_GEN
|
--* TX CRC_GEN
|
crc_gen_tx : crc_gen
|
crc_gen_tx : crc_gen
|
generic map (
|
generic map (
|
C_SR_WIDTH => C_SR_WIDTH,
|
C_SR_WIDTH => C_SR_WIDTH,
|
crc_start_value => (others => '1'))
|
crc_start_value => (others => '1'))
|
port map (
|
port map (
|
clk => OPB_Clk,
|
clk => OPB_Clk,
|
crc_clear => crc_clr,
|
crc_clear => crc_clr,
|
crc_en => tx_crc_en,
|
crc_en => tx_crc_en,
|
crc_data_in => fifo_tx_data,
|
crc_data_in => fifo_tx_data,
|
crc_data_out => opb_tx_crc_value);
|
crc_data_out => opb_tx_crc_value);
|
|
|
-- disable crc_generation for last data block
|
-- disable crc_generation for last data block
|
tx_crc_en <= '1' when (crc_en = '1' and fifo_tx_en = '1' and opb_m_last_block = '0') else
|
tx_crc_en <= '1' when (crc_en = '1' and fifo_tx_en = '1' and opb_m_last_block = '0') else
|
'0';
|
'0';
|
|
|
process(rst, OPB_Clk)
|
process(rst, OPB_Clk)
|
begin
|
begin
|
if (rst = '1') then
|
if (rst = '1') then
|
tx_crc_insert <= '0';
|
tx_crc_insert <= '0';
|
state <= idle;
|
state <= idle;
|
elsif rising_edge(OPB_Clk) then
|
elsif rising_edge(OPB_Clk) then
|
case state is
|
case state is
|
when idle =>
|
when idle =>
|
if (opb_m_last_block = '1') then
|
if (opb_m_last_block = '1') then
|
tx_crc_insert <= '1';
|
tx_crc_insert <= '1';
|
state <= tx_insert_crc;
|
state <= tx_insert_crc;
|
else
|
else
|
tx_crc_insert <= '0';
|
tx_crc_insert <= '0';
|
state <= idle;
|
state <= idle;
|
end if;
|
end if;
|
|
|
when tx_insert_crc =>
|
when tx_insert_crc =>
|
if (opb_m_last_block = '0') then
|
if (opb_m_last_block = '0') then
|
-- abort
|
-- abort
|
tx_crc_insert <= '0';
|
tx_crc_insert <= '0';
|
state <= idle;
|
state <= idle;
|
elsif (fifo_tx_en = '1') then
|
elsif (fifo_tx_en = '1') then
|
tx_crc_insert <= '0';
|
tx_crc_insert <= '0';
|
state <= wait_done;
|
state <= wait_done;
|
else
|
else
|
state <= tx_insert_crc;
|
state <= tx_insert_crc;
|
end if;
|
end if;
|
|
|
when wait_done =>
|
when wait_done =>
|
if (opb_m_last_block = '0') then
|
if (opb_m_last_block = '0') then
|
tx_crc_insert <= '0';
|
tx_crc_insert <= '0';
|
state <= idle;
|
state <= idle;
|
|
|
else
|
else
|
state <= wait_done;
|
state <= wait_done;
|
end if;
|
end if;
|
|
|
when others =>
|
when others =>
|
state <= idle;
|
state <= idle;
|
end case;
|
end case;
|
|
|
end if;
|
end if;
|
end process;
|
end process;
|
end behavior;
|
end behavior;
|
|
|