diff options
author | Bert Lange <b.lange@fzd.de> | 2011-11-07 15:06:13 +0100 |
---|---|---|
committer | Bert Lange <b.lange@fzd.de> | 2011-11-07 15:06:13 +0100 |
commit | 97dacd8ba4f2df6d93706f43f672a35cdfbbcf89 (patch) | |
tree | a3b67b8f8eb075ff6f40ba4f29ab6d40e5367eb5 /ieee_proposed | |
parent | 09b62e30ab072eafd4792104eb1f0971d1f96b5c (diff) | |
download | zpu-97dacd8ba4f2df6d93706f43f672a35cdfbbcf89.zip zpu-97dacd8ba4f2df6d93706f43f672a35cdfbbcf89.tar.gz |
initial commit
Diffstat (limited to 'ieee_proposed')
-rw-r--r-- | ieee_proposed/rtl_tb/fixed_synth.vhd | 741 | ||||
-rw-r--r-- | ieee_proposed/rtl_tb/float_synth.vhd | 712 | ||||
-rw-r--r-- | ieee_proposed/rtl_tb/test_fixed_synth.vhd | 439 | ||||
-rw-r--r-- | ieee_proposed/rtl_tb/test_float_synth.vhd | 892 |
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; |