Files
es-abschlussprojekt/Archiv/Hardware/Mem_to_CRC.vhd
T
2025-01-31 17:47:31 +01:00

259 lines
7.6 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Mem_to_CRC is
generic (
logLength : integer
);
port (
CLK : in std_logic;
RST : in std_logic;
-- Control IO
ready : out std_logic := '0';
start : in std_logic;
startAddress : in std_logic_vector(31 downto 0);
lengthM1 : in std_logic_vector(logLength-1 downto 0);
-- Wishbone Master
D_DAT_O : out std_logic_vector(31 downto 0) := (others => '0') ;
D_DAT_I : in std_logic_vector(31 downto 0);
D_STB_O : out std_logic := '0';
D_ADR_O : out unsigned(31 downto 0) := (others => '0') ;
D_SEL_O : out std_logic_vector( 3 downto 0);
D_WE_O : out std_logic;
D_ACK_I : in std_logic;
-- CRC output
checksum : out std_logic_vector(31 downto 0) := (others => '0')
);
end entity;
architecture arch of Mem_to_CRC is
--Signale zwischen Steuerwerk und Rechenwerk
signal lengthEN : std_logic := '0';
signal lengthLD : std_logic := '0';
signal lengthTC : std_logic := '0';
signal dataEN : std_logic := '0';
signal CRCEN : std_logic := '0';
signal CRCRST : std_logic := '0';
signal startAddressEN : std_logic := '0';
signal startAddressLD : std_logic := '0';
signal startBytesEN : std_logic := '0';
signal startBytesLD : std_logic := '0';
signal startBytesTC : std_logic := '0';
begin
Rechenwerk: block
-- Register
signal dataByte3 : std_logic_vector(7 downto 0) := (others => '0');
signal dataByte2 : std_logic_vector(7 downto 0) := (others => '0');
signal dataByte1 : std_logic_vector(7 downto 0) := (others => '0');
signal dataByte0 : std_logic_vector(7 downto 0) := (others => '0');
signal toCRC : std_logic_vector(7 downto 0) := (others => '0');
signal byteSelect : std_logic_vector(1 downto 0) := (others => '0');
begin
--Zaehler der Anzahl der Datenbytes
CounterLength: process(CLK)
variable counterValue: unsigned(logLength - 1 downto 0) := (others => '0');
begin
if rising_edge(CLK) then
if lengthLD = '1' then --Laden
counterValue := unsigned(lengthM1);
elsif lengthEN = '1' then --runterzaehlen
counterValue := counterValue - 1;
end if;
if counterValue = 0 then --TC setzen
lengthTC <= '1';
else
lengthTC <= '0';
end if;
end if;
end process;
--Zaehler fuer Adressen
CounterAddress: process(CLK)
variable counterValue : unsigned(31 downto 2) := (others => '0');
begin
if rising_edge(CLK) then
if startAddressLD = '1' then
counterValue := unsigned(startAddress(31 downto 2)); --Speicher laden
elsif startAddressEN = '1' then
counterValue := counterValue + 1; --hochzaehlen
end if;
--Variabel ausgeben und auf 32 Bit erweitern
D_ADR_O <= counterValue & "00";
end if;
end process;
--Modulozaehler fuer die einzelnen Bytes
CounterBytes: process(CLK)
variable counterValue : unsigned(1 downto 0) := (others => '0');
begin
if rising_edge(CLK) then
if startBytesLD = '1' then
counterValue := unsigned(startAddress(1 downto 0)); --Speicher laden
elsif startBytesEN = '1' and counterValue < 3 then --hochzaehlen
counterValue := counterValue + 1;
elsif startBytesEN = '1' and counterValue = 3 then
counterValue := (others => '0'); --zuruecksetzen
end if;
if counterValue = 3 then --TC setzen
startBytesTC <= '1';
else
startBytesTC <= '0';
end if;
--Variabel ausgeben und zum Multiplexer fuehren
byteSelect <= std_logic_vector(counterValue);
end if;
end process;
--vier Pufferregister fuer das Datenwort -> vier Datenbytes
SeparateDataWords: process(CLK)
begin
if rising_edge(CLK) then
if DataEN = '1' then
dataByte3 <= D_DAT_I(31 downto 24);
dataByte2 <= D_DAT_I(23 downto 16);
dataByte1 <= D_DAT_I(15 downto 8);
dataByte0 <= D_DAT_I(7 downto 0);
end if;
end if;
end process;
--Multiplexer für das Ansteuern des ersten Datenbytes
ByteSelectMUX: process(byteSelect, dataByte0, dataByte1, dataByte2, dataByte3)
begin
toCRC <= (others => '0');
case byteSelect is
when "11" => toCRC <= dataByte3;
when "10" => toCRC <= dataByte2;
when "01" => toCRC <= dataByte1;
when "00" => toCRC <= dataByte0;
when others => toCRC <= (others => '-');
end case;
end process;
--Feste Ausgaenge
D_SEL_O <= "1111";
D_WE_O <= '0';
------------------------------------------------------------
-- CRC Berechnung
------------------------------------------------------------
CRC_Inst: entity work.CRC
generic map (
crcLength => 32,
inDataLength => 8,
polynomial => x"04C11DB7",
initialValue => x"00000000"
)
port map (
CLK => CLK,
reset => CRCRST,
enable => CRCEN,
inData => toCRC(7 downto 0),
checksum => checksum(31 downto 0)
);
end block;
Steuerwerk : block
-- Typ fuer die Zustandswerte
type state_t is (S_IDLE, S_READ_WORD, S_CALCULATE_CRC, S_ERROR);
-- Interne Signale des Rechenwerks
signal state : state_t := S_IDLE;
signal state_next : state_t;
begin
-- Prozess zur Berechnung des Folgezustandes und der Mealy-Ausgaenge
Transition: process(RST, state, start, D_ACK_I, startBytesTC, lengthTC)
begin
-- Default-Werte fuer Folgezustand und Mealy-Ausgaenge
state_next <= S_ERROR;
lengthEN <= '0';
lengthLD <= '0';
dataEN <= '0';
CRCRST <= '0';
startAddressEN <= '0';
startAddressLD <= '0';
startBytesEN <= '0';
startBytesLD <= '0';
-- Berechnung des Folgezustandes und der Mealy-Ausgaenge
case state is
when S_IDLE =>
if RST = '1' then
state_next <= S_IDLE;
elsif start = '1' then
state_next <= S_READ_WORD;
lengthLD <= '1';
CRCRST <= '1';
startAddressLD <= '1';
startBytesLD <= '1';
elsif start = '0' then
state_next <= S_IDLE;
end if;
when S_READ_WORD =>
if RST = '1' then
state_next <= S_IDLE;
elsif D_ACK_I = '0' then
state_next <= S_READ_WORD;
elsif D_ACK_I = '1' then
state_next <= S_CALCULATE_CRC;
dataEN <= '1';
end if;
when S_CALCULATE_CRC =>
if RST = '1' then
state_next <= S_IDLE;
elsif startBytesTC = '0' and lengthTC = '0' then
state_next <= S_CALCULATE_CRC;
lengthEN <= '1';
startBytesEN <= '1';
elsif startBytesTC = '1' and lengthTC = '0' then
state_next <= S_READ_WORD;
lengthEN <= '1';
startBytesEN <= '1';
startAddressEN <= '1';
elsif lengthTC = '1' then
state_next <= S_IDLE;
end if;
when others =>
lengthEN <= 'X';
lengthLD <= 'X';
dataEN <= 'X';
CRCRST <= 'X';
startAddressEN <= 'X';
startAddressLD <= 'X';
startBytesEN <= 'X';
startBytesLD <= 'X';
end case;
end process;
-- Register fuer Zustand und Moore-Ausgaenge
Reg: process (CLK)
begin
if rising_edge(CLK) then
-- Zustandsregister
state <= state_next;
-- Berechnung der Moore-Ausgaenge
--Default-Werte
ready <= '0';
CRCEN <= '0';
D_STB_O <= '0';
case state_next is
when S_IDLE =>
ready <= '1';
when S_READ_WORD =>
D_STB_O <= '1';
when S_CALCULATE_CRC =>
CRCEN <= '1';
when others =>
ready <= 'X';
CRCEN <= 'X';
D_STB_O <= 'X';
end case;
end if;
end process;
end block;
end architecture;