library ieee;
use ieee. std_logic_1164.all;
use ieee. numeric_std.ALL;
entity fp_adder_test is
port (
clk: in std_logic;
sw: in std_logic_vector (7 downto 0) ;
btn: in std_logic_vector (3 downto 0) ;
an: out std_logic_vector (3 downto 0) ;
sseg: out std_logic_vector (7 downto 0)
) ;
end fp_adder_test;
architecture arch of fp_adder_test is
signal sign1 , sign2 : std_logic;
signal exp1 , exp2: std_logic_vector (3 downto 0) ;
signal frac1 , frac2 : std_logic_vector (7 downto 0) ;
signal sign_out : std_logic;
signal exp_out : std_logic_vector (3 downto 0) ;
signal led3, led2, led1, led0: std_logic_vector (7 downto 0) ;
signal frac_out : std_logic_vector (7 downto 0) ;
begin
--s e t u p t h e f p a d d e r i n p u t s i g n a l s
sign1 <= '0';
exp1 <= "1000";
frac1<= '0' & sw(1) & sw(0) & "01010" ;
sign2 <= sw(7);
exp2 <= btn;
frac2 <= '1' & sw(6 downto 0);
--instantiate fp adder
fp_add_unit : entity work.fp_adder
port map(
sign1=>sign1, sign2=>sign2, exp1=>exp1, exp2=>exp2,
frac1=>frac1, frac2=>frac2,
sign_out=>sign_out , exp_out=>exp_out ,
frac_out=>frac_out
);
--i n s t a n t i a t e t h r e e i n s t a n c e s of h e x d e c o d e r s
--e x p o n e n t
sseg_unit_0 : entity work.hex_to_sseg
port map(hex=>exp_out , dp=>'0' , sseg=>led0);
-- 4 LSBs of f r a c t i o n
sseg_unit_1 : entity work.hex_to_sseg
port map(hex=>frac_out(3 downto 0) ,
dp=>'1',sseg=>led1);
sseg_unit_2: entity work.hex_to_sseg
-- 4 MSBs of f r a c t i o n
port map(hex=>frac_out ( 7 downto 4 ) ,
dp=>'0', sseg=>led2);
--s i g n
led3 <=
"10111111" when sign_out='1' else -- m i d d l e b a r
"11111111" ; --bl a n k
--i s t a n t i a t e 7 - s e g LED d i s p l a j t i m e - m u 1 t i p 1 e x i n g m o d u l e
disp_unit : entity work.disp_mux
port map(
clk => clk , reset => '0' ,
in0=>led0, in1=> led1 , in2 => led2 , in3 => led3 ,
an => an , sseg => sseg
);
end arch;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fp_adder is
port (
sign1,sign2 : in std_logic ;
exp1 , exp2 : in std_logic_vector (3 downto 0 ) ;
frac1 , frac2: in std_logic_vector (7 downto 0) ;
sign_out: out std_logic;
frac_out : out std_logic_vector ( 7 downto 0 );
exp_out : out std_logic_vector (3 downto 0)
);
end fp_adder ;
architecture arch of fp_adder is
--s u f f i x b , s , a , n f o r
--b i g , s m a l l , a l i g n e d , n o r m a l i z e d number
signal signb , signs : std_logic;
signal expb, exps , expn: unsigned (3 downto 0) ;
signal fracb, fracs, fraca, fracn: unsigned(7 downto 0 ) ;
signal sum_norm: unsigned ( 7 downto 0 ) ;
signal exp_diff : unsigned (3 downto 0 ) ;
signal sum: unsigned(8 downto 0); --one e x t r a f o r c a r r y
signal lead0: unsigned (2 downto 0) ;
-- 1 s t s t a g e : s o r t t o find t h e l a r g e r number
begin
process (sign1 , sign2, exp1, exp2, frac1 , frac2)
begin
if (exp1 & frac1) > (exp2 & frac2) then
signb <= sign1;
signs <= sign2;
expb <= unsigned (exp1) ;
exps <= unsigned (exp2) ;
fracb <= unsigned(frac1);
fracs <= unsigned(frac2);
else
signb <= sign2;
signs <= sign1;
expb <= unsigned (exp2 ) ;
exps <= unsigned (exp1) ;
fracb <= unsigned(frac2);
fracs <= unsigned(frac1);
end if ;
end process;
--2nd s t a g e : a l i g n s m a l l e r number
exp_diff <= expb - exps;
with exp_diff select
fraca <=
fracs when "0000",
"0" & fracs(7 downto 1) when"0001",
"00" & fracs(7 downto 2) when"0010",
"000" & fracs(7 downto 3) when"0011",
"0000" & fracs(7 downto 4) when"0100",
"00000" & fracs(7 downto 5) when"0101",
"000000" & fracs(7 downto 6) when"0110",
"0000000" & fracs(7) when"0111",
"00000000" when others;
-- 3 r d s t a g e : a d d / s u b t r a c t
sum <= ( '0' & fracb) + ( '0' & fraca) when signb=signs else
( '0' & fracb) - ( '0' & fraca);
-- 4 t h s t a g e : n o r m a l i z e
lead0 <= "000" when (sum(7)='1') else
"001" when (sum(6)='1') else
"010" when (sum(5)='1') else
"011" when (sum(4)='1') else
"100" when (sum(3)='1') else
"101" when (sum(2)='1') else
"110" when (sum(1)='1') else
"111" ;
-- c o u n t l e a d i n g 0 s
--s h i f r s i g n i f i c a n d a c c o r d i n g t o l e a d i n g 0
with lead0 select
sum_norm <=
sum(7 downto 0) when "000" ,
sum(6 downto 0) & '0' when "001",
sum(5 downto 0 ) & "00" when "010",
sum(4 downto 0 ) & "000" when "011",
sum(3 downto 0 ) & "0000" when "100",
sum(2 downto 0 ) & "00000" when "101",
sum(1 downto 0 ) & "000000" when "110" ,
sum(0) & "0000000" when others;
process (sum, sum_norm, expb, lead0)
begin
if sum (8) = '1' then -- w / c a r r y o u t ; s h i f t f r a c t o r i g h t
expn <= expb + 1 ;
fracn <= sum(8 downto 1);
elsif (lead0 > expb) then -- t o o s m a l l t o n o r m a l i z e ;
expn <= (others => '0' ) ; -- s e t t o 0
fracn <= (others => '0' ) ;
else
expn <= expb - lead0;
fracn <= sum_norm;
end if;
end process;
-- f o r m o u t p u t
sign_out <= signb;
exp_out <= std_logic_vector(expn);
frac_out <= std_logic_vector(fracn);
end arch;
library ieee;
use ieee. std_logic_1164.all;
entity hex_to_sseg is
port (
hex: in std_logic_vector (3 downto 0 ) ;
dp: in std_logic;
sseg: out std_logic_vector (7 downto 0 )
);
end hex_to_sseg;
architecture arch of hex_to_sseg is
begin
with hex select
--hex - t o - 7- s e g in e IZ t I e d decoding
-- Use a with-select statement to light up relevant LEDs
-------------------------------------------------
-- Encoder
-------------------------------------------------
-- HEX-to-seven-segment decoder
-- segment encoding
-- 0
-- ---
-- 5 | | 1
-- --- <------6
-- 4 | | 2
-- ---
-- 3
sseg(6 downto 0 ) <=
--6542130
"1000000" when "0000",--0
"1110011" when "0001",--1
"0101000" when "0010",--2
"0110000" when "0011",--3
"0010011" when "0100",--4
"0010100" when "0101",--5
"0000100" when "0110",--6
"1110010" when "0111",--7
"0000000" when "1000",--8
"0010000" when "1001",--9
"0000010" when "1010",--a
"0000101" when "1011",--b
"0101101" when "1100",--c
"0100001" when "1101",--d
"0001110" when "1110",--e
"0001110" when others;--f
sseg(7) <= dp;
end arch;
library ieee;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;
entity disp_mux is
port(
clk,reset: in std_logic;
in3,in2,in1,in0: in std_logic_vector(7 downto 0 ) ;
an: out std_logic_vector (3 downto 0 ) ;
sseg : out std_logic_vector ( 7 downto 0 )
);
end disp_mux ;
architecture arch of disp_mux is
--r e f r e s h i n g r a t e a r o u n d 800 Hz ( 5 0 M H z / 2 ^ 1 6 )
constant N : integer :=3;
signal q_reg , q_next : unsigned ( N-1 downto 0) ;
signal sel: std_logic_vector (1 downto 0 ) ;
--r e g i s t e r
begin
process (clk, reset)
begin
if reset='1' then
q_reg <= ( others => '0' ) ;
elsif(clk'event and clk='1') then
q_reg <= q_next;
end if ;
end process ;
--n e x t - s t a t e l o g i c f o r t h e c o u n t e r
q_next <= q_reg + 1 ;
-- 2 MSBs o f c o u n t e r t o c o n t r o l 4 - t o - I m u l t i p l e x i n g
-- and t o g e n e r a t e a c t i v e - l o w e n a b l e s i g n a l
sel <= std_logic_vector(q_reg(N-1 downto N-2)) ;
process (sel , in0, in1 , in2, in3)
begin
case sel is
when "00" =>
an <= "0001";
sseg <= in0;
when "01" =>
an <= "0010";
sseg <= in1;
when "10" =>
an <= "0100";
sseg <= in2;
when others =>
an <= "1000";
sseg <= in3;
end case;
end process;
end arch;
No comments:
Post a Comment