--
-- VHDL을 이용한 FPGA 설계
-- 3장. section07. n비트 가산 / 감산기
-- DE2-117 구현
--
library ieee;
use ieee.std_logic_1164.all;
package my_package is
constant adder_width : integer := 4;
constant result_width : integer := 5;
constant max_result : integer := 2**result_width - 1;
constant min_result : integer := -2**result_width;
subtype adder_value is integer range 0 to 2**adder_width - 1;
subtype result_value is integer range min_result to max_result;
end my_package;
library ieee;
use ieee.std_logic_1164.all;
use work.my_package.all;
entity nbitAddSub is
port (
a, b : in adder_value;
mode : in std_logic;
sega : out std_logic_vector (6 downto 0); -- hex6 of de2-117
segb : out std_logic_vector (6 downto 0); -- hex4 of de2-117
segmode : out std_logic_vector (6 downto 0); -- hex3 of de2-117
segsign : out std_logic; -- hex2 of de2-117
seg1 : out std_logic_vector (6 downto 0); -- hex0 of de2-117
seg2 : out std_logic_vector (6 downto 0); -- hex1 of de2-117
underflow : out std_logic;
overflow : out std_logic
);
end nbitAddSub;
architecture arc of nbitAddSub is
signal over, under : std_logic;
signal seg1Reg, seg2Reg : integer range 0 to 15;
-- convert integer value to drive 7-segment
--
function toSeg(
in_value : in integer range 0 to 15
) return std_logic_vector is
begin
case in_value is
when 0 => return "1000000";
when 1 => return "1111001";
when 2 => return "0100100";
when 3 => return "0110000";
when 4 => return "0011001";
when 5 => return "0010010";
when 6 => return "0000010";
when 7 => return "1011000";
when 8 => return "0000000";
when 9 => return "0011000";
when 10 => return "0001000";
when 11 => return "0000011";
when 12 => return "0100111";
when 13 => return "0100001";
when 14 => return "0000110";
when 15 => return "0001110";
when others => return "1111111";
end case;
end toSeg;
begin
process (mode, a, b, over, under)
variable res : result_value;
begin
if (mode = '1') then -- if key0 is not pressed
res := a + b;
segmode <= toSeg(10); -- display 'A' for mode add
else
res := a - b;
segmode <= toSeg(5); -- display 'S' for mode subtraction
end if;
if (res > max_result) then
over <= '1';
else
over <= '0';
end if;
if (res < min_result) then
under <= '1';
else
under <= '0';
end if;
if (res < 0) then
segsign <= '0'; -- turn on minus sign
seg2Reg <= -res / 16;
seg1Reg <= -res mod 16;
else
segsign <= '1'; -- turn off minus sign
seg2Reg <= res / 16;
seg1Reg <= res mod 16;
end if;
overflow <= over;
underflow <= under;
end process;
sega <= toSeg(a);
segb <= toSeg(b);
seg1 <= toSeg(seg1Reg);
seg2 <= toSeg(seg2Reg);
end arc;