summaryrefslogtreecommitdiffstats
path: root/ieee_proposed
diff options
context:
space:
mode:
authorBert Lange <b.lange@fzd.de>2011-11-07 15:06:13 +0100
committerBert Lange <b.lange@fzd.de>2011-11-07 15:06:13 +0100
commit97dacd8ba4f2df6d93706f43f672a35cdfbbcf89 (patch)
treea3b67b8f8eb075ff6f40ba4f29ab6d40e5367eb5 /ieee_proposed
parent09b62e30ab072eafd4792104eb1f0971d1f96b5c (diff)
downloadzpu-97dacd8ba4f2df6d93706f43f672a35cdfbbcf89.zip
zpu-97dacd8ba4f2df6d93706f43f672a35cdfbbcf89.tar.gz
initial commit
Diffstat (limited to 'ieee_proposed')
-rw-r--r--ieee_proposed/rtl_tb/fixed_synth.vhd741
-rw-r--r--ieee_proposed/rtl_tb/float_synth.vhd712
-rw-r--r--ieee_proposed/rtl_tb/test_fixed_synth.vhd439
-rw-r--r--ieee_proposed/rtl_tb/test_float_synth.vhd892
4 files changed, 2784 insertions, 0 deletions
diff --git a/ieee_proposed/rtl_tb/fixed_synth.vhd b/ieee_proposed/rtl_tb/fixed_synth.vhd
new file mode 100644
index 0000000..67ea7a4
--- /dev/null
+++ b/ieee_proposed/rtl_tb/fixed_synth.vhd
@@ -0,0 +1,741 @@
+-- Synthesis test for the fixed point math package
+-- This test is designed to be synthesizable and exercise much of the package.
+-- Created for vhdl-200x by David Bishop (dbishop@vhdl.org)
+-- --------------------------------------------------------------------
+-- modification history : Last Modified $Date: 2006-06-08 10:49:35-04 $
+-- Version $Id: fixed_synth.vhdl,v 1.1 2006-06-08 10:49:35-04 l435385 Exp $
+-- --------------------------------------------------------------------
+
+
+library ieee, ieee_proposed;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee_proposed.fixed_float_types.all;
+use ieee_proposed.fixed_pkg.all;
+entity fixed_synth is
+
+ port (
+ in1, in2 : in STD_LOGIC_VECTOR (15 downto 0); -- inputs
+ out1 : out STD_LOGIC_VECTOR (15 downto 0); -- output
+ cmd : in STD_LOGIC_VECTOR (3 downto 0);
+ clk, rst_n : in STD_ULOGIC); -- clk and reset
+
+end entity fixed_synth;
+
+architecture rtl of fixed_synth is
+
+ subtype sfixed7 is sfixed (3 downto -3); -- 7 bit
+ subtype sfixed16 is sfixed (7 downto -8); -- 16 bit
+ type cmd_type is array (1 to 15) of STD_ULOGIC_VECTOR (cmd'range); -- cmd
+ signal cmdarray : cmd_type; -- command pipeline
+-- type cry_type is array (0 to 4) of sfixed16; -- arrays
+ signal outarray0, outarray1, outarray2, outarray3, outarray4,
+ outarray5, outarray6, outarray7, outarray8, outarray9, outarray10,
+ outarray11, outarray12, outarray13, outarray14, outarray15 : sfixed16;
+ signal in1reg3, in2reg3 : sfixed16; -- register stages
+begin -- architecture rtl
+
+ -- purpose: "0000" test the "+" operator
+ cmd0reg : process (clk, rst_n) is
+ variable in1pin2 : sfixed (SFixed_high(7, -8, '+', 7, -8) downto
+ SFixed_low(7, -8, '+', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray0 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray0 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ in1pin2 := in1reg3 + in2reg3;
+ outarray0 <= resize (in1pin2, outarray0);
+ end if;
+ end process cmd0reg;
+
+ -- purpose: "0001" test the "-" operator
+ cmd1reg : process (clk, rst_n) is
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+-- variable in1min2 : sfixed (SFixed_high(in1reg3, '-', in2reg3) downto
+-- SFixed_low(in1reg3, '-', in2reg3));
+ variable in1min2 : sfixed (SFixed_high(7, -8, '-', 7, -8) downto
+ SFixed_low(7, -8, '-', 7, -8));
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray1 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray1 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ in1min2 := in1reg3 - in2reg3;
+ outarray1 <= resize (in1min2, outarray1);
+ end if;
+ end process cmd1reg;
+
+ -- purpose: "0010" test the "*" operator
+ cmd2reg : process (clk, rst_n) is
+-- variable in1min2 : sfixed (SFixed_high(in1reg3, '*', in2reg3) downto
+-- SFixed_low(in1reg3, '*', in2reg3));
+ variable in1min2 : sfixed (SFixed_high(7, -8, '*', 7, -8) downto
+ SFixed_low(7, -8, '*', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray2 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray2 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ in1min2 := in1reg3 * in2reg3;
+ outarray2 <= resize (in1min2, outarray2);
+ end if;
+ end process cmd2reg;
+
+ -- purpose: "0011" test the "/" operator
+-- cmd3reg : process (clk, rst_n) is
+-- variable in1min2 : sfixed (SFixed_high(in1reg3'high, in1reg3'low,
+-- '/', in2reg3'high, in2reg3'low)
+-- downto
+-- SFixed_low(in1reg3'high, in1reg3'low,
+-- '/', in2reg3'high, in2reg3'low));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+-- begin -- process cmd3reg
+-- if rst_n = '0' then -- asynchronous reset (active low)
+-- outarray3 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := to_sfixed(1, in2array(0));
+-- end loop jrloop;
+-- elsif rising_edge(clk) then -- rising clock edge
+-- outarray3 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- if (in2reg3 = 0) then
+-- in2array(0) := to_sfixed(1, in2array(0));
+-- else
+-- in2array(0) := in2reg3;
+-- end if;
+-- in1min2 := in1array(3) / in2array(3);
+-- outarray(0) := resize (in1min2, outarray(0));
+-- end if;
+-- end process cmd3reg;
+ outarray3 <= (others => '0');
+
+ -- purpose: "0100" test the "+" operator
+ cmd4reg : process (clk, rst_n) is
+ variable in1pin2 : ufixed (uFixed_high(7, -8, '+', 7, -8) downto
+ uFixed_low(7, -8, '+', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray4 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray4 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ in1pin2 := ufixed(in1reg3) + ufixed(in2reg3);
+ outarray4 <= sfixed (resize (in1pin2, outarray4'high, outarray4'low));
+ end if;
+ end process cmd4reg;
+
+ -- purpose: "0101" test the "-" operator
+ cmd5reg : process (clk, rst_n) is
+ variable in1min2 : ufixed (uFixed_high(7, -8, '-', 7, -8) downto
+ uFixed_low(7, -8, '-', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray5 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray5 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ in1min2 := ufixed(in1reg3) - ufixed(in2reg3);
+ outarray5 <= sfixed(resize (in1min2, outarray5'high, outarray5'low));
+ end if;
+ end process cmd5reg;
+
+ -- purpose: "0110" test the "*" operator
+ cmd6reg : process (clk, rst_n) is
+ variable in1min2 : ufixed (uFixed_high(7, -8, '*', 7, -8) downto
+ uFixed_low(7, -8, '*', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray6 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray6 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ in1min2 := ufixed(in1reg3) * ufixed(in2reg3);
+ outarray6 <= sfixed(resize (in1min2, outarray6'high, outarray6'low));
+ end if;
+ end process cmd6reg;
+
+ -- purpose: "0111" test the "/" operator
+-- cmd7reg : process (clk, rst_n) is
+-- variable in1min2 : ufixed (uFixed_high(7, -8, '/', 7, -8) downto
+-- uFixed_low(7, -8, '/', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+-- begin -- process cmd0reg
+-- if rst_n = '0' then -- asynchronous reset (active low)
+-- outarray7 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := sfixed(to_ufixed(1, in2reg3'high, in2reg3'low));
+-- end loop jrloop;
+-- elsif rising_edge(clk) then -- rising clock edge
+-- outarray7 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- if (in2reg3 = 0) then
+-- in2array(0) := sfixed(to_ufixed(1, in2reg3'high, in2reg3'low));
+-- else
+-- in2array(0) := in2reg3;
+-- end if;
+-- in1min2 := ufixed(in1array(3)) / ufixed(in2array(3));
+-- outarray(0) := sfixed(resize (in1min2, outarray7'high, outarray7'low));
+-- end if;
+-- end process cmd7reg;
+ outarray7 <= (others => '0');
+
+ -- purpose: "1000" test the resize test
+ cmd8reg : process (clk, rst_n) is
+ variable tmpfp71, tmpfp72 : sfixed7; -- 8 bit fp number
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray8 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray8 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ -- Resize test Convert inputs into two 8 bit numbers
+ tmpfp71 := resize (in1reg3, tmpfp71'high, tmpfp71'low,
+ fixed_wrap, fixed_truncate);
+ tmpfp72 := resize (in2reg3, tmpfp72'high, tmpfp72'low,
+ fixed_saturate, fixed_round);
+ outarray8 <= (others => '0');
+ fx1 : for i in tmpfp71'range loop
+ outarray8(i+4) <= tmpfp71(i);
+ end loop fx1;
+ fx2 : for i in tmpfp72'range loop
+ outarray8(i-4) <= tmpfp72(i);
+ end loop fx2;
+ end if;
+ end process cmd8reg;
+
+ -- purpose: "1001" test the to_signed/unsigned test
+ cmd9reg : process (clk, rst_n) is
+ variable tmp : STD_LOGIC_VECTOR (1 downto 0); -- temp
+ variable tmpsig : SIGNED (7 downto 0); -- signed number
+ variable tmpuns : UNSIGNED (15 downto 0); -- unsigned number
+ variable tmpint : INTEGER;
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray9 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray9 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ tmp := to_slv (in2reg3(in2reg3'high downto in2reg3'high-1));
+ if (tmp = "00") then
+ -- Signed to sfixed and back
+ tmpsig := to_signed (in1reg3, tmpsig'length);
+ outarray9 <= to_sfixed (tmpsig, outarray9);
+ elsif (tmp = "01") then
+ -- unsigned to ufixed and back
+ tmpuns := to_unsigned (ufixed(in1reg3), tmpuns'length);
+ outarray9 <= sfixed(to_ufixed (tmpuns, outarray9'high,
+ outarray9'low));
+ elsif (tmp = "10") then
+ tmpint := to_integer (in1reg3);
+ outarray9 <= to_sfixed (tmpint, outarray9);
+ else
+ tmpint := to_integer (ufixed(in1reg3));
+ outarray9 <= sfixed(to_ufixed (tmpint, outarray9'high,
+ outarray9'low));
+
+ end if;
+ end if;
+ end process cmd9reg;
+
+ -- purpose: "1010" test the reciprocal, abs, - test
+-- cmd10reg : process (clk, rst_n) is
+-- variable tmp : STD_LOGIC_VECTOR (1 downto 0); -- temp
+-- variable in1recip : sfixed (-in1reg3'low+1 downto -in1reg3'high);
+-- variable uin1recip : ufixed (-in1reg3'low downto -in1reg3'high-1);
+-- variable in1pin2 : sfixed (SFixed_high(7, -8, '+', 7, -8) downto
+-- SFixed_low(7, -8, '+', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+-- begin -- process cmd0reg
+-- if rst_n = '0' then -- asynchronous reset (active low)
+-- outarray10 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := to_sfixed(1, in1reg3);
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+-- elsif rising_edge(clk) then -- rising clock edge
+-- outarray10 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- if (in1reg3 = 0) then
+-- in1array(0) := to_sfixed(1, in1reg3);
+-- else
+-- in1array(0) := in1reg3;
+-- end if;
+-- in2array(0) := in2reg3;
+-- tmp := to_slv (in2array(3)(in2reg3'high downto in2reg3'high-1));
+-- if (tmp = "00") then
+-- in1recip := reciprocal (in1reg3);
+-- outarray(0) := resize (in1recip, outarray(0)'high,
+-- outarray(0)'low);
+-- elsif (tmp = "01") then
+-- uin1recip := reciprocal (ufixed(in1reg3));
+-- outarray(0) := sfixed(resize (uin1recip, outarray(0)'high,
+-- outarray(0)'low));
+-- elsif (tmp = "10") then
+-- -- abs
+-- in1pin2 := abs(in1reg3);
+-- outarray(0) := resize (in1pin2,
+-- outarray(0)'high,
+-- outarray(0)'low);
+-- else
+-- -- -
+-- in1pin2 := - in1reg3;
+-- outarray(0) := resize (in1pin2,
+-- outarray(0)'high,
+-- outarray(0)'low);
+-- end if;
+-- end if;
+-- end process cmd10reg;
+ outarray10 <= (others => '0');
+
+ -- purpose: "1011" test the mod operator
+-- cmd11reg : process (clk, rst_n) is
+-- variable in1min2 : sfixed (SFixed_high(7, -8, 'M', 7, -8) downto
+-- SFixed_low(7, -8, 'm', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+-- begin -- process cmd0reg
+-- if rst_n = '0' then -- asynchronous reset (active low)
+-- outarray11 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := to_sfixed(1, in2array(0));
+-- end loop jrloop;
+-- elsif rising_edge(clk) then -- rising clock edge
+-- outarray11 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- if (in2reg3 = 0) then
+-- in2array(0) := to_sfixed(1, in2array(0));
+-- else
+-- in2array(0) := in2reg3;
+-- end if;
+-- in1min2 := in1reg3 mod in2array(3);
+-- outarray(0) := resize (in1min2, outarray(0));
+-- end if;
+-- end process cmd11reg;
+ outarray11 <= (others => '0');
+
+ -- purpose: "1100" test the rem operator
+-- cmd12reg : process (clk, rst_n) is
+-- variable in1min2 : sfixed (SFixed_high(7, -8, 'R', 7, -8) downto
+-- SFixed_low(7, -8, 'r', 7, -8));
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+-- begin -- process cmd0reg
+-- if rst_n = '0' then -- asynchronous reset (active low)
+-- outarray12 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := to_sfixed(1, in2array(0));
+-- end loop jrloop;
+-- elsif rising_edge(clk) then -- rising clock edge
+-- outarray12 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- if (in2reg3 = 0) then
+-- in2array(0) := to_sfixed(1, in2array(0));
+-- else
+-- in2array(0) := in2reg3;
+-- end if;
+-- in1min2 := in1reg3 rem in2array(3);
+-- outarray(0) := resize (in1min2, outarray(0));
+-- end if;
+-- end process cmd12reg;
+ outarray12 <= (others => '0');
+
+ -- purpose: "1101" test the srl operator
+ cmd13reg : process (clk, rst_n) is
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray13 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray13 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ outarray13 <= in1reg3 srl to_integer(in2reg3);
+ end if;
+ end process cmd13reg;
+
+ -- purpose: "1110" test the sra operator
+ cmd14reg : process (clk, rst_n) is
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray14 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray14 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ outarray14 <= in1reg3 sra to_integer(in2reg3);
+ end if;
+ end process cmd14reg;
+
+ -- purpose: "1111" test the sra operator
+ cmd15reg : process (clk, rst_n) is
+ constant match_data : sfixed16 := "01HL----10HL----"; -- for ?= command
+-- variable outarray : cry_type; -- array for output
+-- variable in1array, in2array : cry_type; -- array for input
+ begin -- process cmd0reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outarray15 <= (others => '0');
+-- jrloop : for j in 0 to 4 loop
+-- outarray (j) := (others => '0');
+-- in1array (j) := (others => '0');
+-- in2array (j) := (others => '0');
+-- end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+-- outarray15 <= outarray(4);
+-- jcloop : for j in 4 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- j1loop : for j in 3 downto 1 loop
+-- in1array (j) := in1array(j-1);
+-- end loop j1loop;
+-- j2loop : for j in 3 downto 1 loop
+-- in2array (j) := in2array(j-1);
+-- end loop j2loop;
+-- in1array(0) := in1reg3;
+-- in2array(0) := in2reg3;
+ -- compare test
+ if (in1reg3 = in2reg3) then
+ outarray15(-8) <= '1';
+ else
+ outarray15(-8) <= '0';
+ end if;
+ if (in1reg3 /= in2reg3) then
+ outarray15(-7) <= '1';
+ else
+ outarray15(-7) <= '0';
+ end if;
+ if (in1reg3 < in2reg3) then
+ outarray15(-6) <= '1';
+ else
+ outarray15(-6) <= '0';
+ end if;
+ if (in1reg3 > in2reg3) then
+ outarray15(-5) <= '1';
+ else
+ outarray15(-5) <= '0';
+ end if;
+ if (in1reg3 <= in2reg3) then
+ outarray15(-4) <= '1';
+ else
+ outarray15(-4) <= '0';
+ end if;
+ if (in1reg3 >= in2reg3) then
+ outarray15(-3) <= '1';
+ else
+ outarray15(-3) <= '0';
+ end if;
+ if (in1reg3 = 45) then
+ outarray15(-2) <= '1';
+ else
+ outarray15(-2) <= '0';
+ end if;
+ if (in1reg3 = 3.125) then
+ outarray15(-1) <= '1';
+ else
+ outarray15(-1) <= '0';
+ end if;
+ -- add integer and real
+ outarray15(0) <= \?=\ (in1reg3, in2reg3 + 45);
+ if (in1reg3 = in2reg3 + 3.125) then
+ outarray15(1) <= '1';
+ else
+ outarray15(1) <= '0';
+ end if;
+ if (std_match (in1reg3, match_data)) then
+ outarray15(2) <= '1';
+ else
+ outarray15(2) <= '0';
+ end if;
+ outarray15(3) <= nor_reduce (in1reg3 or in2reg3);
+ outarray15(4) <= xnor_reduce (in1reg3 xor in2reg3);
+ outarray15(5) <= nand_reduce (not in1reg3);
+ outarray15(6) <= or_reduce ('1' and ufixed(in1reg3));
+ if find_leftmost(in1reg3, '1') = 3 then
+ outarray15(7) <= '1';
+ else
+ outarray15(7) <= '0';
+ end if;
+ end if;
+ end process cmd15reg;
+
+ -- purpose: register the inputs and the outputs
+ -- type : sequential
+ -- inputs : clk, rst_n, in1, in2
+ -- outputs: out1
+ cmdreg : process (clk, rst_n) is
+ variable outreg : sfixed16; -- register stages
+ variable in1reg, in2reg : sfixed16; -- register stages
+ variable in1reg2, in2reg2 : sfixed16; -- register stages
+ begin -- process mulreg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ in1reg := (others => '0');
+ in2reg := (others => '0');
+ in1reg2 := (others => '0');
+ in2reg2 := (others => '0');
+ in1reg3 <= (others => '0');
+ in2reg3 <= (others => '0');
+ out1 <= (others => '0');
+ outreg := (others => '0');
+ rcloop : for i in 1 to 15 loop
+ cmdarray (i) <= (others => '0');
+ end loop rcloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ out1 <= to_slv (outreg);
+ outregc : case cmdarray (13) is
+ when "0000" => outreg := outarray0;
+ when "0001" => outreg := outarray1;
+ when "0010" => outreg := outarray2;
+ when "0011" => outreg := outarray3;
+ when "0100" => outreg := outarray4;
+ when "0101" => outreg := outarray5;
+ when "0110" => outreg := outarray6;
+ when "0111" => outreg := outarray7;
+ when "1000" => outreg := outarray8;
+ when "1001" => outreg := outarray9;
+ when "1010" => outreg := outarray10;
+ when "1011" => outreg := outarray11;
+ when "1100" => outreg := outarray12;
+ when "1101" => outreg := outarray13;
+ when "1110" => outreg := outarray14;
+ when "1111" => outreg := outarray15;
+ when others => null;
+ end case outregc;
+ cmdpipe : for i in 15 downto 3 loop
+ cmdarray (i) <= cmdarray (i-1);
+ end loop cmdpipe;
+ cmdarray (2) <= STD_ULOGIC_VECTOR(cmd);
+ in1reg3 <= in1reg2;
+ in2reg3 <= in2reg2;
+ in1reg2 := in1reg;
+ in2reg2 := in2reg;
+ in1reg := to_sfixed (in1, in1reg);
+ in2reg := to_sfixed (in2, in2reg);
+ end if;
+ end process cmdreg;
+
+end architecture rtl;
diff --git a/ieee_proposed/rtl_tb/float_synth.vhd b/ieee_proposed/rtl_tb/float_synth.vhd
new file mode 100644
index 0000000..be9786e
--- /dev/null
+++ b/ieee_proposed/rtl_tb/float_synth.vhd
@@ -0,0 +1,712 @@
+-------------------------------------------------------------------------------
+-- Synthesis test for the floating point math package
+-- This test is designed to be synthesizable and exercise much of the package.
+-- Created for vhdl-200x by David Bishop (dbishop@vhdl.org)
+-- --------------------------------------------------------------------
+-- modification history : Last Modified $Date: 2006-06-08 10:50:32-04 $
+-- Version $Id: float_synth.vhdl,v 1.1 2006-06-08 10:50:32-04 l435385 Exp $
+-------------------------------------------------------------------------------
+library ieee, ieee_proposed;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee_proposed.fixed_float_types.all;
+use ieee_proposed.fixed_pkg.all;
+use ieee_proposed.float_pkg.all;
+use ieee.math_real.all;
+entity float_synth is
+
+ port (
+ in1, in2 : in std_logic_vector (31 downto 0); -- inputs
+ out1 : out std_logic_vector (31 downto 0); -- output
+ cmd : in std_logic_vector (3 downto 0);
+ clk, rst_n : in std_ulogic); -- clk and reset
+
+end entity float_synth;
+
+architecture rtl of float_synth is
+ subtype fp16 is float (6 downto -9); -- 16 bit
+
+ type cmd_type is array (1 to 15) of std_ulogic_vector (cmd'range); -- cmd
+ signal cmdarray : cmd_type; -- command pipeline
+ type cry_type is array (0 to 15) of float32; -- arrays
+ signal outx : cry_type;
+ signal in1reg3, in2reg3 : float32; -- register stages
+
+begin -- architecture rtl
+
+ -- purpose: "0000" test the "+" operator
+ cmd0reg: process (clk, rst_n) is
+ variable outarray : cry_type; -- array for output
+ begin -- process cmd0reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(0) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(0) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ outarray(0) := in1reg3 + in2reg3;
+ end if;
+
+ end process cmd0reg;
+
+ -- purpose: "0001" test the "-" operator
+ cmd1reg: process (clk, rst_n) is
+ variable outarray : cry_type; -- array for output
+ begin -- process cmd1reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(1) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(1) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ outarray(0) := in1reg3 - in2reg3;
+ end if;
+
+ end process cmd1reg;
+
+ -- purpose: "0010" test the "*" operator
+ cmd2reg: process (clk, rst_n) is
+ variable outarray : cry_type; -- array for output
+ begin -- process cmd2reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(2) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(2) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ outarray(0) := in1reg3 * in2reg3;
+ end if;
+
+ end process cmd2reg;
+
+ -- purpose: "0011" performs test the "/" operator
+ cmd3reg: process (clk, rst_n) is
+ variable outarray : cry_type; -- array for output
+ begin -- process cmd1reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(3) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(3) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ if (cmdarray(4) = "0011") then
+ outarray(0) := in1reg3 / in2reg3;
+ else
+ outarray(0) := (others => '0');
+ end if;
+ end if;
+ end process cmd3reg;
+
+ -- purpose: "0100" test the "resize" function
+ cmd4reg: process (clk, rst_n) is
+ variable tmpfp161, tmpfp162 : fp16; -- 16 bit fp number
+ variable outarray : cry_type; -- array for output
+ variable tmpcmd : STD_LOGIC_VECTOR (2 downto 0);
+ begin -- process cmd1reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(4) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(4) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ tmpcmd := to_slv (in2reg3 (in2reg3'low+2 downto in2reg3'low));
+ case tmpcmd is
+ when "000" =>
+ tmpfp161 := resize ( arg => in1reg3,
+ exponent_width => tmpfp161'high,
+ fraction_width => -tmpfp161'low,
+ denormalize_in => true,
+ denormalize => false,
+ round_style => round_zero);
+ when "001" =>
+ tmpfp161 := resize ( arg => in1reg3,
+-- size_res => tmpfp161,
+ exponent_width => tmpfp161'high,
+ fraction_width => -tmpfp161'low,
+ denormalize_in => false,
+ denormalize => false);
+ when "010" =>
+ tmpfp161 := resize ( arg => in1reg3,
+ exponent_width => tmpfp161'high,
+ fraction_width => -tmpfp161'low,
+ denormalize_in => false,
+ denormalize => false);
+ when "011" =>
+ tmpfp161 := resize ( arg => in1reg3,
+-- size_res => tmpfp161,
+ exponent_width => tmpfp161'high,
+ fraction_width => -tmpfp161'low,
+ denormalize_in => true,
+ denormalize => false,
+ round_style => round_inf);
+ when "100" =>
+ tmpfp161 := resize ( arg => in1reg3,
+ exponent_width => tmpfp161'high,
+ fraction_width => -tmpfp161'low,
+ denormalize_in => true,
+ denormalize => false,
+ round_style => round_neginf);
+ when "101" =>
+ tmpfp161 := resize ( arg => in1reg3,
+-- size_res => tmpfp161,
+ exponent_width => tmpfp161'high,
+ fraction_width => -tmpfp161'low,
+ denormalize_in => true,
+ denormalize => false,
+ check_error => false,
+ round_style => round_zero);
+ when "110" =>
+ tmpfp161 := resize ( arg => in1reg3,
+ exponent_width => tmpfp161'high,
+ fraction_width => -tmpfp161'low);
+ when "111" =>
+ tmpfp161 := resize ( arg => in1reg3,
+ exponent_width => tmpfp161'high,
+ fraction_width => -tmpfp161'low
+-- size_res => tmpfp161
+ );
+ when others => null;
+ end case;
+ outarray(0)(-8 downto -23) := tmpfp161;
+ outarray(0)(8 downto 6) := float(tmpcmd);
+ outarray(0)(6 downto -7) := (others => '0');
+ end if;
+ end process cmd4reg;
+
+ -- purpose: "0101" Conversion function test
+ cmd5reg: process (clk, rst_n) is
+ variable uns : unsigned (15 downto 0); -- unsigned number
+ variable s : signed (15 downto 0); -- signed number
+ variable uf : ufixed (8 downto -7); -- unsigned fixed
+ variable sf : sfixed (8 downto -7); -- signed fixed point
+ variable outarray : cry_type; -- array for output
+ variable tmpcmd : STD_LOGIC_VECTOR (2 downto 0);
+ begin -- process cmd1reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(5) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(5) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ tmpcmd := to_slv (in2reg3 (in2reg3'low+2 downto in2reg3'low));
+ case tmpcmd is
+ when "000" =>
+ uns := to_unsigned (in1reg3, uns'length);
+ outarray(0)(-8 downto -23) := float(std_logic_vector(uns));
+ when "001" =>
+ uns := to_unsigned (in1reg3, uns);
+ outarray(0)(-8 downto -23) := float(std_logic_vector(uns));
+ when "010" =>
+ s := to_signed (in1reg3, s'length);
+ outarray(0)(-8 downto -23) := float(std_logic_vector(s));
+ when "011" =>
+ s := to_signed (in1reg3, s);
+ outarray(0)(-8 downto -23) := float(std_logic_vector(s));
+ when "100" =>
+ uf := to_ufixed (in1reg3, uf'high, uf'low);
+ outarray(0)(-8 downto -23) := float(to_slv(uf));
+ when "101" =>
+ uf := to_ufixed (in1reg3, uf);
+ outarray(0)(-8 downto -23) := float(to_slv(uf));
+ when "110" =>
+ sf := to_sfixed (in1reg3, sf'high, sf'low);
+ outarray(0)(-8 downto -23) := float(to_slv(sf));
+ when "111" =>
+ sf := to_sfixed (in1reg3, sf);
+ outarray(0)(-8 downto -23) := float(to_slv(sf));
+ when others => null;
+ end case;
+ outarray(0)(8 downto 6) := float(tmpcmd);
+ outarray(0)(5 downto -7) := (others => '0');
+ end if;
+ end process cmd5reg;
+
+ -- purpose: "0110" to_float()
+ cmd6reg: process (clk, rst_n) is
+ variable uns : unsigned (15 downto 0); -- unsigned number
+ variable s : signed (15 downto 0); -- signed number
+ variable uf : ufixed (8 downto -7); -- unsigned fixed
+ variable sf : sfixed (8 downto -7); -- signed fixed point
+ variable outarray : cry_type; -- array for output
+ variable tmpcmd : STD_LOGIC_VECTOR (2 downto 0);
+ begin -- process cmd1reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(6) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(6) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ tmpcmd := to_slv (in2reg3 (in2reg3'low+2 downto in2reg3'low));
+ case tmpcmd is
+ when "000" =>
+ uns := UNSIGNED (to_slv (in1reg3(-8 downto -23)));
+ outarray(0) := to_float(uns, 8, 23);
+ when "001" =>
+ uns := UNSIGNED (to_slv (in1reg3(-8 downto -23)));
+ outarray(0) := to_float(uns, in1reg3);
+ when "010" =>
+ s := SIGNED (to_slv (in1reg3(-8 downto -23)));
+ outarray(0) := to_float(s, 8, 23);
+ when "011" =>
+ s := SIGNED (to_slv (in1reg3(-8 downto -23)));
+ outarray(0) := to_float(s, in1reg3);
+ when "100" =>
+ uf := to_ufixed (to_slv (in1reg3(-8 downto -23)), uf'high, uf'low);
+ outarray(0) := to_float(uf, 8, 23);
+ when "101" =>
+ uf := to_ufixed (to_slv (in1reg3(-8 downto -23)), uf);
+ outarray(0) := to_float(uf, in1reg3);
+ when "110" =>
+ sf := to_sfixed (to_slv (in1reg3(-8 downto -23)), sf'high, sf'low);
+ outarray(0) := to_float(sf, 8, 23);
+ when "111" =>
+ sf := to_sfixed (to_slv (in1reg3(-8 downto -23)), sf);
+ outarray(0) := to_float(sf, in1reg3);
+ when others => null;
+ end case;
+ end if;
+ end process cmd6reg;
+
+ -- purpose: "0111" mod function
+-- cmd7reg: process (clk, rst_n) is
+-- variable tmpuns : unsigned (31 downto 0); -- unsigned number
+-- variable outarray : cry_type; -- array for output
+-- begin -- process cmd1reg
+-- if rst_n = '0' then -- asynchronous reset (active low)
+-- outx(7) <= ( others => '0');
+-- jrloop: for j in 0 to 7 loop
+-- outarray (j) := (others => '0');
+-- end loop jrloop;
+-- elsif rising_edge(clk) then -- rising clock edge
+-- outx(7) <= outarray(7);
+-- jcloop: for j in 7 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- outarray(0) := in1reg3 mod in2reg3;
+-- end if;
+-- end process cmd7reg;
+ outx(7) <= (others => '0');
+
+ -- purpose: "1000" rem function
+-- cmd8reg: process (clk, rst_n) is
+-- variable outarray : cry_type; -- array for output
+-- begin -- process cmd2reg
+
+-- if rst_n = '0' then -- asynchronous reset (active low)
+-- outx(8) <= ( others => '0');
+-- jrloop: for j in 0 to 7 loop
+-- outarray (j) := (others => '0');
+-- end loop jrloop;
+-- elsif rising_edge(clk) then -- rising clock edge
+-- outx(8) <= outarray(7);
+-- jcloop: for j in 7 downto 1 loop
+-- outarray (j) := outarray(j-1);
+-- end loop jcloop;
+-- outarray(0) := in1reg3 rem in2reg3;
+-- end if;
+
+-- end process cmd8reg;
+ outx(8) <= (others => '0');
+
+ -- purpose: "1001" to_float (constants) test
+ cmd9reg: process (clk, rst_n) is
+ variable outarray : cry_type; -- array for output
+ variable tmpcmd : STD_LOGIC_VECTOR (2 downto 0);
+ begin -- process cmd2reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(9) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(9) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ tmpcmd := to_slv (in2reg3 (in2reg3'low+2 downto in2reg3'low));
+ case tmpcmd is
+ when "000" =>
+ outarray(0) := to_float(0, 8, 23);
+ when "001" =>
+ outarray(0) := to_float(0.0, 8, 23);
+ when "010" =>
+ outarray(0) := to_float(8, in1reg3);
+ when "011" =>
+ outarray(0) := to_float(8.0, in1reg3);
+ when "100" =>
+ outarray(0) := to_float(-8, 8, 23);
+ when "101" =>
+ outarray(0) := to_float(-8.0, 8, 23);
+ when "110" =>
+ outarray(0) := to_float(27000, in2reg3);
+ when "111" =>
+-- outarray(0) := "01000000010010010000111111011011";
+ outarray(0) := to_float(MATH_PI, in2reg3);
+ when others => null;
+ end case;
+ end if;
+
+ end process cmd9reg;
+
+ -- purpose: "1010" data manipulation (+, -, scalb, etc)
+ cmd10reg: process (clk, rst_n) is
+ variable tmpcmd : STD_LOGIC_VECTOR (2 downto 0);
+ variable s : SIGNED (7 downto 0); -- signed number
+ variable outarray : cry_type; -- array for output
+ constant posinf : float32 := "01111111100000000000000000000000"; -- +inf
+ constant neginf : float32 := "11111111100000000000000000000000"; -- +inf
+ constant onept5 : float32 := "00111111110000000000000000000000"; -- 1.5
+ begin -- process cmd2reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(10) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(10) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ tmpcmd := to_slv (in2reg3 (in2reg3'low+2 downto in2reg3'low));
+ case tmpcmd is
+ when "000" =>
+ outarray(0) := - in1reg3;
+ when "001" =>
+ outarray(0) := abs( in1reg3);
+ when "010" =>
+ if (cmdarray(4) = "1010") then
+ s := resize (SIGNED (to_slv (in2reg3(8 downto 5))), s'length);
+ outarray(0) := Scalb (in1reg3, s);
+ else
+ outarray(0) := (others => '0');
+ end if;
+ when "011" =>
+ if (cmdarray(4) = "1010") then
+ s := logb (in1reg3);
+ outarray(0) := (others => '0');
+ outarray(0)(-16 downto -23) := float(std_logic_vector(s));
+ else
+ outarray(0) := (others => '0');
+ end if;
+-- when "100" =>
+-- outarray(0) := Nextafter ( in1reg3, onept5);
+-- when "101" =>
+-- outarray(0) := Nextafter ( in1reg3, -onept5);
+-- when "110" =>
+-- outarray(0) := Nextafter ( x => in1reg3, y => posinf,
+-- check_error => false,
+-- denormalize => false);
+-- when "111" =>
+-- outarray(0) := Nextafter (x => in1reg3, y => neginf,
+-- check_error => false,
+-- denormalize => false);
+ when others =>
+ outarray(0) := (others => '0');
+ end case;
+ end if;
+
+ end process cmd10reg;
+
+ -- purpose "1011" copysign
+ cmd11reg: process (clk, rst_n) is
+ variable outarray : cry_type; -- array for output
+ begin -- process cmd2reg
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(11) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(11) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ outarray(0) := Copysign (in1reg3, in2reg3);
+ end if;
+ end process cmd11reg;
+
+ -- purpose "1100" compare test
+ cmd12reg: process (clk, rst_n) is
+ variable outarray : cry_type; -- array for output
+ constant fifteenpt5 : float32 := "01000001011110000000000000000000";-- 15.5
+ begin -- process cmd2reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(12) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(12) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ outarray(0) := (others => '0');
+ if (in1reg3 = in2reg3) then
+ outarray(0)(outarray(0)'high) := '1';
+ else
+ outarray(0)(outarray(0)'high) := '0';
+ end if;
+ if (in1reg3 /= in2reg3) then
+ outarray(0)(outarray(0)'high-1) := '1';
+ else
+ outarray(0)(outarray(0)'high-1) := '0';
+ end if;
+ if (in1reg3 > in2reg3) then
+ outarray(0)(outarray(0)'high-2) := '1';
+ else
+ outarray(0)(outarray(0)'high-2) := '0';
+ end if;
+ if (in1reg3 < in2reg3) then
+ outarray(0)(outarray(0)'high-3) := '1';
+ else
+ outarray(0)(outarray(0)'high-3) := '0';
+ end if;
+ if (in1reg3 >= in2reg3) then
+ outarray(0)(outarray(0)'high-4) := '1';
+ else
+ outarray(0)(outarray(0)'high-4) := '0';
+ end if;
+ if (in1reg3 <= in2reg3) then
+ outarray(0)(outarray(0)'high-5) := '1';
+ else
+ outarray(0)(outarray(0)'high-5) := '0';
+ end if;
+ outarray(0)(outarray(0)'high-6) := \?=\ (in1reg3, 15);
+ outarray(0)(outarray(0)'high-7) := \?=\ (in1reg3, 15.5);
+ if (Unordered (in1reg3, in2reg3)) then
+ outarray(0)(outarray(0)'high-8) := '1';
+ else
+ outarray(0)(outarray(0)'high-8) := '0';
+ end if;
+ if (Finite (in1reg3)) then
+ outarray(0)(outarray(0)'high-9) := '1';
+ else
+ outarray(0)(outarray(0)'high-9) := '0';
+ end if;
+ if (Isnan (in1reg3)) then
+ outarray(0)(outarray(0)'high-10) := '1';
+ else
+ outarray(0)(outarray(0)'high-10) := '0';
+ end if;
+ end if;
+
+ end process cmd12reg;
+
+ -- purpose "1101" boolean test
+ cmd13reg: process (clk, rst_n) is
+ variable tmpcmd : STD_LOGIC_VECTOR (2 downto 0);
+ variable outarray : cry_type; -- array for output
+ begin -- process cmd2reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(13) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(13) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ tmpcmd := to_slv (in2reg3 (in2reg3'low+2 downto in2reg3'low));
+ case tmpcmd is
+ when "000" =>
+ outarray(0) := not (in1reg3);
+ when "001" =>
+ outarray(0) := in1reg3 and in2reg3;
+ when "010" =>
+ outarray(0) := in1reg3 or in2reg3;
+ when "011" =>
+ outarray(0) := in1reg3 nand in2reg3;
+ when "100" =>
+ outarray(0) := in1reg3 nor in2reg3;
+ when "101" =>
+ outarray(0) := in1reg3 xor in2reg3;
+ when "110" =>
+ outarray(0) := in1reg3 xnor in2reg3;
+ when "111" =>
+ outarray(0) := in1reg3 xor '1';
+ when others => null;
+ end case;
+ end if;
+
+ end process cmd13reg;
+
+ -- purpose "1110" reduce and vector test
+ cmd14reg: process (clk, rst_n) is
+ variable tmpcmd : STD_LOGIC_VECTOR (2 downto 0);
+ variable outarray : cry_type; -- array for output
+ begin -- process cmd2reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(14) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(14) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ tmpcmd := to_slv (in2reg3 (in2reg3'low+2 downto in2reg3'low));
+ case tmpcmd is
+ when "000" =>
+ outarray(0) := (others => '0');
+ outarray(0)(outarray(0)'high) := and_reduce (in1reg3);
+ outarray(0)(outarray(0)'high-1) := nand_reduce (in1reg3);
+ outarray(0)(outarray(0)'high-2) := or_reduce (in1reg3);
+ outarray(0)(outarray(0)'high-3) := nor_reduce (in1reg3);
+ outarray(0)(outarray(0)'high-4) := xor_reduce (in1reg3);
+ outarray(0)(outarray(0)'high-5) := xnor_reduce (in1reg3);
+ when "001" =>
+ outarray(0) := in1reg3 and in2reg3(in2reg3'high);
+ when "010" =>
+ outarray(0) := in1reg3 or in2reg3(in2reg3'high);
+ when "011" =>
+ outarray(0) := in1reg3 nand in2reg3(in2reg3'high);
+ when "100" =>
+ outarray(0) := in1reg3 nor in2reg3(in2reg3'high);
+ when "101" =>
+ outarray(0) := in2reg3(in2reg3'high) xor in1reg3;
+ when "110" =>
+ outarray(0) := in2reg3(in2reg3'high) xnor in1reg3;
+ when "111" =>
+ outarray(0) := in2reg3(in2reg3'high) and in1reg3;
+ when others => null;
+ end case;
+ end if;
+
+ end process cmd14reg;
+
+ -- purpose "1111" + constant
+ cmd15reg: process (clk, rst_n) is
+ variable tmpcmd : STD_LOGIC_VECTOR (2 downto 0);
+ variable outarray : cry_type; -- array for output
+ begin -- process cmd2reg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ outx(15) <= ( others => '0');
+ jrloop: for j in 0 to 7 loop
+ outarray (j) := (others => '0');
+ end loop jrloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ outx(15) <= outarray(7);
+ jcloop: for j in 7 downto 1 loop
+ outarray (j) := outarray(j-1);
+ end loop jcloop;
+ tmpcmd := to_slv (in2reg3 (in2reg3'low+2 downto in2reg3'low));
+ case tmpcmd is
+ when "000" =>
+ outarray(0) := in1reg3 + 1;
+ when "001" =>
+ outarray(0) := 1 + in1reg3;
+ when "010" =>
+ outarray(0) := in1reg3 + 1.0;
+ when "011" =>
+ outarray(0) := 1.0 + in1reg3;
+ when "100" =>
+ outarray(0) := in1reg3 * 1;
+ when "101" =>
+ outarray(0) := 1 * in1reg3;
+ when "110" =>
+ outarray(0) := in1reg3 * 1.0;
+ when "111" =>
+ outarray(0) := 1.0 * in1reg3;
+ when others => null;
+ end case;
+ end if;
+
+ end process cmd15reg;
+
+ -- purpose: multiply floating point
+ -- type : sequential
+ -- inputs : clk, rst_n, in1, in2
+ -- outputs: out1
+ cmdreg: process (clk, rst_n) is
+ variable outreg : float32; -- register stages
+ variable in1reg, in2reg : float32; -- register stages
+ variable in1reg2, in2reg2 : float32; -- register stages
+ begin -- process mulreg
+
+ if rst_n = '0' then -- asynchronous reset (active low)
+ in1reg := ( others => '0');
+ in2reg := ( others => '0');
+ in1reg2 := ( others => '0');
+ in2reg2 := ( others => '0');
+ in1reg3 <= ( others => '0');
+ in2reg3 <= ( others => '0');
+ out1 <= ( others => '0');
+ outreg := (others => '0');
+ rcloop: for i in 1 to 15 loop
+ cmdarray (i) <= (others => '0');
+ end loop rcloop;
+ elsif rising_edge(clk) then -- rising clock edge
+ out1 <= to_slv (outreg);
+ outregc: case cmdarray (13) is
+ when "0000" => outreg := outx (0);
+ when "0001" => outreg := outx (1);
+ when "0010" => outreg := outx (2);
+ when "0011" => outreg := outx (3);
+ when "0100" => outreg := outx (4);
+ when "0101" => outreg := outx (5);
+ when "0110" => outreg := outx (6);
+ when "0111" => outreg := outx (7);
+ when "1000" => outreg := outx (8);
+ when "1001" => outreg := outx (9);
+ when "1010" => outreg := outx (10);
+ when "1011" => outreg := outx (11);
+ when "1100" => outreg := outx (12);
+ when "1101" => outreg := outx (13);
+ when "1110" => outreg := outx (14);
+ when "1111" => outreg := outx (15);
+ when others => null;
+ end case outregc;
+ cmdpipe: for i in 15 downto 3 loop
+ cmdarray (i) <= cmdarray (i-1);
+ end loop cmdpipe;
+ cmdarray (2) <= std_ulogic_vector(cmd);
+ in1reg3 <= in1reg2;
+ in2reg3 <= in2reg2;
+ in1reg2 := in1reg;
+ in2reg2 := in2reg;
+ in1reg := to_float (in1, in1reg);
+ in2reg := to_float (in2, in2reg);
+ end if;
+
+ end process cmdreg;
+
+end architecture rtl;
diff --git a/ieee_proposed/rtl_tb/test_fixed_synth.vhd b/ieee_proposed/rtl_tb/test_fixed_synth.vhd
new file mode 100644
index 0000000..182875d
--- /dev/null
+++ b/ieee_proposed/rtl_tb/test_fixed_synth.vhd
@@ -0,0 +1,439 @@
+-- Test vectors for the synthesis test for the fixed point math package
+-- This test is designed to test fixed_synth and exercise much of the entity.
+-- Created for vhdl-200x by David Bishop (dbishop@vhdl.org)
+-- --------------------------------------------------------------------
+-- modification history : Last Modified $Date: 2006-06-08 10:55:54-04 $
+-- Version $Id: test_fixed_synth.vhdl,v 1.1 2006-06-08 10:55:54-04 l435385 Exp $
+-- --------------------------------------------------------------------
+
+entity test_fixed_synth is
+ generic (
+ quiet : boolean := false); -- make the simulation quiet
+end entity test_fixed_synth;
+
+library ieee, ieee_proposed;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee_proposed.fixed_pkg.all;
+architecture testbench of test_fixed_synth is
+
+ procedure report_error (
+ constant errmes : in string; -- error message
+ actual : in sfixed; -- data from algorithm
+ constant expected : in sfixed) is -- reference data
+ begin -- function report_error
+ assert actual = expected
+ report errmes & CR
+ & "Actual: " & to_string(actual)
+ & " (" & real'image(to_real(actual)) & ")" & CR
+ & " /= " & to_string(expected)
+ & " (" & real'image(to_real(expected)) & ")"
+ severity error;
+ return;
+ end procedure report_error;
+
+ -- Device under test. Note that all inputs and outputs are std_logic_vector.
+ -- This entity can be use both pre and post synthesis.
+ component fixed_synth is
+ port (
+ in1, in2 : in std_logic_vector (15 downto 0); -- inputs
+ out1 : out std_logic_vector (15 downto 0); -- output
+ cmd : in std_logic_vector (3 downto 0);
+ clk, rst_n : in std_ulogic); -- clk and reset
+ end component fixed_synth;
+ constant clock_period : time := 500 ns; -- clock period
+ subtype sfixed7 is sfixed (3 downto -3); -- 7 bit
+ subtype sfixed16 is sfixed (7 downto -8); -- 16 bit
+ signal stop_clock : boolean := false; -- stop the clock
+ signal clk, rst_n : std_ulogic; -- clk and reset
+ signal in1slv, in2slv, out1slv : std_logic_vector(15 downto 0);
+ signal in1, in2 : sfixed16; -- inputs
+ signal out1 : sfixed16; -- output
+ signal cmd : std_logic_vector (3 downto 0); -- command string
+begin -- architecture testbench
+
+ -- From fixed point to Std_logic_vector
+ in1slv <= to_slv(in1);
+ in2slv <= to_slv(in2);
+ -- Std_logic_vector to fixed point.
+ out1 <= to_sfixed(out1slv, out1'high, out1'low);
+ DUT: fixed_synth
+ port map (
+ in1 => in1slv, -- [in std_logic_vector (15 downto 0)] inputs
+ in2 => in2slv, -- [in std_logic_vector (15 downto 0)] inputs
+ out1 => out1slv, -- [out std_logic_vector (15 downto 0)] output
+ cmd => cmd, -- [in std_logic_vector (2 downto 0)]
+ clk => clk, -- [in std_ulogic] clk and reset
+ rst_n => rst_n); -- [in std_ulogic] clk and reset
+
+ -- purpose: clock driver
+ clkprc: process is
+ begin -- process clkprc
+ if (not stop_clock) then
+ clk <= '0';
+ wait for clock_period/2.0;
+ clk <= '1';
+ wait for clock_period/2.0;
+ else
+ wait;
+ end if;
+ end process clkprc;
+
+ -- purpose: reset driver
+ reset_proc: process is
+ begin -- process reset_proc
+ rst_n <= '0';
+ wait for clock_period * 2.0;
+ rst_n <= '1';
+ wait;
+ end process reset_proc;
+
+ -- purpose: main test loop
+ tester: process is
+ begin -- process tester
+ cmd <= "0000"; -- add mode
+ in1 <= (others => '0');
+ in2 <= (others => '0');
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ in1 <= "0000011010000000"; -- 6.5
+ in2 <= "0000001100000000"; -- 3
+ wait for clock_period;
+ cmd <= "0001"; -- subtract mode
+ in1 <= "0000011010000000"; -- 6.5
+ in2 <= "0000001100000000"; -- 3
+ wait for clock_period;
+ cmd <= "0010"; -- multiply mode
+ in1 <= "0000011010000000"; -- 6.5
+ in2 <= "0000001100000000"; -- 3
+ wait for clock_period;
+ cmd <= "0000"; -- add mode
+ in1 <= "0000000010000000"; -- 0.5
+ in2 <= "0000000010000000"; -- 0.5
+ wait for clock_period;
+ in1 <= to_sfixed (3.14, sfixed16'high, sfixed16'low);
+ in2 <= "0000001100000000"; -- 3
+ wait for clock_period;
+ cmd <= "0011"; -- divide
+ in1 <= "0000000010000000"; -- 0.5
+ in2 <= "0000000010000000"; -- 0.5
+ wait for clock_period;
+ in1 <= to_sfixed (-0.5, sfixed16'high, sfixed16'low); -- -0.5
+ in2 <= "0000000010000000"; -- 0.5
+ wait for clock_period;
+ cmd <= "0100"; -- unsigned add
+ in1 <= "0000011010000000"; -- 6.5
+ in2 <= "0000001100000000"; -- 3
+ wait for clock_period;
+ cmd <= "0101"; -- subtract mode
+ in1 <= "0000011010000000"; -- 6.5
+ in2 <= "0000001100000000"; -- 3
+ wait for clock_period;
+ cmd <= "0110"; -- multiply mode
+ in1 <= "0000011010000000"; -- 6.5
+ in2 <= "0000001100000000"; -- 3
+ wait for clock_period;
+ cmd <= "0100"; -- add mode
+ in1 <= "0000000010000000"; -- 0.5
+ in2 <= "0000000010000000"; -- 0.5
+ wait for clock_period;
+ in1 <= to_sfixed (3.14, sfixed16'high, sfixed16'low);
+ in2 <= "0000001100000000"; -- 3
+ wait for clock_period;
+ cmd <= "0111"; -- divide
+ in1 <= "0000000010000000"; -- 0.5
+ in2 <= "0000000010000000"; -- 0.5
+ wait for clock_period;
+ in1 <= to_sfixed (6.5, sfixed16'high, sfixed16'low); -- 6.5
+ in2 <= "0000000010000000"; -- 0.5
+ wait for clock_period;
+ -- resize
+ cmd <= "1000";
+ in1 <= to_sfixed (5.25, in1);
+ in2 <= to_sfixed (-5.25, in2);
+ wait for clock_period;
+ in1 <= to_sfixed (21.125, in1);
+ in2 <= to_sfixed (21.125, in2);
+ wait for clock_period;
+ in2 <= (in2'high => '0', in2'high-1 => '0', others => '0');
+ cmd <= "1001"; -- SIGNED
+ in1 <= to_sfixed (6.25, in1);
+ wait for clock_period;
+ in2 <= (in2'high => '0', in2'high-1 => '1', others => '0');
+ cmd <= "1001"; -- UNSIGNED
+ in1 <= to_sfixed (7.25, in1);
+ wait for clock_period;
+ in2 <= (in2'high => '1', in2'high-1 => '0', others => '0');
+ cmd <= "1001"; -- SIGNED
+ in1 <= to_sfixed (6.25, in1);
+ wait for clock_period;
+ in2 <= (in2'high => '1', in2'high-1 => '1', others => '0');
+ cmd <= "1001"; -- UNSIGNED
+ in1 <= to_sfixed (7.25, in1);
+ wait for clock_period;
+ cmd <= "1010";
+ in2 <= (in2'high => '0', in2'high-1 => '0', others => '0');
+ in1 <= to_sfixed (3, in1);
+ wait for clock_period;
+ cmd <= "1010";
+ in2 <= (in2'high => '0', in2'high-1 => '1', others => '0');
+ in1 <= to_sfixed (5, in1);
+ wait for clock_period;
+ cmd <= "1010";
+ in2 <= (in2'high => '1', in2'high-1 => '0', others => '0');
+ in1 <= to_sfixed (-5.5, in1);
+ wait for clock_period;
+ cmd <= "1010";
+ in2 <= (in2'high => '1', in2'high-1 => '1', others => '0');
+ in1 <= to_sfixed (7.25, in1);
+ wait for clock_period;
+ cmd <= "1010"; -- abs (mod)
+ in2 <= (in2'high => '1', in2'high-1 => '0', others => '0');
+ in1 <= to_sfixed (-42, in1);
+ wait for clock_period;
+ cmd <= "1011"; -- mod
+ in1 <= to_sfixed (6.25, in1);
+ in2 <= to_sfixed (6, in2);
+ wait for clock_period;
+ cmd <= "1100"; -- REM
+ in1 <= to_sfixed (6.25, in1);
+ in2 <= to_sfixed (6, in2);
+ wait for clock_period;
+ cmd <= "1101"; -- srl
+ in1 <= to_sfixed (5.25, in1);
+ in2 <= to_sfixed (-1, in2);
+ wait for clock_period;
+ cmd <= "1110"; -- sra
+ in1 <= to_sfixed (-7.25, in1);
+ in2 <= to_sfixed (1, in2);
+ wait for clock_period;
+ cmd <= "1111"; -- compare
+ in1 <= to_sfixed (42, in1);
+ in2 <= to_sfixed (42, in1);
+ wait for clock_period;
+ in1 <= to_sfixed (45, in1);
+ in2 <= to_sfixed (90, in1);
+ wait for clock_period;
+ in1 <= to_sfixed (3.125, in1);
+ in2 <= (others => '0');
+ wait for clock_period;
+ in1 <= "0110111110101111";
+ in2 <= "1111111111111111";
+ wait for clock_period;
+ in1 <= (others => '0');
+ in2 <= (others => '0');
+ wait for clock_period;
+ in1 <= "0000111000000000";
+ in2 <= "0000111000000000";
+ wait for clock_period;
+ in1 <= (others => '1');
+ in2 <= (others => '1');
+ wait for clock_period;
+ wait for clock_period;
+
+ wait for clock_period;
+ cmd <= "0000"; -- add mode
+ in1 <= (others => '0');
+ in2 <= (others => '0');
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait;
+ end process tester;
+
+ -- purpose: check the output of the tester
+ -- type : combinational
+ -- inputs :
+ -- outputs:
+ checktest: process is
+ constant fxzero : sfixed16 := (others => '0'); -- zero
+ variable chks16 : sfixed16; -- variable
+ variable sm1, sm2 : sfixed7; -- small fixed point
+ begin -- process checktest
+ wait for clock_period/2.0;
+ wait for clock_period;
+ wait for clock_period;
+ waitloop: while (out1 = fxzero) loop
+ wait for clock_period;
+ end loop waitloop;
+ chks16 := to_sfixed ((3.0+6.5), sfixed16'high, sfixed16'low);
+ report_error ( "3.0 + 6.5 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed ((6.5 - 3.0), sfixed16'high, sfixed16'low);
+ report_error ( "6.5 - 3.0 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed ((6.5 * 3.0), sfixed16'high, sfixed16'low);
+ report_error ( "6.5 * 3.0 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed (1, sfixed16'high, sfixed16'low);
+ report_error ( "0.5 + 0.5 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed (6.14, sfixed16'high, sfixed16'low);
+ report_error ( "3.14 + 3 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := "0000000100000000";
+ report_error ( "0.5/0.5 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed (-1, sfixed16'high, sfixed16'low);
+ report_error ( "-0.5/0.5 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed ((3.0+6.5), sfixed16'high, sfixed16'low);
+ report_error ( "3.0 + 6.5 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed ((6.5 - 3.0), sfixed16'high, sfixed16'low);
+ report_error ( "6.5 - 3.0 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed ((6.5 * 3.0), sfixed16'high, sfixed16'low);
+ report_error ( "6.5 * 3.0 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed (1, sfixed16'high, sfixed16'low);
+ report_error ( "0.5 + 0.5 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed (6.14, sfixed16'high, sfixed16'low);
+ report_error ( "3.14 + 3 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := "0000000100000000";
+ report_error ( "0.5/0.5 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ chks16 := to_sfixed (13, sfixed16'high, sfixed16'low);
+ report_error ( "6.5/0.5 error",
+ out1,
+ chks16);
+ wait for clock_period;
+ -- resize test
+ sm1 := out1 (7 downto 1);
+ sm2 := to_sfixed (5.25, sm2);
+ report_error ( "resize 1 error", sm1, sm2);
+ sm1 := out1 (-1 downto -7);
+ sm2 := to_sfixed (-5.25, sm2);
+ report_error ( "resize 2 error", sm1, sm2);
+ wait for clock_period;
+ sm1 := out1 (7 downto 1);
+ sm2 := "0101001"; -- wrapped
+-- sm2 := to_sfixed (21.125, sm2, 0, false, false); -- wrap, no round
+ report_error ( "resize 1 error", sm1, sm2);
+ sm1 := out1 (-1 downto -7);
+ sm2 := "0111111"; -- saturate
+ report_error ( "resize 2 error", sm1, sm2);
+ wait for clock_period;
+ -- to_signed and back
+ report_error ("to_signed(6.25)", out1, to_sfixed (6, out1));
+ wait for clock_period;
+ -- to_unsigned and back
+ report_error ("to_unsigned(7.25)", out1, to_sfixed (7, out1));
+ wait for clock_period;
+ -- to_integer and back
+ report_error ("to_signed(6.25)", out1, to_sfixed (6, out1));
+ wait for clock_period;
+ -- to_integer(ufixed) and back
+ report_error ("to_unsigned(7.25)", out1, to_sfixed (7, out1));
+ wait for clock_period;
+ report_error ("1/3", out1, to_sfixed (1.0/3.0, out1'high, -7));
+ wait for clock_period;
+ report_error ("unsigned 1/5", out1, to_sfixed (1.0/5.0, out1));
+ wait for clock_period;
+ report_error ("abs (-5.5)", out1, to_sfixed (5.5, out1));
+ wait for clock_period;
+ report_error ("-7.25", out1, to_sfixed (-7.25, out1));
+ wait for clock_period;
+ report_error ("abs(-42)", out1, to_sfixed (42, out1));
+ wait for clock_period;
+ report_error ("6.25 mod 6", out1, to_sfixed (0.25, out1));
+ wait for clock_period;
+ report_error ("6.25 rem 6", out1, to_sfixed (0.25, out1));
+ wait for clock_period;
+ chks16 := "0000101010000000";
+ report_error ("5.25 srl -1", out1, chks16);
+ wait for clock_period;
+ chks16 := "1111110001100000";
+ report_error ("-7.25 sra 1", out1, chks16);
+ wait for clock_period;
+ -- 7654321012345678
+ chks16 := "0111000000110001";
+ assert (std_match (out1, chks16))
+ report "42=42 compare " & CR
+ & "Actual " & to_string(out1) & CR
+ & "Expected " & to_string(chks16) severity error;
+ wait for clock_period;
+ chks16 := "------0001010110";
+ assert (std_match (out1, chks16))
+ report "45=90 compare " & CR
+ & "Actual " & to_string(out1) & CR
+ & "Expected " & to_string(chks16) severity error;
+ wait for clock_period;
+ chks16 := "------1010101010";
+ assert (std_match (out1, chks16))
+ report "3.125=0 compare " & CR
+ & "Actual " & to_string(out1) & CR
+ & "Expected " & to_string(chks16) severity error;
+ wait for clock_period;
+ -- 7654321012345678
+ chks16 := "0--1010000101010";
+ assert (std_match (out1, chks16))
+ report "pattern1 compare " & CR
+ & "Actual " & to_string(out1) & CR
+ & "Expected " & to_string(chks16) severity error;
+ wait for clock_period;
+ -- 7654321012345678
+ chks16 := "0001100000110001";
+ assert (std_match (out1, chks16))
+ report "zero = zero " & CR
+ & "Actual " & to_string(out1) & CR
+ & "Expected " & to_string(chks16) severity error;
+ wait for clock_period;
+ -- 7654321012345678
+ chks16 := "1111000000110001";
+ assert (std_match (out1, chks16))
+ report "pattern2 compare " & CR
+ & "Actual " & to_string(out1) & CR
+ & "Expected " & to_string(chks16) severity error;
+ wait for clock_period;
+ -- 7654321012345678
+ chks16 := "0111000000110001";
+ assert (std_match (out1, chks16))
+ report "-1 = -1 " & CR
+ & "Actual " & to_string(out1) & CR
+ & "Expected " & to_string(chks16) severity error;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ assert (false) report "Testing complete" severity note;
+ stop_clock <= true;
+ wait;
+ end process checktest;
+end architecture testbench;
diff --git a/ieee_proposed/rtl_tb/test_float_synth.vhd b/ieee_proposed/rtl_tb/test_float_synth.vhd
new file mode 100644
index 0000000..90b40e8
--- /dev/null
+++ b/ieee_proposed/rtl_tb/test_float_synth.vhd
@@ -0,0 +1,892 @@
+-------------------------------------------------------------------------------
+-- test routine for the post synthesis 32 bit multiply
+-------------------------------------------------------------------------------
+
+entity test_float_synth is
+ generic (
+ quiet : BOOLEAN := false);
+end entity test_float_synth;
+
+use std.textio.all;
+library ieee, ieee_proposed;
+use ieee.math_real.all;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee_proposed.fixed_float_types.all;
+use ieee_proposed.fixed_pkg.all;
+use ieee_proposed.float_pkg.all;
+
+--library modelsim_lib;
+--use modelsim_lib.util.all;
+
+architecture testbench of test_float_synth is
+ subtype fp16 is float (6 downto -9); -- 16 bit
+ function reverse (
+ inpvec : STD_LOGIC_VECTOR (0 to 31))
+ return float32 is
+ variable result : float32;
+ begin
+ for i in 0 to 31 loop
+ result (i-23) := inpvec(i);
+ end loop; -- i
+ return result;
+ end function reverse;
+
+ -- purpose: converts an float32 into a std_logic_vector
+-- function to_slv (
+-- input : float32) -- float32 input
+-- return std_logic_vector is
+-- variable result : std_logic_vector (31 downto 0); -- result
+-- begin -- function to_slv
+-- floop: for i in float32'range loop
+-- result (i + fp_fraction_width) := input (i);
+-- end loop floop;
+-- return result;
+-- end function to_slv;
+
+ -- purpose: converts a std_logic_vector to an float32
+ function to_float32x (
+ signal input : STD_LOGIC_VECTOR (31 downto 0))
+ return float32 is
+ variable result : float32;
+ begin -- function to_float32x
+ return to_float (input, float32'high, -float32'low);
+ end function to_float32x;
+
+ procedure report_error (
+ constant errmes : STRING; -- error message
+ actual : in float32; -- data from algorithm
+ constant expected : float32) is -- reference data
+ begin -- function report_error
+ assert actual = expected
+ report errmes & " miscompare" & CR &
+ "Actual " & to_string (actual) & " ("
+ & REAL'image(to_real(actual))& ") /= " & CR &
+ "Expected " & to_string (expected) & " ("
+ & REAL'image(to_real(expected))& ")"
+ severity error;
+ return;
+ end procedure report_error;
+ procedure report_error16 (
+ constant errmes : STRING; -- error message
+ actual : in fp16; -- data from algorithm
+ constant expected : fp16) is -- reference data
+ begin -- function report_error
+ assert actual = expected
+ report errmes & " miscompare" & CR &
+ "Actual " & to_string (actual) & " ("
+ & REAL'image(to_real(actual))& ") /= " & CR &
+ "Expected " & to_string (expected) & " ("
+ & REAL'image(to_real(expected))& ")"
+ severity error;
+ return;
+ end procedure report_error16;
+
+ component float_synth is
+ port (
+ in1, in2 : in STD_LOGIC_VECTOR(31 downto 0); -- inputs
+ out1 : out STD_LOGIC_VECTOR(31 downto 0); -- output
+ cmd : in STD_LOGIC_VECTOR (3 downto 0);
+ clk, rst_n : in STD_ULOGIC); -- clk and reset
+ end component float_synth;
+ for all : float_synth
+ use entity work.float_synth(rtl);
+ constant clock_period : TIME := 500 ns; -- clock period
+ signal stop_clock : BOOLEAN := false; -- stop the clock
+ signal out1real : REAL; -- real version
+ signal in1, in2 : float32; -- inputs
+ signal out1 : float32; -- output
+ constant zero0 : float32 := (others => '0'); -- zero
+ signal cmd : STD_LOGIC_VECTOR (3 downto 0); -- command
+ signal clk, rst_n : STD_ULOGIC; -- clk and reset
+ signal in1slv, in2slv, out1slv : STD_LOGIC_VECTOR(31 downto 0);
+ signal indelay : float32; -- spied signal
+begin -- architecture testbench
+ out1real <= to_real (out1);
+ in1slv <= to_slv(in1);
+ in2slv <= to_slv(in2);
+ out1 <= to_float32x(out1slv);
+ DUT : float_synth
+ port map (
+ in1 => in1slv, -- [in float32] inputs
+ in2 => in2slv, -- [in float32] inputs
+ out1 => out1slv, -- [out float32] output
+ cmd => cmd,
+ clk => clk, -- [in std_ulogic] clk and reset
+ rst_n => rst_n); -- [in std_ulogic] clk and reset
+
+-- spy_process : process
+-- begin
+-- signal_force ("/DUT/in2reg3", "00000000000000000000000000000000",
+-- 500 ns, freeze, 5000 ns, 1);
+-- wait;
+-- end process spy_process;
+
+ -- purpose: clock driver
+ -- type : combinational
+ -- inputs :
+ -- outputs:
+ clkprc : process is
+
+ begin -- process clkprc
+ if (not stop_clock) then
+ clk <= '0';
+ wait for clock_period/2.0;
+ clk <= '1';
+ wait for clock_period/2.0;
+ else
+ wait;
+ end if;
+ end process clkprc;
+
+ -- purpose: reset driver
+ -- type : combinational
+ -- inputs :
+ -- outputs:
+ reset_proc : process is
+
+ begin -- process reset_proc
+
+ rst_n <= '0';
+ wait for clock_period * 2.0;
+ rst_n <= '1';
+ wait;
+ end process reset_proc;
+
+ -- purpose: main test loop
+ -- type : combinational
+ -- inputs :
+ -- outputs:
+ tester : process is
+
+ begin -- process tester
+ cmd <= "0110"; -- 16 bit to float32 mode
+ in1 <= "10000000000000000000001000101111"; -- 4.33 ufixed
+ in2 <= "00000000000000000000000000000100"; -- 4
+ floop1: for i in 1 to 100 loop
+ wait for clock_period;
+ end loop floop1;
+ cmd <= "0110"; -- 16 bit to float32 mode
+ in1 <= "10000000000000000000001000101011"; -- 4.33 ufixed
+ in2 <= "00000000000000000000000000000100"; -- 4
+ floop2: for i in 1 to 100 loop
+ wait for clock_period;
+ end loop floop2;
+ cmd <= "0010";
+ in1 <= reverse("00000000000000000000101100000010"); -- 6.5
+ in2 <= reverse("00000000000000000001010001000010"); -- 42
+ wait for clock_period;
+ in1 <= reverse("00000000000000000001010001000010"); -- 42
+ in2 <= reverse("00000000000000000000101100000010"); -- 6.5
+ wait for clock_period;
+ in1 <= reverse("00000000000000000000101100000010"); -- 6.5
+ in2 <= reverse("00000000000000000000101100000010"); -- 6.5
+ wait for clock_period;
+ in1 <= reverse("00000000000000000001010001000010"); -- 42
+ in2 <= "01000000000000000000000000000000"; -- 2
+ wait for clock_period;
+ in1 <= "00111110101010101010101010101011"; -- 1/3
+ in2 <= "01000000000000000000000000000000"; -- 2
+ wait for clock_period;
+ in1 <= reverse("00000000000000000001010001000010"); -- 42
+ in2 <= reverse("00000000000000000000101100000011"); -- -6.5
+ wait for clock_period;
+ in1 <= reverse("10000000000000000000000000000000"); -- 2**-149
+ in2 <= "11000000000000000000000000000000"; -- -2.0
+ wait for clock_period;
+ in1 <= reverse("00000000000000000000001000000000"); -- 2**-127
+ in2 <= "00111110100000000000000000000000"; -- 0.25
+ wait for clock_period;
+ in1 <= reverse("00000000000000000001010001000010"); -- 42
+ in2 <= reverse("00000000000000000000101100000010"); -- 6.5
+ wait for clock_period;
+ cmd <= "0001"; -- subtract mode
+ in2 <= "01001011111001110011000110011011"; -- 30303030
+ in1 <= "01001011111001110011000110011100"; -- 30303033
+ wait for clock_period;
+ in1 <= reverse("00000000000000000000101100000010"); -- 6.5
+ in2 <= "01000000100000000000000000000000"; -- 4
+ wait for clock_period;
+ in2 <= reverse("00000000000000000000101100000010"); -- 6.5
+ in1 <= "01000000100000000000000000000000"; -- 4
+ wait for clock_period;
+ in1 <= "01000000100010101010101010101011"; -- 4.333333
+ in2 <= "00111110101010101010101010101011"; -- 1/3
+ wait for clock_period;
+ cmd <= "0000"; -- add mode
+ in1 <= "00111110101010101010101010101011"; -- 1/3
+ in2 <= "01000000000000000000000000000000"; -- 2
+ wait for clock_period;
+ in2 <= "00111110101010101010101010101011"; -- 1/3
+ in1 <= "01000000000000000000000000000000"; -- 2
+ wait for clock_period;
+ in1 <= "00000000100000000000000000000001"; -- 2**-126
+ in2 <= "01000000100000000000000000000001"; -- 4+
+ wait for clock_period;
+ cmd <= "0011"; -- divide mode
+ in1 <= "00111111100000000000000000000000"; -- 1.0
+ in2 <= "01000000010000000000000000000000"; -- 3.0
+ wait for clock_period;
+ in1 <= "01001100000011001011110001001111"; -- 36892987
+ in2 <= "00000000010000000000000000000000"; -- 2**-127
+ wait for clock_period;
+ in1 <= "10111110101010101010101010101011"; -- -1/3
+ in2 <= "01000000000000000000000000000000"; -- 2
+ wait for clock_period;
+ cmd <= "0100"; -- 32 to 16 conversion mode
+ in1 <= "00111111100000000000000000000000"; -- 1.0
+ in2 <= (others => '0');
+ wait for clock_period;
+ in1 <= "10111110101010101010101010101011"; -- -1/3, no round
+ wait for clock_period;
+ in1 <= "10111110101010101010101010101011"; -- -1/3
+ in2 <= "00000000000000000000000000000001"; -- opcode 1
+ wait for clock_period;
+ cmd <= "0101"; -- conversion mode
+ in1 <= "00111111100000000000000000000000"; -- 1.0
+ in2 <= "01000000000000000000000000000000"; -- opcode zero
+ wait for clock_period;
+ in1 <= "01000010001010000000000000000000"; -- 42.0
+ in2 <= "00000000000000000000000000000001"; -- opcode 1
+ wait for clock_period;
+ in1 <= "10111111100000000000000000000000"; -- -1.0
+ in2 <= "00000000000000000000000000000010"; -- 2
+ wait for clock_period;
+ in1 <= "00111111100000000000000000000000"; -- 1.0
+ in2 <= "00000000000000000000000000000011"; -- 3
+ wait for clock_period;
+ in1 <= "01000000100010101010101010101011"; -- 4.333333
+ in2 <= "00000000000000000000000000000100"; -- 4
+ wait for clock_period;
+ in1 <= "00111111100000000000000000000000"; -- 1.0
+ in2 <= "00000000000000000000000000000101"; -- 5
+ wait for clock_period;
+ in1 <= "11000000100010101010101010101011"; -- -4.333333
+ in2 <= "00000000000000000000000000000110"; -- 6 to_sfixed
+ wait for clock_period;
+ in1 <= "00111111100000000000000000000000"; -- 1.0
+ in2 <= "00000000000000000000000000000111"; -- 7 to_sfixed
+ wait for clock_period;
+ cmd <= "0110"; -- 16 bit to float32 mode
+ in1 <= "00000000000000000000000000000011"; -- 3
+ in2 <= "01000000000000000000000000000000"; -- mode 0
+ wait for clock_period;
+ in1 <= "00000000000000000000000000000100"; -- 4
+ in2 <= "01000000000000000000000000000001"; -- 1
+ wait for clock_period;
+ in1 <= "00000000000000001111111111111110"; -- -2
+ in2 <= "01000000000000000000000000000010"; -- 2 to_float(signed)
+ wait for clock_period;
+ in1 <= "00000000000000000000000000000100"; -- 4
+ in2 <= "01000000000000000000000000000011"; -- mode 3
+ wait for clock_period;
+ in1 <= "10000000000000000000001000101011"; -- 4.33 ufixed
+ in2 <= "00000000000000000000000000000100"; -- 4
+ wait for clock_period;
+ in1 <= "10100000000000000000000010000000"; -- 1.0 ufixed
+ in2 <= "00000000000000000000000000000101"; -- 5
+ wait for clock_period;
+ in1 <= "11000000000000001111110111010101"; -- -4.333 sfixed
+ in2 <= "00000000000000000000000000000110"; -- 6
+ wait for clock_period;
+ in1 <= "10100000000000000000000010000000"; -- 1.0 sfixed
+ in2 <= "00000000000000000000000000000111"; -- 7
+ wait for clock_period;
+ cmd <= "0111"; -- Mod
+ in1 <= "00000000000000000000000000000011"; --
+ in2 <= "00000000000000000000000000000011"; --
+ wait for clock_period;
+ in1 <= "00000010001100101111000100111011"; -- 36892987
+ in2 <= "00000010001100101111000100111011"; -- 36892987
+ wait for clock_period;
+ in1 <= "11000000100010101010101010101011"; -- -4.333333
+ in2 <= "01000000100000000000000000000000"; -- 4
+ wait for clock_period;
+ cmd <= "1000"; -- rem
+ in1 <= "00000000000000000000000000000011"; --
+ in2 <= "00000000000000000000000000000011"; --
+ wait for clock_period;
+ in1 <= "00000010001100101111000100111011"; -- 36892987
+ in2 <= "00000010001100101111000100111011"; -- 36892987
+ wait for clock_period;
+ in1 <= "11000000100010101010101010101011"; -- -4.333333
+ in2 <= "01000000100000000000000000000000"; -- 4
+ wait for clock_period;
+ cmd <= "1001"; -- constants conversion
+ in2 <= "11000000000000000000000000000000"; -- command 0
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000001"; -- command 1
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000010"; -- command 2
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000011"; -- command 3
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000100"; -- command 4
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000101"; -- command 5
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000110"; -- command 6
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000111"; -- command 7
+ wait for clock_period;
+ cmd <= "1010"; -- conversions
+ in1 <= to_float (1, in1);
+ in2 <= "11000000000000000000000000000000"; -- command 0
+ wait for clock_period;
+ in1 <= to_float (-2, in1);
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000001"; -- command 1
+ wait for clock_period;
+ in1 <= to_float (1, in1);
+ wait for clock_period;
+ in2 <= "00010000000000000000000000000010"; -- command 2 scalb
+ in1 <= to_float (1, in1);
+ wait for clock_period;
+ in2 <= "11110000000000000000000000000010"; -- command 2 scalb
+ in1 <= to_float (1, in1);
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000011"; -- command 3 logb
+ in1 <= to_float (1, in1);
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000011"; -- command 3 logb
+ in1 <= to_float (0.25, in1);
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000100"; -- 4 nextafter
+ in1 <= to_float (1, in1);
+ wait for clock_period;
+ in1 <= to_float (4, in1);
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000101"; -- 5 nextafter
+ in1 <= to_float (1, in1);
+ wait for clock_period;
+ in1 <= to_float (-4, in1);
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000110"; -- 6 nextafter
+ in1 <= to_float (1, in1);
+ wait for clock_period;
+ in1 <= to_float (4, in1);
+ wait for clock_period;
+ in2 <= "11000000000000000000000000000111"; -- 7 nextafter
+ in1 <= to_float (1, in1);
+ wait for clock_period;
+ in1 <= to_float (-4, in1);
+ wait for clock_period;
+ cmd <= "1011"; -- copy sign
+ in1 <= to_float (2, in1);
+ in2 <= to_float (2, in1);
+ wait for clock_period;
+ in1 <= to_float (-3, in1);
+ in2 <= to_float (3, in1);
+ wait for clock_period;
+ in1 <= to_float (4, in1);
+ in2 <= to_float (-4, in1);
+ wait for clock_period;
+ in1 <= to_float (-5, in1);
+ in2 <= to_float (-5, in1);
+ wait for clock_period;
+ cmd <= "1100"; -- compare test
+ in1 <= to_float (15, in1);
+ in2 <= to_float (15, in1);
+ wait for clock_period;
+ in1 <= to_float (15.5, in1);
+ in2 <= to_float (-2, in1);
+ wait for clock_period;
+ in1 <= to_float (-2, in1);
+ in2 <= to_float (2, in1);
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= to_float (-2, in1);
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000001"; -- NAN
+ in2 <= to_float (-2, in1);
+ wait for clock_period;
+ cmd <= "1101"; -- boolean test
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000000"; -- command 0 , not
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000001"; -- command 1, and
+ wait for clock_period;
+ in1 <= "01111111000000000000000000000000"; -- + inf
+ in2 <= "00111111000000000000000000000010"; -- command 2, or
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000011"; -- command 3, nand
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000100"; -- command 4, nor
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000101"; -- command 5, xor
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000110"; -- command 6, xnor
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000111"; -- command 7, xor '1'
+ wait for clock_period;
+ cmd <= "1110"; -- reduce and vector test test
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000000"; -- command 0,
+ wait for clock_period;
+ in1 <= "11111111111111111111111111111111"; -- all 1
+ wait for clock_period;
+ in1 <= "10000000000000000000000000000000"; -- -0
+ wait for clock_period;
+ in1 <= "00000000000000000000000000000000"; -- 0
+ wait for clock_period;
+ in1 <= "01111111100000000000000000000000"; -- + inf
+ in2 <= "00111111100000000000000000000001"; -- command 1, and '0'
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000001"; -- command 1, and '1'
+ wait for clock_period;
+ in2 <= "00111111100000000000000000000010"; -- command 2, or '0'
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000010"; -- command 2, or '1'
+ wait for clock_period;
+ in2 <= "00111111100000000000000000000011"; -- command 3, nand '0'
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000011"; -- command 3, nand '1'
+ wait for clock_period;
+ in2 <= "00111111100000000000000000000100"; -- command 4, nor '0'
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000100"; -- command 4, nor '1'
+ wait for clock_period;
+ in2 <= "00111111100000000000000000000101"; -- command 5, xor '0'
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000101"; -- command 5, xor '1'
+ wait for clock_period;
+ in2 <= "00111111100000000000000000000110"; -- command 6, xnor '0'
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000110"; -- command 6, xnor '1'
+ wait for clock_period;
+ in2 <= "00111111100000000000000000000111"; -- command 7, and '0'
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000111"; -- command 7, and '1'
+ wait for clock_period;
+ cmd <= "1111"; -- add and mult by constant
+ in2 <= "10111111100000000000000000000000"; -- command 0, + 1
+ in1 <= to_float (2, in1);
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000001"; -- command 1, 1 +
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000010"; -- command 2, + 1.0
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000011"; -- command 3, 1.0 +
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000100"; -- command 4, * 1
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000101"; -- command 5, 1 *
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000110"; -- command 6, * 1.0
+ wait for clock_period;
+ in2 <= "10111111100000000000000000000111"; -- command 7, 1.0 *
+ wait for clock_period;
+
+
+ wait for clock_period;
+ cmd <= "0000"; -- add mode
+ in1 <= (others => '0');
+ in2 <= (others => '0');
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait for clock_period;
+ wait;
+ end process tester;
+
+ -- purpose: check the output of the tester
+ -- type : combinational
+ -- inputs :
+ -- outputs:
+ checktest : process is
+ variable out16, out16t : fp16; -- 16 bit fp variables
+ variable out1t, out2t : float32; -- 32 bit float
+ variable s16, s16t : SIGNED(7 downto 0); -- 7 bit SIGNED
+ variable latency : INTEGER := 0;
+ begin -- process checktest
+ wait for clock_period/2.0;
+ floop3: for i in 1 to 100 loop
+ wait for clock_period;
+ end loop floop3;
+ latency := 0;
+ out2t := "01000000100010101100000000000000";
+ wl1: while out1 /= out2t loop
+ wait for clock_period;
+ latency := latency + 1;
+ assert latency /= 100 report "After 100 loops, pattern never found"
+ severity failure;
+ end loop wl1;
+ report "Latency was " & INTEGER'image(latency) severity note;
+ floop4: for i in 1 to 100 loop
+ wait for clock_period;
+ end loop floop4;
+ report_error ("42 * 6.5 error",
+ out1,
+ to_float (273, out1));
+ wait for clock_period;
+ report_error ("6.5 * 42 error",
+ out1,
+ to_float (273, out1'high, -out1'low));
+ wait for clock_period;
+ report_error ("Multiply 42.25 miscompare",
+ out1,
+ "01000010001010010000000000000000"); -- 42.25
+ wait for clock_period;
+ report_error ("Multiply 84 miscompare",
+ out1,
+ "01000010101010000000000000000000"); -- 84
+ wait for clock_period;
+ report_error ("Multiply 2/3 miscompare",
+ out1,
+ "00111111001010101010101010101011"); -- 2/3
+ wait for clock_period;
+ report_error ("Multiply -273 miscompare",
+ out1,
+ "11000011100010001000000000000000"); -- -273
+ wait for clock_period;
+ report_error ("mult 2**-148 test miscompare",
+ out1,
+ reverse("01000000000000000000000000000001")); -- -2*-148
+ wait for clock_period;
+ report_error ("Multiply 2**-129 miscompare",
+ out1,
+ reverse("00000000000000000000100000000000")); -- 2**-129
+ wait for clock_period;
+ report_error ("6.5 * 42 error",
+ out1,
+ to_float (273, out1));
+ wait for clock_period;
+ report_error ("Subtract 30303033 - 30303030 miscompare",
+ out1,
+ "01000000000000000000000000000000"); -- 2 (not 3, rounding)
+ wait for clock_period;
+ report_error ("Subtract 6.5 - 4 miscompare",
+ out1,
+ "01000000001000000000000000000000"); -- 2.5
+ wait for clock_period;
+ report_error ("Subtract 4 - 6.5 miscompare",
+ out1,
+ "11000000001000000000000000000000"); -- -2.5
+ wait for clock_period;
+ report_error ("Subtract 4.333 - 1/3 miscompare",
+ out1,
+ "01000000100000000000000000000000"); -- 4
+ wait for clock_period;
+ report_error ("Add 2.333 miscompare",
+ out1,
+ "01000000000101010101010101010101"); -- 2.333333
+ wait for clock_period;
+ report_error ("Add 2.333 rev miscompare",
+ out1,
+ "01000000000101010101010101010101"); -- 2.333333
+ wait for clock_period;
+ report_error ("Add 4 + miscompare",
+ out1,
+ "01000000100000000000000000000001"); -- 4
+ wait for clock_period;
+ report_error ("div 1/3 test miscompare",
+ out1,
+ "00111110101010101010101010101011"); -- 1/3
+ wait for clock_period;
+ report_error ("div 369297/2**-126 test miscompare",
+ out1,
+ "01111111100000000000000000000000");
+ wait for clock_period;
+ report_error ("-1/6 test miscompare",
+ out1, "10111110001010101010101010101011"); -- -1/6
+ wait for clock_period;
+ -- resize function
+ out16 := to_float (to_slv (out1(-8 downto -23)), 6, 9);
+ out16t := to_float (1, out16t);
+ report_error16 ("1.0 fp16 converserion",
+ out16, out16t);
+ wait for clock_period;
+ out16 := to_float (to_slv (out1(-8 downto -23)), 6, 9);
+ out16t := to_float (arg => -1.0/3.0, size_res => out16t,
+ round_style => round_zero);
+ report_error16 ("-1/3 not rounded fp16 converserion",
+ out16, out16t);
+ wait for clock_period;
+ out16 := to_float (to_slv (out1(-8 downto -23)), 6, 9);
+ out16t := to_float (-1.0/3.0, out16t);
+ report_error16 ("-1/3 fp16 converserion",
+ out16, out16t);
+ -- conversion test
+ wait for clock_period;
+ report_error ("1.0 to unsigned miscompare",
+ out1, "00000000000000000000000000000001");
+ wait for clock_period;
+ report_error ("42 to unsigned miscompare",
+ out1, "00100000000000000000000000101010");
+ wait for clock_period;
+ report_error ("-1.0 to signed miscompare",
+ out1, "01000000000000001111111111111111");
+ wait for clock_period;
+ report_error ("1.0 to signed miscompare",
+ out1, "01100000000000000000000000000001");
+ wait for clock_period;
+ report_error ("4.33 to ufixed miscompare",
+ out1, "10000000000000000000001000101011");
+ wait for clock_period;
+ report_error ("1.0 to ufixed miscompare",
+ out1, "10100000000000000000000010000000");
+ wait for clock_period;
+ report_error ("4.333 to sfixed miscompare",
+ out1, "11000000000000001111110111010101");
+ wait for clock_period;
+ report_error ("1.0 to sfixed miscompare",
+ out1, "11100000000000000000000010000000");
+ wait for clock_period;
+ report_error ("unsigned 3 to float miscompare",
+ out1, to_float(3, out1));
+ wait for clock_period;
+ report_error ("unsigned 4 to float miscompare",
+ out1, to_float(4, out1));
+ wait for clock_period;
+ report_error ("signed -2 to float miscompare",
+ out1, to_float(-2, out1));
+ wait for clock_period;
+ report_error ("signed 4 to float miscompare",
+ out1, to_float(4, out1));
+ wait for clock_period;
+ report_error ("ufixed 4.333 to float miscompare",
+ out1, "01000000100010101100000000000000"); -- 4.333333
+ wait for clock_period;
+ report_error ("ufixed 1.0 to float miscompare",
+ out1, "00111111100000000000000000000000"); -- 1.0
+ wait for clock_period;
+ report_error ("sfixed -4.333 to float miscompare",
+ out1, "11000000100010101100000000000000"); -- -4.333333
+ wait for clock_period;
+ report_error ("sfixed 1.0 to float miscompare",
+ out1, "00111111100000000000000000000000"); -- 1.0
+ wait for clock_period;
+ report_error ("denormal mod denormal miscompare",
+ out1, zero0);
+ wait for clock_period;
+ report_error ("large mod large miscompare",
+ out1, zero0);
+ wait for clock_period;
+ report_error ("-4.333 mod 4 miscompare",
+ out1,
+ from_string ("01000000011010101010101010101010", out1));
+ wait for clock_period;
+ report_error ("denormal rem denormal miscompare",
+ out1, zero0);
+ wait for clock_period;
+ report_error ("large rem large miscompare",
+ out1, zero0);
+ wait for clock_period;
+ out1t := "10111110101010101010101010110000";
+ report_error ("-4.333 rem 4 miscompare",
+ out1, out1t);
+ wait for clock_period;
+ report_error ("to_float(0) miscompare",
+ out1, zero0);
+ wait for clock_period;
+ report_error ("to_float(0.0) miscompare",
+ out1, zero0);
+ wait for clock_period;
+ report_error ("to_float(8) miscompare",
+ out1, to_float(8.0, out1));
+ wait for clock_period;
+ report_error ("to_float(8.0) miscompare",
+ out1, to_float(8, out1));
+ wait for clock_period;
+ report_error ("to_float(-8) miscompare",
+ out1, to_float(-8.0, out1));
+ wait for clock_period;
+ report_error ("to_float(-8.0) miscompare",
+ out1, to_float(-8, out1));
+ wait for clock_period;
+ report_error ("to_float(27000) miscompare",
+ out1, to_float(27000.0, out1));
+ wait for clock_period;
+ report_error ("to_float(PI) miscompare",
+ out1, to_float(3.141592653589, out1));
+ -- Conversion test
+ wait for clock_period;
+ report_error ("-1 miscompare",
+ out1, to_float(-1, out1));
+ wait for clock_period;
+ report_error ("-(-2) miscompare",
+ out1, to_float(2, out1));
+ wait for clock_period;
+ report_error ("abs(-2) miscompare",
+ out1, to_float(2, out1));
+ wait for clock_period;
+ report_error ("abs(1) miscompare",
+ out1, to_float(1, out1));
+ wait for clock_period;
+ report_error ("scalb (1, 1) miscompare",
+ out1, to_float(2, out1));
+ wait for clock_period;
+ report_error ("scalb (1, -1) miscompare",
+ out1, to_float(0.5, out1));
+ wait for clock_period;
+ s16 := SIGNED (to_slv (out1(-16 downto -23)));
+ assert (s16 = 0) report "logb (1) returned "
+ & to_string(to_sfixed(s16)) severity error;
+ wait for clock_period;
+ s16 := SIGNED (to_slv (out1(-16 downto -23)));
+ assert (s16 = -2) report "logb (0.25) returned "
+ & to_string(to_sfixed(s16)) severity error;
+ wait for clock_period;
+ out1t := "00111111100000000000000000000001";
+ report_error ("nextafter (1, 1.5)", out1, out1t);
+ wait for clock_period;
+ out1t := "01000000011111111111111111111111";
+ report_error ("nextafter (4, 1.5)", out1, out1t);
+ wait for clock_period;
+ out1t := "00111111011111111111111111111111";
+ report_error ("nextafter (1, -1.5)", out1, out1t);
+ wait for clock_period;
+ out1t := "11000000011111111111111111111111";
+ report_error ("nextafter (-4, -1.5)", out1, out1t);
+ wait for clock_period;
+ out1t := "00111111100000000000000000000001";
+ report_error ("nextafter (1, inf)", out1, out1t);
+ wait for clock_period;
+ out1t := "01000000100000000000000000000001";
+ report_error ("nextafter (4, inf)", out1, out1t);
+ wait for clock_period;
+ out1t := "00111111011111111111111111111111";
+ report_error ("nextafter (1, neginf)", out1, out1t);
+ wait for clock_period;
+ out1t := "11000000100000000000000000000001";
+ report_error ("nextafter (-4, neginf)", out1, out1t);
+ wait for clock_period;
+ report_error ("Copysign (2,2)", out1, to_float(2, out1));
+ wait for clock_period;
+ report_error ("Copysign (-3,3)", out1, to_float(3, out1));
+ wait for clock_period;
+ report_error ("Copysign (4,-4)", out1, to_float(-4, out1));
+ wait for clock_period;
+ report_error ("Copysign (-5,-5)", out1, to_float(-5, out1));
+ wait for clock_period;
+ out1t := "10001110000000000000000000000000";
+ report_error ("compare test 15, 15", out1, out1t);
+ wait for clock_period;
+ out1t := "01101001000000000000000000000000";
+ report_error ("compare test 15.5, -2", out1, out1t);
+ wait for clock_period;
+ out1t := "01010100000000000000000000000000";
+ report_error ("compare test -2, 2", out1, out1t);
+ wait for clock_period;
+ out1t := "01101000010000000000000000000000";
+ report_error ("compare test inf, -2", out1, out1t);
+ wait for clock_period;
+ out1t := "01000000101000000000000000000000";
+ report_error ("compare test NAN, -2", out1, out1t);
+ wait for clock_period;
+ out1t := "10000000011111111111111111111111"; -- not + inf
+ report_error ("not +inf", out1, out1t);
+ wait for clock_period;
+ out1t := "00111111100000000000000000000000"; -- and
+ report_error ("and +inf", out1, out1t);
+ wait for clock_period;
+ out1t := "01111111000000000000000000000010"; -- or
+ report_error ("or +inf", out1, out1t);
+ wait for clock_period;
+ out1t := "11000000011111111111111111111111"; -- nand
+ report_error ("nand +inf", out1, out1t);
+ wait for clock_period;
+ out1t := "10000000011111111111111111111011"; -- nor
+ report_error ("nor +inf", out1, out1t);
+ wait for clock_period;
+ out1t := "01000000000000000000000000000101"; -- xor
+ report_error ("xor +inf", out1, out1t);
+ wait for clock_period;
+ out1t := "10111111111111111111111111111001"; -- xnor
+ report_error ("xnor +inf", out1, out1t);
+ wait for clock_period;
+ out1t := "10000000011111111111111111111111"; -- xnor '1'
+ report_error ("+inf xor '1'", out1, out1t);
+ wait for clock_period;
+ out1t := "01100100000000000000000000000000"; -- reduce test
+ report_error ("_reduce test", out1, out1t);
+ wait for clock_period;
+ out1t := "10100100000000000000000000000000"; -- reduce test
+ report_error ("_reduce all 1 test", out1, out1t);
+ wait for clock_period;
+ out1t := "01101000000000000000000000000000"; -- reduce test
+ report_error ("_reduce -0 test", out1, out1t);
+ wait for clock_period;
+ out1t := "01010100000000000000000000000000"; -- reduce test
+ report_error ("_reduce 0 test", out1, out1t);
+ wait for clock_period;
+ out1t := "00000000000000000000000000000000"; -- 0
+ report_error ("and 0 test", out1, out1t);
+ wait for clock_period;
+ out1t := "01111111100000000000000000000000"; -- + inf
+ report_error ("and 1 test", out1, out1t);
+ wait for clock_period;
+ out1t := "01111111100000000000000000000000"; -- + inf
+ report_error ("or 0 test", out1, out1t);
+ wait for clock_period;
+ out1t := "11111111111111111111111111111111"; -- all 1
+ assert (to_slv (out1) = to_slv (out1t))
+ report "or 1 test error " & to_string (out1) & " /= "
+ & to_string (out1t) severity error;
+ wait for clock_period;
+ out1t := "11111111111111111111111111111111"; -- all 1
+ assert (to_slv (out1) = to_slv (out1t))
+ report "nand 0 test error " & to_string (out1) & " /= "
+ & to_string (out1t) severity error;
+ wait for clock_period;
+ out1t := "10000000011111111111111111111111"; -- - denormal
+ report_error ("nand 1 test", out1, out1t);
+ wait for clock_period;
+ out1t := "10000000011111111111111111111111"; -- - denormal
+ report_error ("nor 0 test", out1, out1t);
+ wait for clock_period;
+ out1t := "00000000000000000000000000000000"; -- 0
+ report_error ("nor 1 test", out1, out1t);
+ wait for clock_period;
+ out1t := "01111111100000000000000000000000"; -- + inf
+ report_error ("xor 0 test", out1, out1t);
+ wait for clock_period;
+ out1t := "10000000011111111111111111111111"; -- - denormal
+ report_error ("xor 1 test", out1, out1t);
+ wait for clock_period;
+ out1t := "10000000011111111111111111111111"; -- - denormal
+ report_error ("xnor 0 test", out1, out1t);
+ wait for clock_period;
+ out1t := "01111111100000000000000000000000"; -- + inf
+ report_error ("xnor 1 test", out1, out1t);
+ wait for clock_period;
+ out1t := "00000000000000000000000000000000"; -- 0
+ report_error ("and 0 test", out1, out1t);
+ wait for clock_period;
+ out1t := "01111111100000000000000000000000"; -- + inf
+ report_error ("and 1 test", out1, out1t);
+ wait for clock_period;
+ out1t := to_float(3, out1t);
+ report_error ("2 + 1 test", out1, out1t);
+ wait for clock_period;
+ report_error ("1 + 2 test", out1, out1t);
+ wait for clock_period;
+ report_error ("2 + 1.0 test", out1, out1t);
+ wait for clock_period;
+ report_error ("1.0 + 2 test", out1, out1t);
+ wait for clock_period;
+ out1t := to_float(2, out1t);
+ report_error ("2 * 1 test", out1, out1t);
+ wait for clock_period;
+ report_error ("1 * 2 test", out1, out1t);
+ wait for clock_period;
+ report_error ("2 * 1.0 test", out1, out1t);
+ wait for clock_period;
+ report_error ("1.0 * 2 test", out1, out1t);
+
+ wait for clock_period;
+ assert (false) report "Testing complete" severity note;
+ stop_clock <= true;
+ wait;
+ end process checktest;
+end architecture testbench;
OpenPOWER on IntegriCloud