B
Bert_Paris
Guest
-- Fact_rtl.vhd
-- --------------------------------------------------
-- Factorial Example - Synthesizable & efficient !
-- --------------------------------------------------
-- Author : Bert Cuzeau. ALSE. http://www.alse-fr.com
-- Tested successfully with Quartus II v9.0.
-- but it should be fine with any decent synthesizer.
--
-- Note : added registers in front and after to easily
-- get the Tsu (Fmax) after synthesis
-- Synthesis results : 10 LUTs for the Factorial, as expected !
-- Timing : speed practically unlimited since 1 Logic Level (250Mhz on
Cyclone III)
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-- ---------------------------------------
Entity Factorial is
-- ---------------------------------------
port ( Clk : in std_logic;
Din : in std_logic_vector (2 downto 0); -- 0! .. 7! = 0
... 944
Result : out std_logic_vector (9 downto 0) ); -- 0 .. 1023
End Entity Factorial;
-- ---------------------------------------
Architecture RTL of Factorial is -- yes, this is perfect for
synthesis !
-- ---------------------------------------
-- The usual recursive function
function fact (d : natural) return natural is
variable res : natural;
begin
if d=0 then
res := 0;
elsif d=1 then
res := 1;
else
res := d * fact (d-1);
end if;
return res;
end function fact;
-- Constant table type
type Table_t is array (0 to 7) of unsigned(result'range);
-- Function to initialize a table with the factorial
impure function Init_Table return Table_t is
variable T : Table_t;
begin
for I in T'range loop
T(I) := to_unsigned(fact(I),Result'length);
end loop;
return T;
end function Init_Table;
-- The Table itself, initialized at creation :
signal Table : Table_t := Init_Table;
-- note ;: this table will be smplified in a few Logic Elements
signal Dinr : std_logic_vector (Din'range);
------\
begin -- Architecture
------/
Dinr <= Din when rising_edge(Clk); -- input FFs
result <= std_logic_vector(Table(to_integer(unsigned(Dinr)))) when
rising_edge(Clk);
end RTL;
------------------------------------------
-- Test Bench. Simulate -all
------------------------------------------
-- synopsys translate_off
library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all;
Entity factorial_tb is end;
Architecture test of factorial_tb is
signal Clk : std_logic := '0';
signal Din : std_logic_vector (2 downto 0) := "000"; -- 0! .. 7! =
840
signal Result : std_logic_vector (9 downto 0);
begin
assert Clk='0' or now < 500 ns report "Simulation has ended (not an
error)." severity failure;
Clk <= not Clk after 5 ns; -- 100 MHz clock
Din <= std_logic_vector (unsigned(Din)+1) after 40 ns; -- F/4
uut: entity work.factorial port map (Clk,Din,Result);
end architecture TEST;
-- synopsys translate_on
-- --------------------------------------------------
-- Factorial Example - Synthesizable & efficient !
-- --------------------------------------------------
-- Author : Bert Cuzeau. ALSE. http://www.alse-fr.com
-- Tested successfully with Quartus II v9.0.
-- but it should be fine with any decent synthesizer.
--
-- Note : added registers in front and after to easily
-- get the Tsu (Fmax) after synthesis
-- Synthesis results : 10 LUTs for the Factorial, as expected !
-- Timing : speed practically unlimited since 1 Logic Level (250Mhz on
Cyclone III)
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-- ---------------------------------------
Entity Factorial is
-- ---------------------------------------
port ( Clk : in std_logic;
Din : in std_logic_vector (2 downto 0); -- 0! .. 7! = 0
... 944
Result : out std_logic_vector (9 downto 0) ); -- 0 .. 1023
End Entity Factorial;
-- ---------------------------------------
Architecture RTL of Factorial is -- yes, this is perfect for
synthesis !
-- ---------------------------------------
-- The usual recursive function
function fact (d : natural) return natural is
variable res : natural;
begin
if d=0 then
res := 0;
elsif d=1 then
res := 1;
else
res := d * fact (d-1);
end if;
return res;
end function fact;
-- Constant table type
type Table_t is array (0 to 7) of unsigned(result'range);
-- Function to initialize a table with the factorial
impure function Init_Table return Table_t is
variable T : Table_t;
begin
for I in T'range loop
T(I) := to_unsigned(fact(I),Result'length);
end loop;
return T;
end function Init_Table;
-- The Table itself, initialized at creation :
signal Table : Table_t := Init_Table;
-- note ;: this table will be smplified in a few Logic Elements
signal Dinr : std_logic_vector (Din'range);
------\
begin -- Architecture
------/
Dinr <= Din when rising_edge(Clk); -- input FFs
result <= std_logic_vector(Table(to_integer(unsigned(Dinr)))) when
rising_edge(Clk);
end RTL;
------------------------------------------
-- Test Bench. Simulate -all
------------------------------------------
-- synopsys translate_off
library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all;
Entity factorial_tb is end;
Architecture test of factorial_tb is
signal Clk : std_logic := '0';
signal Din : std_logic_vector (2 downto 0) := "000"; -- 0! .. 7! =
840
signal Result : std_logic_vector (9 downto 0);
begin
assert Clk='0' or now < 500 ns report "Simulation has ended (not an
error)." severity failure;
Clk <= not Clk after 5 ns; -- 100 MHz clock
Din <= std_logic_vector (unsigned(Din)+1) after 40 ns; -- F/4
uut: entity work.factorial port map (Clk,Din,Result);
end architecture TEST;
-- synopsys translate_on