Skip to content

Instantly share code, notes, and snippets.

@tausen
Created April 7, 2014 14:19
Show Gist options
  • Save tausen/10021169 to your computer and use it in GitHub Desktop.
Save tausen/10021169 to your computer and use it in GitHub Desktop.
shiftaddmult
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity shiftaddmult is
generic (WIDTH: integer := 8);
port (
clk: in std_logic;
reset: in std_logic;
x: in std_logic_vector(WIDTH-1 downto 0);
y: in std_logic_vector(WIDTH-1 downto 0)
);
end shiftaddmult;
architecture rtl of shiftaddmult is
signal acc: std_logic_vector(WIDTH*2-1 downto 0);
signal ylsb: std_logic_vector(WIDTH*2-1 downto 0);
signal xreg: std_logic_vector(WIDTH*2-1 downto 0);
signal yreg: std_logic_vector(WIDTH-1 downto 0);
signal andout: std_logic_vector(WIDTH*2-1 downto 0);
signal xsign: std_logic_vector(WIDTH-1 downto 0);
signal ysign: std_logic_vector(WIDTH-1 downto 0);
signal x_invsign: std_logic_vector(WIDTH-1 downto 0);
signal y_invsign: std_logic_vector(WIDTH-1 downto 0);
begin
-- if lsb of y is 0, andout is all zeros
-- if lsb of y is 1, andout is xreg
ylsb <= (others=>yreg(0));
andout <= ylsb and xreg;
-- used for sign extension
xsign <= (others=>x(WIDTH-1));
ysign <= (others=>y(WIDTH-1));
-- 2's complement sign inversion
x_invsign <= (not x) + 1;
y_invsign <= (not y) + 1;
process (clk, reset, x, y)
begin
if (reset = '1') then
-- sign extend into double width registers (need room for shifting)
if (y(WIDTH-1) = '1') then
-- if multiplier is negative, invert multiplier and multiplicand
xreg <= (not xsign) & x_invsign;
yreg <= y_invsign;
else
xreg <= xsign & x;
yreg <= y;
end if;
-- reset accumulator
acc <= (others=>'0');
elsif (clk = '1') then
-- shift xreg left
xreg <= xreg(WIDTH*2-2 downto 0) & '0';
-- shift yreg right
yreg <= '0' & yreg(WIDTH-1 downto 1);
-- add xreg to acc if lsb of y is 1, otherwise do nothing (add zeros)
acc <= andout + acc;
end if;
end process;
end rtl;
-- TEST BENCH --
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY shiftaddmult_vhd_tst IS
END shiftaddmult_vhd_tst;
ARCHITECTURE shiftaddmult_arch OF shiftaddmult_vhd_tst IS
-- constants
constant N : integer := 4;
-- signals
SIGNAL clk : STD_LOGIC;
SIGNAL reset : STD_LOGIC;
SIGNAL x : STD_LOGIC_VECTOR(N-1 DOWNTO 0);
SIGNAL y : STD_LOGIC_VECTOR(N-1 DOWNTO 0);
COMPONENT shiftaddmult
generic (WIDTH: integer := N);
PORT (
clk : IN STD_LOGIC;
reset : IN STD_LOGIC;
x : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
y : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0)
);
END COMPONENT;
BEGIN
i1 : shiftaddmult
generic map(WIDTH => N)
PORT MAP (
clk => clk,
reset => reset,
x => x,
y => y
);
init : PROCESS
BEGIN
-- code that executes only once
x <= "1111";
y <= "0111";
reset <= '1';
wait for 15 ns;
reset <= '0';
WAIT;
END PROCESS init;
always : PROCESS
BEGIN
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
clk <= '0';
wait for 10 ns;
WAIT;
END PROCESS always;
END shiftaddmult_arch;
@tausen
Copy link
Author

tausen commented Apr 7, 2014

Et par simuleringer:
http://tausen.org/s/a397cb0c66.png
http://tausen.org/s/55a05bc66b.png
http://tausen.org/s/c79d372329.png

Den første simulering:
inputs x,y har en sign bit og 3 fractional bits, så
x = 1,111 -> -0,001 -> -2**-3 -> -0.125
y = 0,111 -> 2**-1 + 2**-2 + 2**-3 -> 0.875
og resultatet skulle så gerne blive -0.109375
men resultatet (i acc_bin) har en extension sign bit, en sign bit og 6 fractional bits, så
acc = (1)1,111001 -> -(0)0,000111 -> -(2**-4 + 2**-5 + 2**-6) -> -0.109375

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment