⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 example16_9.vhd

📁 fp codes is used to realize the aritjmetics
💻 VHD
字号:
library ieee; use ieee.std_logic_1164.all;
--use ieee.std_logic_arith.all;
--use ieee.std_logic_unsigned.all;
package mypackage is
constant p: natural := 4;
constant B: natural := 10;
constant B_div_2: natural := 5;
constant NDIGITS :INTEGER := p+1;
constant PDIGITS :INTEGER := p+3;
subtype digit is natural range 0 to B-1;
type digit_vector is array (integer range <>) of digit;
type mybit_vector is array (integer range <>) of std_logic;
--function to_integer (x: digit_vector) return natural;
--function to_digit_vector (int_x: natural; n: natural) return digit_vector;
end mypackage;

---------------------------------------------------------------
-- RESTORING base-B Divisor
-- 
-- 
---------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use work.mypackage.all;

entity modif_div_rest_baseB is
    port (
        A: in digit_vector(NDIGITS-1 downto 0);
        BB: in digit_vector(NDIGITS-1 downto 0);
        Q: out digit_vector(PDIGITS-1 downto 0);
	  R: out digit_vector(NDIGITS-1 downto 0)
     );
end modif_div_rest_baseB;

architecture div_arch of modif_div_rest_baseB is
component rest_baseB_step is
    port (
		a_by_B: in digit_vector(NDIGITS downto 0);
		BB: in digit_vector(NDIGITS-1 downto 0);
  		q: out digit;
		r: out digit_vector(NDIGITS-1 downto 0)
     );
end component;
type connections_in is array (0 to PDIGITS-1) of digit_vector(NDIGITS downto 0);
type connections_out is array (0 to PDIGITS-1) of digit_vector(NDIGITS-1 downto 0);
Signal wires_in: connections_in;
Signal wires_out: connections_out;
begin
 wires_in(0) <= 0&A; 	 
 divisor: for i in 0 to PDIGITS-1 generate
    rest_step: rest_baseB_step port map (a_by_B => wires_in(i),
  			 BB => BB, q => Q(PDIGITS-i-1), r => wires_out(i));			 
  end generate;
wire_connections: for i in 1 to PDIGITS-1 generate 
wires_in(i) <= wires_out(i-1)&0;
end generate;
  R <= wires_out(PDIGITS-1);
end div_arch;

---------------------------------------------------------------
-- RESTORING base-B Division step
-- 
-- 
---------------------------------------------------------------
library IEEE;
use work.mypackage.all;

entity rest_baseB_step is
    port (
        a_by_B: in digit_vector(NDIGITS downto 0);
        BB: in digit_vector(NDIGITS-1 downto 0);
  		  q: out digit;
		  r: out digit_vector(NDIGITS-1 downto 0)
     );
end rest_baseB_step;

architecture behavioural of rest_baseB_step is
component look_up_table is
    port (
        at: in digit_vector(2 downto 0);
        bt: in digit_vector(1 downto 0);
  		  qt: out digit;
		  qt_1: out digit
     );
end component;
component base_b_mult is
    port (
        a: in digit;
        BB: in digit_vector(NDIGITS-1 downto 0);
  		  m: out digit_vector(NDIGITS downto 0)
     );
end component;
component base_b_adder is
    port (
        a: in digit_vector(NDIGITS-1 downto 0);
        BB: in digit_vector(NDIGITS-1 downto 0);
  		  s: out digit_vector(NDIGITS downto 0)
     );
end component;
component base_b_subt is
    port (
        a: in digit_vector(NDIGITS downto 0);
        BB: in digit_vector(NDIGITS downto 0);
  		  s: out digit_vector(NDIGITS downto 0);
  		  sign: out bit
     );
end component;
signal at: digit_vector(2 downto 0);
signal bt: digit_vector(1 downto 0);
signal qt,qt_1: digit;
signal q_x_b, a_x_BASE, remainder, rem_plus_b: digit_vector(NDIGITS downto 0);
signal sign: bit;
begin
at <= a_by_B(NDIGITS downto NDIGITS-2);
bt <= BB(NDIGITS-1 downto NDIGITS-2);
a_x_BASE <= a_by_B;
LookUpTable: look_up_table port map (at => at, bt => bt, qt => qt, qt_1 => qt_1);			 
mult:        base_b_mult port map (a => qt, BB => BB, m => q_x_b);
subtrator:   base_b_subt port map (a => a_x_BASE, BB => q_x_b, s => remainder, sign => sign);
adder:       base_b_adder port map (a => remainder(NDIGITS-1 downto 0), BB => BB, s => rem_plus_b);
multiplexers: process (sign,qt_1, qt, rem_plus_b,remainder)
begin
	  if sign = '1' then
	 	 q <= qt_1;
		 r <= rem_plus_b(NDIGITS-1 downto 0);
	  else
	 	 q <= qt;
		 r <= remainder(NDIGITS-1 downto 0);
	  end if; 
end process;
end behavioural;

---------------------------------------------------------------
-- RESTORING base-B Division step: base B adder
-- 
-- 
---------------------------------------------------------------

library IEEE;
use work.mypackage.all;

entity base_B_adder is
    port (
        a: in digit_vector(NDIGITS-1 downto 0);
        BB: in digit_vector(NDIGITS-1 downto 0);
  		  s: out digit_vector(NDIGITS downto 0)
     );
end base_B_adder;

architecture behavior of base_B_adder is
begin
   process(BB,A)
	variable carry: digit_vector(NDIGITS downto 0);
	begin
   carry(0) := 0;
	for i in 0 to NDIGITS-1 loop
      s(i) <= (BB(i) + A(i) + carry(i)) mod B;
      carry(i+1) := (BB(i) + A(i) + carry(i)) / B;
   end loop;
	s(NDIGITS) <= carry(NDIGITS);
	end process;
end behavior;

---------------------------------------------------------------
-- RESTORING base-B Division step: base B multiplier
-- 
-- 
---------------------------------------------------------------
library IEEE;
use work.mypackage.all;

entity base_B_mult is
    port (
        a: in digit;
        BB: in digit_vector(NDIGITS-1 downto 0);
  		  m: out digit_vector(NDIGITS downto 0)
     );
end base_B_mult;

architecture behavior of base_B_mult is
begin
   process(BB,A)
	variable carry: digit_vector(NDIGITS downto 0);
	begin
	carry(0) := 0;
	for i in 0 to NDIGITS-1 loop
		m(i) <= (BB(i) * A + carry(i)) mod B;
		carry(i+1) := ( BB(i) * A + carry(i) ) / B;
	end loop;
	m(NDIGITS) <= carry(NDIGITS);
	end process;
end behavior;

---------------------------------------------------------------
-- RESTORING base-B Division step: base B subtractor
-- 
-- 
---------------------------------------------------------------
library IEEE;
use work.mypackage.all;
entity base_B_subt is
    port (
        a: in digit_vector(NDIGITS downto 0);
        BB: in digit_vector(NDIGITS downto 0);
  		  s: out digit_vector(NDIGITS downto 0);
  		  sign: out bit
     );
end base_B_subt;

architecture behavior of base_B_subt is
begin
process(BB,a)
	variable borrow: digit_vector(NDIGITS+1 downto 0);
	begin
	borrow(0) := 0;
	for i in 0 to NDIGITS loop
      s(i) <= (A(i) - BB(i) - borrow(i)) mod B;
      --borrow(i+1) <= (A(i) - BB(i) - borrow(i)) / B;
      if (A(i) - BB(i) - borrow(i)) < 0 then	borrow(i+1) :=	1;
		else borrow(i+1) := 0;
		end if;
	end loop;
	if borrow(NDIGITS+1) = 0 then 
		sign <= '0';
   else 
		sign <= '1';
	end if;
end process;
end behavior;

---------------------------------------------------------------
-- RESTORING base-B Division step: Look Up Table
-- 
-- 
---------------------------------------------------------------
library IEEE;
use work.mypackage.all;
entity look_up_table is
    port (
        at: in digit_vector(2 downto 0);
        bt: in digit_vector(1 downto 0);
  		  qt: out digit;
		  qt_1: out digit
     );
end look_up_table;

architecture behavior of look_up_table is
begin
process(at,bt)
variable at_i,bt_i,qt_i: integer ;
begin
	qt <= 0;
	qt_1 <= 0;
	at_i := at(2) *B*B + at(1)*B + at(0);
	bt_i := bt(1) *B + bt(0);
	if bt_i > 0 then
		qt_i := at_i / bt_i;
		if qt_i < B and qt_i > 0 then
			qt <= qt_i;
			qt_1 <= qt_i - 1;
      elsif qt_i = B then
			qt <= B - 1;
			qt_1 <= B - 1;
		end if;
	end if;
end process;
end behavior;

library ieee; use ieee.std_logic_1164.all;
--use ieee.std_logic_arith.all;
--use ieee.std_logic_unsigned.all;
use work.mypackage.all;
entity division is
port (
s1, s2: in digit_vector(0 downto -p);
sign1, sign2: in std_logic;
e1, e2: in integer;
s: out digit_vector(0 downto -(p+3));
sign: out std_logic;
e: out integer
);
end division;

architecture circuit of division is
component modif_div_rest_baseB
    port (
        A: in digit_vector(NDIGITS-1 downto 0);
        BB: in digit_vector(NDIGITS-1 downto 0);
        Q: out digit_vector(PDIGITS-1 downto 0);
		  R: out digit_vector(NDIGITS-1 downto 0)
     );
end component;
signal int_s1, int_s2, int_remainder: digit_vector(p downto 0);
signal unaligned_quotient: digit_vector(p+2 downto 0);
begin
int_s1(0) <= s1(-p); int_s2(0) <= s2(-p);
to_integers: for i in 1 to p generate
int_s1(i) <= s1(i-p);
int_s2(i) <= s2(i-p);
end generate;
--int_s1(p+1) <= 0; int_s2(p+1) <= s2(0);
divider: modif_div_rest_baseB port map (int_s1, int_s2, unaligned_quotient, int_remainder); 
alignment: for i in 0 downto -(p+2) generate s(i) <= unaligned_quotient(i+p+2); end generate;
process(int_remainder)
variable acc_or: digit;
begin
acc_or := 0;
for i in p downto 0 loop 
if (int_remainder(i) > 0) or (acc_or > 0) then acc_or := 1; end if;
end loop;
if acc_or > 0 then s(-(p+3)) <= 1; else s(-(p+3)) <= 0; end if;
end process;
sign <= sign1 xor sign2;
e <= e1 - e2;
end circuit;

library ieee; use ieee.std_logic_1164.all;
--use ieee.std_logic_arith.all;
--use ieee.std_logic_unsigned.all;
use work.mypackage.all;
entity test_division is end test_division;

architecture test of test_division is
component division
port (
s1, s2: in digit_vector(0 downto -p);
sign1, sign2: in std_logic;
e1, e2: in integer;
s: out digit_vector(0 downto -(p+3));
sign: out std_logic;
e: out integer
);
end component;
signal s1, s2: digit_vector(0 downto -p);
signal sign1, sign2, sign: std_logic;
signal e1, e2, e: integer;
signal s: digit_vector(0 downto -(p+3));
begin
device_under_test: division port map (s1, s2, sign1, sign2, e1, e2, s, sign, e);
s1 <= (3, 4, 3, 7, 5), (2, 5, 4, 9, 1) after 10 ns, (1, 0, 0, 9, 9) after 20 ns;
s2 <= (2, 5, 4, 9, 1), (3, 4, 3, 7, 5) after 10 ns, (1, 0, 0, 0, 0) after 40 ns;
sign1 <= '0';
sign2 <= '0';
e1 <= 3, 3 after 10 ns, 2 after 20 ns;
e2 <= -1, 2 after 10 ns, 3 after 20 ns;
end test;

library ieee; use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.mypackage.all;
entity normalization is
port (
e: in natural;
s: in digit_vector(0 downto -(p+3));
new_s: out digit_vector(0 downto -(p+3));
new_e: out natural
);
end normalization;

architecture rtl of normalization is
signal quotient_by_B: digit_vector(0 downto -(p+3));
begin
multiply_by_B: for i in -(p+2) to 0 generate quotient_by_B(i) <= s(i-1); end generate; 
quotient_by_B(-(p+3)) <= 0;
new_s <= quotient_by_B when s(0) = 0 else s;
new_e <= e-1 when s(0) = 0 else e;
end rtl;

library ieee; use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.mypackage.all;
entity rounding is
port (
s: in digit_vector(0 downto -(p+3));
e: in natural;
new_s: out digit_vector(0 downto -p);
new_e: out natural
);
end rounding;

architecture behavior of rounding is
begin
process(s)
variable carry: digit_vector(1 downto -p);
variable sum: digit_vector(0 downto -p);
begin
if s(-(p+1)) < B_div_2 then new_s <= s(0 downto -p); new_e <= e;
elsif (s(-(p+1)) > B_div_2) or (s(-(p+2)) > 0) or (s(-p) mod 2 = 1)  then 
--plus ulp
carry(-p) := 1;
for i in -p to 0 loop 
if s(i) + carry(i) > B-1 then carry(i+1) := 1; else carry(i+1) := 0; end if;
sum(i) := (carry(i) + s(i)) mod B;
end loop;
------
new_s <= sum; new_e <= e;
else new_s <= s(0 downto -p); new_e <= e;
end if;
end process;
end behavior;

library ieee; use ieee.std_logic_1164.all;
--use ieee.std_logic_arith.all;
--use ieee.std_logic_unsigned.all;
use work.mypackage.all;
entity fp_divider is
port (
sign1, sign2: in std_logic;
e1, e2: in integer;
s1, s2: in digit_vector(0 downto -p);
sign: out std_logic;
e: out natural;
s: out digit_vector(0 downto -p)
);
end fp_divider;

architecture circuit of fp_divider is
component division
port (
s1, s2: in digit_vector(0 downto -p);
sign1, sign2: in std_logic;
e1, e2: in integer;
s: out digit_vector(0 downto -(p+3));
sign: out std_logic;
e: out integer
);
end component;
component normalization
port (
e: in natural;
s: in digit_vector(0 downto -(p+3));
new_s: out digit_vector(0 downto -(p+3));
new_e: out natural
);
end component;
component rounding
port (
s: in digit_vector(0 downto -(p+3));
e: in natural;
new_s: out digit_vector(0 downto -p);
new_e: out natural
);
end component;
signal e_d, e_n: natural;
signal s_d, s_n: digit_vector(0 downto -(p+3));
begin
divider_component: division 
port map (s1, s2, sign1, sign2, e1, e2, s_d, sign, e_d);
normalization_component: normalization port map (e_d, s_d, s_n, e_n);
rounding_component: rounding port map (s_n, e_n, s, e);
end circuit;


library ieee; use ieee.std_logic_1164.all;
--use ieee.std_logic_arith.all;
--use ieee.std_logic_unsigned.all;
use work.mypackage.all;
entity test_fp_divider is end test_fp_divider;

architecture test of test_fp_divider is
component fp_divider
port (
sign1, sign2: in std_logic;
e1, e2: in integer;
s1, s2: in digit_vector(0 downto -p);
sign: out std_logic;
e: out natural;
s: out digit_vector(0 downto -p)
);
end component;
signal s1, s2, s: digit_vector(0 downto -p);
signal sign1, sign2, sign: std_logic;
signal e1, e2, e: integer;
begin
device_under_test: fp_divider port map (sign1, sign2, e1, e2, s1, s2, sign, e, s);
s1 <= (3, 4, 3, 7, 5), (2, 5, 4, 9, 1) after 10 ns, (1, 0, 0, 9, 9) after 20 ns, 
(1, 0, 0, 0, 0) after 50 ns, (9, 9, 9, 9, 9) after 60 ns;
s2 <= (2, 5, 4, 9, 1), (3, 4, 3, 7, 5) after 10 ns, (1, 0, 0, 0, 0) after 40 ns, 
(9, 9, 9, 9, 9) after 50 ns, (1, 0, 0, 0, 0) after 60 ns;
sign1 <= '0', '1' after 10 ns, '0' after 30 ns;
sign2 <= '0', '1' after 20 ns;
e1 <= 3, 3 after 10 ns, 2 after 20 ns;
e2 <= -1, 2 after 10 ns, 3 after 20 ns;
end test;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -