showcase component

Matrix Multiply 2x2 (int8)

Open in playground

A 2x2 matrix multiply over int8 values, fully combinational. Matrix multiplication is the core operation of machine learning: a neural-network layer is one large matrix product, and quantized inference runs it on 8-bit integers exactly like these. This is the smallest honest slice of that machine.

Each output element is a row-times-column dot product. c00 multiplies row 0 of A against column 0 of B and adds the pair. Four outputs need eight int8 multipliers and four adders, and all of them exist at once as parallel hardware. Nothing is reused and nothing waits: area buys the answer in a single step. Two int8 factors need 16 product bits, and one addition can carry into a 17th, so the outputs are 17 bits wide.

In the waveform: at the second 10 ns step every operand is -128, and all four outputs snap to +32768 together. There is no sequencing to watch, which is the whole point of the combinational form.

In the netlist: the view shows structure, not gate fabric. Each multiply is one block and each dot product is a two-level tree feeding an adder, eight multipliers side by side. Open the design in the playground and run synthesis there to watch those blocks expand into thousands of real gates.

The course builds the adders and signed arithmetic underneath this design from first principles in Arithmetic Circuits.

-- 2x2 int8 matrix multiply, fully combinational: all eight products and
-- four sums exist as parallel hardware, answering in a single step
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity matmul_2x2 is
  port (
    a00 : in  std_logic_vector(7 downto 0);
    a01 : in  std_logic_vector(7 downto 0);
    a10 : in  std_logic_vector(7 downto 0);
    a11 : in  std_logic_vector(7 downto 0);
    b00 : in  std_logic_vector(7 downto 0);
    b01 : in  std_logic_vector(7 downto 0);
    b10 : in  std_logic_vector(7 downto 0);
    b11 : in  std_logic_vector(7 downto 0);
    c00 : out std_logic_vector(16 downto 0);
    c01 : out std_logic_vector(16 downto 0);
    c10 : out std_logic_vector(16 downto 0);
    c11 : out std_logic_vector(16 downto 0)
  );
end entity matmul_2x2;

architecture rtl of matmul_2x2 is
begin

  -- Each output is one row-times-column dot product: two int8 multiplies
  -- (16-bit products) and one add, so 17 bits hold every possible result
  c00 <= std_logic_vector(resize(signed(a00) * signed(b00), 17)
                        + resize(signed(a01) * signed(b10), 17));
  c01 <= std_logic_vector(resize(signed(a00) * signed(b01), 17)
                        + resize(signed(a01) * signed(b11), 17));
  c10 <= std_logic_vector(resize(signed(a10) * signed(b00), 17)
                        + resize(signed(a11) * signed(b10), 17));
  c11 <= std_logic_vector(resize(signed(a10) * signed(b01), 17)
                        + resize(signed(a11) * signed(b11), 17));

end architecture rtl;
Waveform loading...