diff --git a/hardware/signal_processing/crc.vhd b/hardware/signal_processing/crc.vhd index 7b80a4d..15dce43 100644 --- a/hardware/signal_processing/crc.vhd +++ b/hardware/signal_processing/crc.vhd @@ -8,33 +8,36 @@ library work; entity crc is port ( - clk : in std_logic; - reset : in std_logic; - task_start : in std_logic; - task_state : out work.task.State; - signal_read : out std_logic; - signal_readdata : in std_logic_vector(31 downto 0); - signal_write : out std_logic; - signal_writedata: out std_logic_vector(31 downto 0) + clk : in std_logic; + reset : in std_logic; + + task_start : in std_logic; + task_state : out work.task.State; + + signal_read : out std_logic; + signal_readdata : in std_logic_vector( 31 downto 0 ); + + signal_write : out std_logic; + signal_writedata : out std_logic_vector( 31 downto 0 ) ); end entity crc; architecture rtl of crc is signal current_task_state : work.task.State; - signal next_task_state : work.task.State; - signal index : integer range 0 to work.task.STREAM_LEN := 0; + signal next_task_state : work.task.State; + signal index : integer range 0 to work.task.STREAM_LEN; - constant CRC_INIT : std_logic_vector(31 downto 0) := X"FFFFFFFF"; - constant CRC_POLY : std_logic_vector(31 downto 0) := X"EDB88320"; - signal crc : std_logic_vector(31 downto 0) := CRC_INIT; - signal data_reg : std_logic_vector(31 downto 0); - signal data_valid : std_logic := '0'; + constant CRC_INIT : std_logic_vector(31 downto 0) := X"FFFFFFFF"; + constant CRC_POLY : std_logic_vector(31 downto 0) := X"EDB88320"; + + signal crc_reg : std_logic_vector(31 downto 0) := CRC_INIT; + signal data_reg : std_logic_vector(31 downto 0); + signal data_ready : std_logic := '0'; begin task_state <= current_task_state; - - -- TASK STATE MACHINE (VORLAGE - nicht ändern!) - task_state_transitions: process(current_task_state, task_start, index) + + task_state_transitions : process ( current_task_state, task_start, index ) is begin next_task_state <= current_task_state; case current_task_state is @@ -43,8 +46,7 @@ begin next_task_state <= work.task.TASK_RUNNING; end if; when work.task.TASK_RUNNING => - -- WICHTIG: Schreiben nach 1024 Werten (index 0-1023) - if index = 1023 then + if index = work.task.STREAM_LEN then next_task_state <= work.task.TASK_DONE; end if; when work.task.TASK_DONE => @@ -54,67 +56,71 @@ begin end case; end process; - -- Data Channel Control signal_read <= '1' when current_task_state = work.task.TASK_RUNNING - and data_valid = '0' - and index < 1024 + and data_ready = '0' + and index < work.task.STREAM_LEN else '0'; signal_write <= '1' when current_task_state = work.task.TASK_DONE else '0'; - signal_writedata <= crc xor X"FFFFFFFF"; -- Final XOR + + signal_writedata <= crc_reg xor X"FFFFFFFF"; - -- Haupt-Sync Process (identisch zur SW-Version) - sync: process(clk, reset) - variable temp_crc : std_logic_vector(31 downto 0); - begin - if reset = '1' then - current_task_state <= work.task.TASK_IDLE; - index <= 0; - crc <= CRC_INIT; - data_reg <= (others => '0'); - data_valid <= '0'; - - elsif rising_edge(clk) then - current_task_state <= next_task_state; - - case next_task_state is - when work.task.TASK_IDLE => - index <= 0; - crc <= CRC_INIT; - data_valid <= '0'; +sync : process ( clk, reset ) is + variable temp_crc : std_logic_vector(31 downto 0); +begin + if reset = '1' then + current_task_state <= work.task.TASK_IDLE; + index <= 0; + crc_reg <= CRC_INIT; + data_reg <= X"00000000"; + data_ready <= '0'; + + elsif rising_edge(clk) then + current_task_state <= next_task_state; + + case next_task_state is + when work.task.TASK_IDLE => + index <= 0; + crc_reg <= CRC_INIT; + data_ready <= '0'; + data_reg <= X"00000000"; + + when work.task.TASK_RUNNING => + -- DATA LESEN (Timing korrekt) + if signal_read = '1' then + data_reg <= signal_readdata; + data_ready <= '1'; + end if; + + -- CRC UPDATE (INDEX PRÜFEN VOR Update!) + if data_ready = '1' then + -- WICHTIG: Index bleibt gleich bis TASK_DONE triggert! + --temp_crc := crc_reg xor data_reg; -- Berechne aber schreibe nicht sofort - when work.task.TASK_RUNNING => - -- 1. DATA LESEN (Timing: signal_read='1' -> NEXT CLK data_valid) - if signal_read = '1' then - data_reg <= signal_readdata; - data_valid <= '1'; - end if; + temp_crc := crc_reg xor data_reg; + for i in 0 to 31 loop + if temp_crc(0) = '1' then + temp_crc := std_logic_vector(shift_right(unsigned(temp_crc), 1)) xor CRC_POLY; + else + temp_crc := std_logic_vector(shift_right(unsigned(temp_crc), 1)); + end if; + end loop; - -- 2. CRC UPDATE (zlib: XOR dann 32x bitweise LSB-first) - if data_valid = '1' then - temp_crc := crc xor data_reg; - crc <= temp_crc; - - -- 32 Bit LSB-first Verarbeitung in EINEM Takt (wie SW) - for i in 0 to 31 loop - if temp_crc(0) = '1' then - temp_crc := std_logic_vector(shift_right(unsigned(temp_crc), 1)) xor CRC_POLY; - else - temp_crc := std_logic_vector(shift_right(unsigned(temp_crc), 1)); - end if; - end loop; - crc <= temp_crc; - - data_valid <= '0'; + crc_reg <= temp_crc; + data_ready <= '0'; + + -- INDEX NUR erhöhen wenn NICHT letzter! + if index < work.task.STREAM_LEN then index <= index + 1; - end if; - - when work.task.TASK_DONE => - index <= 0; - data_valid <= '0'; - end case; - end if; - end process; + end if; -- Bei index=1023: bleibt 1023 → TASK_DONE triggert! + end if; + + when work.task.TASK_DONE => + index <= 0; + data_ready <= '0'; + end case; + end if; +end process sync; + end architecture rtl; -