📄 example16_9.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 + -