Livt packages
Livt.Signal
Version 0.1.1
Q1.15 sample streams, filters, windows, rate conversion, FFTs, oscillators, and mixers for Livt.
Published files (80)
src/window/WindowQ15PipelinePrimitive.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.livt_lang_icontext_package.all;
use work.livt_lang_package.all;
entity livt_signal_window_windowq15pipelineprimitive is
port (
ctor_lvt_context_in : in t_icontext_in;
ctor_coefficients : in integer_1d;
ctor_inputvalid : in boolean;
ctor_inputready : out boolean;
ctor_inputsample : in std_logic_vector(15 downto 0);
ctor_inputfirst : in boolean;
ctor_inputlast : in boolean;
ctor_outputvalid : out boolean;
ctor_outputready : in boolean;
ctor_outputsample : out std_logic_vector(15 downto 0);
ctor_outputfirst : out boolean;
ctor_outputlast : out boolean
);
end;
architecture rtl of livt_signal_window_windowq15pipelineprimitive is
function quantize_q15(value : signed(63 downto 0)) return std_logic_vector is
variable magnitude : unsigned(63 downto 0);
variable rounded : unsigned(63 downto 0);
variable sticky : boolean := false;
variable negative : boolean;
variable raw : integer;
begin
negative := value(63) = '1';
if negative then magnitude := unsigned(-value);
else magnitude := unsigned(value); end if;
rounded := shift_right(magnitude, 15);
if magnitude(14) = '1' then
for bit_index in 0 to 13 loop
if magnitude(bit_index) = '1' then sticky := true; end if;
end loop;
if sticky or rounded(0) = '1' then rounded := rounded + 1; end if;
end if;
if negative then
if rounded > to_unsigned(32768, 64) then
return std_logic_vector(to_signed(-32768, 16));
end if;
raw := to_integer(rounded(15 downto 0));
return std_logic_vector(to_signed(-raw, 16));
end if;
if rounded > to_unsigned(32767, 64) then
return std_logic_vector(to_signed(32767, 16));
end if;
return std_logic_vector(to_signed(to_integer(rounded(14 downto 0)), 16));
end;
constant SAMPLES : positive := ctor_coefficients'length;
signal position : natural range 0 to SAMPLES - 1 := 0;
signal stage_sample : signed(15 downto 0) := (others => '0');
signal stage_coefficient : integer range -32768 to 32767 := 0;
signal stage_valid, stage_first, stage_last : std_logic := '0';
signal result_sample : std_logic_vector(15 downto 0) := (others => '0');
signal result_valid, result_first, result_last : std_logic := '0';
signal advance : boolean;
begin
advance <= result_valid = '0' or ctor_outputready;
ctor_inputready <= ctor_lvt_context_in.rst = '0' and advance;
ctor_outputvalid <= ctor_lvt_context_in.rst = '0' and result_valid = '1';
ctor_outputsample <= result_sample;
ctor_outputfirst <= result_first = '1';
ctor_outputlast <= result_last = '1';
process (ctor_lvt_context_in.clk)
variable selected_position : natural range 0 to SAMPLES - 1;
variable product : signed(63 downto 0);
begin
if rising_edge(ctor_lvt_context_in.clk) then
if ctor_lvt_context_in.rst = '1' then
position <= 0;
stage_valid <= '0';
stage_first <= '0';
stage_last <= '0';
result_valid <= '0';
result_first <= '0';
result_last <= '0';
else
for index in ctor_coefficients'range loop
assert to_integer(ctor_coefficients(index)) >= -32768 and
to_integer(ctor_coefficients(index)) <= 32767
report "window coefficient must fit signed Q1.15" severity failure;
end loop;
if advance then
result_valid <= stage_valid;
result_first <= stage_first;
result_last <= stage_last;
if stage_valid = '1' then
product := resize(stage_sample * stage_coefficient, 64);
result_sample <= quantize_q15(product);
end if;
if ctor_inputvalid then
if ctor_inputfirst then selected_position := 0;
else selected_position := position; end if;
stage_sample <= signed(ctor_inputsample);
stage_coefficient <= to_integer(ctor_coefficients(selected_position));
stage_valid <= '1';
if ctor_inputfirst then stage_first <= '1';
else stage_first <= '0'; end if;
if ctor_inputlast then stage_last <= '1';
else stage_last <= '0'; end if;
if ctor_inputlast or selected_position = SAMPLES - 1 then
position <= 0;
else
position <= selected_position + 1;
end if;
else
stage_valid <= '0';
stage_first <= '0';
stage_last <= '0';
end if;
end if;
end if;
end if;
end process;
end;