Files
es-praktikum/Milestone2/axis_audio_bitcrusher.vhd
T
Sebastian Meyer 37a669c883 Bitcrusherv2_1
2024-10-23 19:20:44 +02:00

149 lines
4.7 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all
use ieee.numeric_std.all
entity axis_audio_bitcrusher is
generic
(
BIT_REDUCTION : integer := 14;
HAS_LAST : boolean := false
);
port
(
AXIS_ACLK : in std_logic;
AXIS_ARESETN : in std_logic;
-- AXI Streaming Target Port
S_AXIS_TVALID : in std_logic := '0';
S_AXIS_TDATA : in std_logic_vector(15 downto 0) := (others => '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(15 downto 0);
M_AXIS_TLAST : out std_logic;
M_AXIS_TREADY : in std_logic := '1'
);
end;
architecture rtl of axis_audio_bitcrusher is
begin
-- Steuersignale zwischen Steuerwerk und Rechenwerk
signal RegInputEn : std_logic := '0';
signal RegOutputEn : std_logic := '0';
-- Signale innerhalb des Rechenwerks
signal caculatorInput : std_logic_vector(15 downto 0);
signal caculatorOutput : std_logic_vector(15 downto 0);
signal safeTLast : std_logic := '0';
-- Finite state machine
type state_t is (S_INPUT, S_CALCULATE, S_OUTPUT, S_ERROR);
signal state : state_t := S_INPUT;
signal state_next : state_t;
begin
-- Register fuer die Inputdaten
RegInput: process
begin
wait until rising_edge(clk);
if RegInputEn = '1' then
caculatorInput <= S_AXIS_TDATA;
end if;
end process;
-- Kombinatorik fuer Bitcrusherberechnung
Bitcrusher: process (caculatorInput)
begin
calculatorOutput <= caculatorInput(16 downto BIT_REDUCTION) & (others => '0'); -- Setze die Bits 0 bis (x-1) auf Null
end process;
-- Register fuer die Outputdaten
RegOutput: process
begin
wait until rising_edge(clk);
if RegOutputEn = '1' then
M_AXIS_TDATA <= caculatorOutput;
end if;
end process;
-- Prozesse fuer endlichen Automaten
Transition: process(state, reset, M_AXIS_TREADY, S_AXIS_TVALID, S_AXIS_TLAST)
begin
-- Default-Werte fuer Folgezustand und Mealy-Ausgaenge
state_next <= S_ERROR;
-- Berechnung des Folgezustandes und der Mealy-Ausgaenge
case state is
when S_INPUT =>
if HAS_LAST = '1' then
if S_AXIS_TLAST = '1' then
safeTLast <= '1';
end if;
end if;
if S_AXIS_TVALID = '1' then
state_next <= S_CALCULATE;
elsif S_AXIS_TVALID = '0' then
state_next <= S_INPUT;
end if;
when S_CALCULATE =>
state_next <= S_OUTPUT;
when S_OUTPUT =>
if HAS_LAST = '1' then
if safeTLast = '1' then
M_AXIS_TLAST <= '1';
end if;
end if;
if M_AXIS_TREADY = '1' then
state_next <= S_INPUT;
elsif M_AXIS_TREADY = '0' then
state_next <= S_OUTPUT;
end if;
when S_ERROR =>
if reset = '1' then
state_next <= S_OUTPUT;
else
state_next <= S_ERROR;
end if;
end case;
end process;
-- Register fuer Zustand und Ausgaenge
Reg: process
begin
wait until rising_edge(clk);
-- Zustandswechsel
state <= state_next;
-- Berechnung der Moore-Ausgaenge, die nur vom Zustand abhaengen
-- Default-Werte
S_AXIS_TREADY <= 'X';
RegOutputEn <= 'X';
RegInputEn <= 'X';
M_AXIS_TVALID <= 'X';
case state_next is
when S_INPUT =>
S_AXIS_TREADY <= '1';
RegOutputEn <= '0';
RegInputEn <= '0';
M_AXIS_TVALID <= '0';
when S_CALCULATE =>
S_AXIS_TREADY <= '0';
RegOutputEn <= '1';
RegInputEn <= '0';
M_AXIS_TVALID <= '0';
when S_OUTPUT =>
S_AXIS_TREADY <= '0';
RegOutputEn <= '0';
RegInputEn <= '1';
M_AXIS_TVALID <= '1';
when S_ERROR =>
S_AXIS_TREADY <= 'X';
RegOutputEn <= 'X';
RegInputEn <= 'X';
M_AXIS_TVALID <= 'X';
end case;
end process;
end rtl;