Files
es-abschlussprojekt/Hardware/axis_crc.vhd
T
2025-02-09 17:36:30 +01:00

149 lines
5.3 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity axis_crc is
port (
CLK : in std_logic;
RESETN : in std_logic;
-- for crc calculation
initial_value : in std_logic_vector(31 downto 0);
polynomial : in std_logic_vector(31 downto 0);
-- AXI Streaming Target Port
S_AXIS_TVALID : in std_logic;
S_AXIS_TDATA : in std_logic_vector(31 downto 0);
S_AXIS_TLAST : in std_logic := '0';
S_AXIS_TREADY : out std_logic;
-- AXI Streaming Initiator Port
M_AXIS_TVALID : out std_logic;
M_AXIS_TDATA : out std_logic_vector(31 downto 0);
M_AXIS_TLAST : out std_logic;
M_AXIS_TREADY : in std_logic
);
end entity;
architecture rtl of axis_crc is
type state_t is (IDLE, SECOND_HALF, PROVIDE_DATA, CHECKSUM);
signal state : state_t := IDLE;
signal crc_sig : std_logic_vector(31 downto 0);
begin
process
-- fuer CRC-Berechnung
variable CRC : std_logic_vector(31 downto 0);
variable MSB : std_logic;
variable data : std_logic_vector(31 downto 0);
variable last : std_logic;
begin
wait until rising_edge(CLK);
if RESETN = '0' then
state <= IDLE;
S_AXIS_TREADY <= '1';
M_AXIS_TVALID <= '0';
M_AXIS_TLAST <= '0';
crc_sig <= initial_value;
else
case state is
when IDLE =>
if S_AXIS_TVALID = '1' then
data := S_AXIS_TDATA;
last := S_AXIS_TLAST;
CRC := crc_sig;
-- Board speichert Daten mit LITTLE ENDIAN
-- -> Die Daten aus dem Speicher sollen aufsteigend
-- in die CRC-Summe reingerechnet werden
-- Daher: Erst untere 16 Bit in die CRC Summe reinrechnen
-- Erstes byte reinrechnen
CRC := CRC xor (data(7 downto 0) & (23 downto 0 =>'0'));
for i in 0 to 7 loop
if CRC(31) = '1' then
CRC := (CRC(30 downto 0) & '0') xor polynomial;
else
CRC := CRC(30 downto 0) & '0';
end if;
end loop;
-- Zweites byte reinrechnen
CRC := CRC xor (data(15 downto 8) & (23 downto 0 =>'0'));
for i in 0 to 7 loop
if CRC(31) = '1' then
CRC := (CRC(30 downto 0) & '0') xor polynomial;
else
CRC := CRC(30 downto 0) & '0';
end if;
end loop;
S_AXIS_TREADY <= '0';
state <= SECOND_HALF;
end if;
when SECOND_HALF =>
-- Dann obere 16 Bit in die CRC Summe reinrechnen
-- Drittes byte reinrechnen
CRC := CRC xor (data(23 downto 16) & (23 downto 0 =>'0'));
for i in 0 to 7 loop
if CRC(31) = '1' then
CRC := (CRC(30 downto 0) & '0') xor polynomial;
else
CRC := CRC(30 downto 0) & '0';
end if;
end loop;
-- Viertes byte reinrechnen
CRC := CRC xor (data(31 downto 24) & (23 downto 0 =>'0'));
for i in 0 to 7 loop
if CRC(31) = '1' then
CRC := (CRC(30 downto 0) & '0') xor polynomial;
else
CRC := CRC(30 downto 0) & '0';
end if;
end loop;
crc_sig <= CRC;
-- Daten an M_AXIS ausgeben
M_AXIS_TVALID <= '1';
M_AXIS_TDATA <= data;
state <= PROVIDE_DATA;
when PROVIDE_DATA =>
if M_AXIS_TREADY = '1' then
if last = '1' then
M_AXIS_TLAST <= '1';
M_AXIS_TDATA <= crc_sig;
state <= CHECKSUM;
else
S_AXIS_TREADY <= '1';
M_AXIS_TVALID <= '0';
state <= IDLE;
end if;
end if;
when CHECKSUM =>
if M_AXIS_TREADY = '1' then
S_AXIS_TREADY <= '1';
M_AXIS_TVALID <= '0';
M_AXIS_TLAST <= '0';
crc_sig <= initial_value;
state <= IDLE;
end if;
when others => null;
end case;
end if;
end process;
end architecture;