kansas-lava-0.2.4: Prelude/VHDL/Lava.vhd
-- These are core Lava built-in functions Lava programs can rely on having
-- Todo: Consider prepending lava_ to the names.
-- These are core Lava built-in functions Lava programs can rely on having
-- Todo: Consider prepending lava_ to the names.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
package lava is
function lava_to_std_logic (i0 : std_logic_vector(0 downto 0)) return std_logic;
end;
package body lava is
-- This is because we store memories of booleans as vector(0 downto 0)
function lava_to_std_logic (i0 : std_logic_vector(0 downto 0)) return std_logic is
begin
return i0(0);
end;
end lava;
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_register is
generic(
width : natural;
def : integer
);
port(
rst : in std_logic;
clk : in std_logic;
clk_en : in std_logic;
i0 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0)
);
end entity lava_register;
architecture Behavioral of lava_register is
signal reg : std_logic_vector(width-1 downto 0) := STD_LOGIC_VECTOR(TO_SIGNED(def,width));
begin
proc : process(rst, clk, clk_en) is
begin
if rst = '1' then
reg <= STD_LOGIC_VECTOR(TO_SIGNED(def,width));
elsif rising_edge(clk) then
if (clk_en = '1') then
reg <= i0;
end if;
end if;
end process proc;
o0 <= reg;
end Behavioral;
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_delay is
generic(
width : natural
);
port(
rst : in std_logic;
clk : in std_logic;
clk_en : in std_logic;
i0 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0)
);
end entity lava_delay;
architecture Behavioral of lava_delay is
begin
proc : process(rst, clk, clk_en) is
begin
if rising_edge(clk) then
if (clk_en = '1') then
o0 <= i0;
end if;
end if;
end process proc;
end Behavioral;
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_bram is
generic(
addr_width : natural;
data_width : natural;
element_count : natural;
sync : natural
);
port (
rst : in std_logic;
clk : in std_logic;
clk_en : in std_logic;
wEn : in std_logic;
wAddr : in std_logic_vector(addr_width-1 downto 0);
wData : in std_logic_vector(data_width-1 downto 0);
rAddr : in std_logic_vector(addr_width-1 downto 0);
o0 : out std_logic_vector(data_width-1 downto 0)
);
end entity lava_bram;
architecture Behavioral of lava_bram is
type mem_type is array (element_count-1 downto 0) of std_logic_vector(data_width-1 downto 0);
signal mem : mem_type := (others => (others => 'X'));
begin
proc : process(rst, clk, clk_en) is
begin
if rising_edge(clk) then
if (clk_en = '1') then
if (wEn = '1') then
mem(to_integer(unsigned(wAddr))) <= wData;
end if;
end if;
end if;
if sync = 0 then
-- async; someone else adding any delays on writing.
o0 <= mem(to_integer(unsigned(rAddr)));
else
if rising_edge(clk) then
if (clk_en = '1') then
-- sync; with built in delay
o0 <= mem(to_integer(unsigned(rAddr)));
end if;
end if;
end if;
end process proc;
end Behavioral;
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_unsigned_mul is
generic(
width : natural
);
port (
i0 : in std_logic_vector(width-1 downto 0);
i1 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0)
);
end entity lava_unsigned_mul;
architecture Behavioral of lava_unsigned_mul is
signal tmp : std_logic_vector(2*width-1 downto 0);
begin
-- a version of multiply that has the same sized output
tmp <= std_logic_vector((unsigned(i0)) * (unsigned(i1)));
o0 <= tmp(width-1 downto 0);
end Behavioral;
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_signed_mul is
generic(
width : natural
);
port (
i0 : in std_logic_vector(width-1 downto 0);
i1 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0)
);
end entity lava_signed_mul;
architecture Behavioral of lava_signed_mul is
signal tmp : std_logic_vector(2*width-1 downto 0);
begin
-- a version of multiply that has the same sized output
tmp <= std_logic_vector((signed(i0)) * (signed(i1)));
o0 <= tmp(width-1 downto 0);
end Behavioral;
--------------------------------------------------------------------------------
-- TO fix below this
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_sampled_add is
generic (
width : natural := 8; -- signal width
frac_width : natural := 8); -- value for max * min
port(i0 : in std_logic_vector(width-1 downto 0);
i1 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0));
end entity lava_sampled_add;
architecture Behavioral of lava_sampled_add is
signal tmp : signed(width-1 + 1 downto 0);
signal top2Bits : std_logic_vector(1 downto 0);
constant zeros : std_logic_vector(width - 2 downto 0) := (others => '0');
constant ones : std_logic_vector(width - 2 downto 0) := (others => '1');
begin
tmp <= signed (i0(width-1) & i0) + signed (i1(width-1) & i1);
top2Bits <= std_logic_vector(tmp(width downto width-1));
o0 <= '0' & ones when top2Bits = "01" else
'1' & zeros when top2Bits = "10" else
std_logic_vector(tmp(width-1 downto 0));
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_sampled_sub is
generic (
width : natural := 8; -- signal width
frac_width : natural := 8); -- value for max * min
port(i0 : in std_logic_vector(width-1 downto 0);
i1 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0));
end entity lava_sampled_sub;
architecture Behavioral of lava_sampled_sub is
signal tmp : signed(width-1 + 1 downto 0);
constant zeros : std_logic_vector(width - 2 downto 0) := (others => '0');
constant ones : std_logic_vector(width - 2 downto 0) := (others => '1');
begin
tmp <= signed (i0(width-1) & i0) - signed (i1(width-1) & i1);
o0 <= '0' & ones when tmp(width downto width-1) = "01" else
'1' & zeros when tmp(width downto width-1) = "10" else
std_logic_vector(tmp(width-1 downto 0));
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_sampled_mul is
generic (
width : natural := 8; -- signal width
frac_width : natural := 4); -- value for max * min
port(i0 : in std_logic_vector(width-1 downto 0);
i1 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0));
end entity lava_sampled_mul;
architecture Behavioral of lava_sampled_mul is
signal tmp : signed(2*width-1 downto 0);
signal topBits : signed(width-1 downto 0);
signal r0 : signed(2*width-1 downto frac_width);
signal r1 : signed(2*width-1 downto frac_width);
constant zeros : std_logic_vector(width - 2 downto 0) := (others => '0');
constant ones : std_logic_vector(width - 2 downto 0) := (others => '1');
begin
tmp <= signed (i0) * signed (i1);
r0 <= tmp(2*width-1 downto frac_width);
-- This is Round half to even (http://en.wikipedia.org/wiki/Rounding#Round_half_to_even)
r1 <= r0 when tmp(frac_width-1) = '0' else
r0 when tmp(frac_width) = '0' and tmp(frac_width-1) = '1' and tmp (frac_width - 2 downto 0) = 0 else
r0 + 1;
o0 <= std_logic_vector(r1(frac_width + width - 1 downto frac_width))
when r1(2*width-1 downto frac_width + width-1) = 0 else
std_logic_vector(r1(frac_width + width - 1 downto frac_width))
when r1(2*width-1 downto frac_width + width-1) = -1 else
'1' & zeros when tmp(2*width-1) = '1' else '0' & ones;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity lava_sampled_negate is
generic (
width : natural := 8; -- signal width
frac_width : natural := 8); -- value for max * min
port(i0 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0));
end entity lava_sampled_negate;
architecture Behavioral of lava_sampled_negate is
signal tmp : signed(width-1 + 1 downto 0);
constant zeros : std_logic_vector(width - 2 downto 0) := (others => '0');
constant ones : std_logic_vector(width - 2 downto 0) := (others => '1');
begin
tmp <= - signed (i0(width-1) & i0);
o0 <= '0' & ones when tmp(width downto width-1) = "01" else
'1' & zeros when tmp(width downto width-1) = "10" else
std_logic_vector(tmp(width-1 downto 0));
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity sampled_fixedDivPowOfTwo is
generic (
width : natural := 8; -- signal width
frac_width : natural := 8; -- value for max * min
shift_by : natural);
port(i0 : in std_logic_vector(width-1 downto 0);
o0 : out std_logic_vector(width-1 downto 0));
end entity sampled_fixedDivPowOfTwo;
architecture Behavioral of sampled_fixedDivPowOfTwo is
signal r0 : std_logic_vector(width-1 downto 0);
begin
-- sign extend
r0 <= (width-1 downto width-(shift_by +1) => i0(width-1)) & i0(width-2 downto shift_by);
-- This is Round half to even (http://en.wikipedia.org/wiki/Rounding#Round_half_to_even)
o0 <= r0 when i0(shift_by-1) = '0' else
r0 when i0(shift_by) = '0' and i0(shift_by-1) = '1' and (shift_by = 1 or i0(shift_by - 2 downto 0) = 0) else
r0 + 1;
end Behavioral;
-------------------------------------------------------------------------------
-- Flux stuff
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity upflux is
port(i0 : in std_logic_vector;
go : in std_logic;
clk_en : in std_logic;
clk : in std_logic;
rst : in std_logic;
o_en : out std_logic;
o0 : out std_logic_vector;
o_clk_en : out std_logic);
end entity upflux;
architecture Behavioral of upflux is
signal reg : std_logic := '0';
begin
o_en <= reg;
o0 <= i0; -- Flowthrough
o_clk_en <= go and clk_en; -- go, based on your clock enable
proc : process(rst, clk, clk_en) is
begin
if rising_edge(clk) then
if (clk_en = '1') then
reg <= go;
end if;
end if;
end process proc;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity downflux is
generic(
width : natural
);
port (i0 : in std_logic_vector(width-1 downto 0);
en : in std_logic;
clk : in std_logic;
rst : in std_logic;
clk_en : in std_logic;
go : out std_logic;
o0 : out std_logic_vector(width-1 downto 0));
end entity downflux;
architecture Behavioral of downflux is
signal reg : std_logic_vector(width-1 downto 0);
begin
go <= en; -- this signal becomes the clock enable.
o0 <= reg; -- this is a lava delay
proc : process(rst, clk, clk_en) is
begin
if rising_edge(clk) then
if (clk_en = '1') then
reg <= i0;
end if;
end if;
end process proc;
end Behavioral;