143 lines
4.7 KiB
VHDL
143 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
|
|
-- 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(AXIS_ACLK);
|
|
if RegInputEn = '1' then
|
|
caculatorInput <= S_AXIS_TDATA;
|
|
end if;
|
|
end process;
|
|
|
|
-- Kombinatorik fuer Bitcrusherberechnung
|
|
Bitcrusher: process (caculatorInput)
|
|
begin
|
|
caculatorOutput <= caculatorInput(15 downto BIT_REDUCTION + 1) & (BIT_REDUCTION downto 0 => '0');
|
|
end process;
|
|
|
|
-- Register fuer die Outputdaten
|
|
RegOutput: process
|
|
begin
|
|
wait until rising_edge(AXIS_ACLK);
|
|
if RegOutputEn = '1' then
|
|
M_AXIS_TDATA <= caculatorOutput;
|
|
end if;
|
|
end process;
|
|
|
|
-- Prozesse fuer endlichen Automaten
|
|
Transition: process(state, AXIS_ARESETN, 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 = true 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 = true 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 AXIS_ARESETN = '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(AXIS_ACLK);
|
|
-- 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 <= '1';
|
|
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 <= '0';
|
|
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; |