Livt packages
Livt.ML
Version 1.6.1
Fixed-size quantized inference, tensor storage, attention, and transformer building blocks for Livt.
Published files (132)
- DotProduct.lvt
- FixedPointAccumulator.lvt
- Int8BroadcastMac64x8.lvt
- Int8BroadcastMac64x8Primitive.lvt
- Int8BroadcastMac64x8Primitive.vhd
- Int8Dot64x8.lvt
- Int8Dot64x8Primitive.lvt
- Int8Dot64x8Primitive.vhd
- Int8Linear4x8.lvt
- Int8Linear8x3.lvt
- Int8LinearAccumulator.lvt
- Int8Mac8.lvt
- Int8MatrixAccumulator32.lvt
- Int8MatrixAccumulator32Primitive.lvt
- Int8MatrixAccumulator32Primitive.vhd
- Int8MatrixAccumulator32Stream.lvt
- Linear8x8.lvt
- MatrixVectorMultiplication.lvt
- QLinearMatMul256x10.lvt
- QLinearMatMul256x10Ram.lvt
- QLinearMatMul256x10Stream.lvt
- QuantizedMatrix.lvt
- VecAdd.lvt
src/linear/Int8BroadcastMac64x8Primitive.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.Numeric_Std.all;
use work.livt_lang_icontext_package.t_icontext_in;
entity livt_ml_linear_int8broadcastmac64x8primitive is
port(
ctor_lvt_context_in : in t_icontext_in;
ctor_request : in std_logic;
ctor_clear : in std_logic;
ctor_activation : in signed(31 downto 0);
ctor_weights : in std_logic_vector(511 downto 0);
ctor_resultindex : in std_logic_vector(5 downto 0);
ctor_acknowledge : out std_logic;
ctor_result : out signed(31 downto 0)
);
end;
architecture RTL of livt_ml_linear_int8broadcastmac64x8primitive is
type T_AccumulatorArray is array (0 to 63) of signed(31 downto 0);
type T_ProductArray is array (0 to 7) of signed(31 downto 0);
signal accumulators : T_AccumulatorArray := (others => (others => '0'));
signal products : T_ProductArray := (others => (others => '0'));
signal weight_row : std_logic_vector(511 downto 0) := (others => '0');
signal activation_value : signed(15 downto 0) := (others => '0');
signal pending_request : std_logic := '0';
signal running : boolean := false;
signal group_index : natural range 0 to 7 := 0;
begin
compute : process(ctor_lvt_context_in.clk) is
variable next_group : natural;
begin
if rising_edge(ctor_lvt_context_in.clk) then
if ctor_lvt_context_in.rst = '1' then
accumulators <= (others => (others => '0'));
products <= (others => (others => '0'));
weight_row <= (others => '0');
activation_value <= (others => '0');
pending_request <= '0';
ctor_acknowledge <= '0';
running <= false;
group_index <= 0;
elsif running then
for lane in 0 to 7 loop
accumulators(group_index * 8 + lane) <=
accumulators(group_index * 8 + lane) + products(lane);
end loop;
if group_index = 7 then
ctor_acknowledge <= pending_request;
running <= false;
else
next_group := group_index + 1;
for lane in 0 to 7 loop
products(lane) <= resize(
activation_value * signed(weight_row((next_group * 8 + lane) * 8 + 7 downto
(next_group * 8 + lane) * 8)), 32);
end loop;
group_index <= next_group;
end if;
elsif ctor_request /= ctor_acknowledge then
if ctor_clear = '1' then
accumulators <= (others => (others => '0'));
ctor_acknowledge <= ctor_request;
else
weight_row <= ctor_weights;
activation_value <= resize(ctor_activation, 16);
pending_request <= ctor_request;
group_index <= 0;
for lane in 0 to 7 loop
products(lane) <= resize(
resize(ctor_activation, 16) *
signed(ctor_weights(lane * 8 + 7 downto lane * 8)), 32);
end loop;
running <= true;
end if;
end if;
end if;
end process compute;
read_result : process(all) is
begin
if is_x(ctor_resultindex) then
ctor_result <= (others => '0');
else
ctor_result <= accumulators(to_integer(unsigned(ctor_resultindex)));
end if;
end process read_result;
end;