7.1 - Consider an Arithmetic Circuit that can perform four operations: a+b, a-b, a+1 and a-1, where a and b are 16-bit Unsigned Numbers and the desired operation is specified by a 2-bit Control Signal, ctrl.
Is it possible to design this circuit just with one adder without using sequential logic.
I designed this circuit with 2's complementary logic but i cannot add logic (a + (not b) + 1) just one adder without memory components
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Ex_7_1_b is
generic( BUS_WIDTH : integer := 16 );
port ( a : in STD_LOGIC_VECTOR (BUS_WIDTH - 1 downto 0);
b : in STD_LOGIC_VECTOR (BUS_WIDTH - 1 downto 0);
ctrl : in STD_LOGIC_VECTOR (1 downto 0);
y : out STD_LOGIC_VECTOR (BUS_WIDTH - 1 downto 0)
);
end Ex_7_1_b;
architecture Behavioral of Ex_7_1_b is
signal adder : unsigned(BUS_WIDTH - 1 downto 0);
signal mux_sign : unsigned(BUS_WIDTH - 1 downto 0);
signal mux_inp_sel : unsigned(BUS_WIDTH - 1 downto 0);
signal mux_val : unsigned(BUS_WIDTH - 1 downto 0);
signal result : unsigned(BUS_WIDTH - 1 downto 0);
begin
mux_val <= to_unsigned(0, mux_val'length) when ctrl(1) = '1' else to_unsigned(1, mux_val'length);
mux_inp_sel <= mux_val when ctrl(0) = '1' else unsigned(b);
mux_sign <= not (mux_inp_sel) when ctrl(1) = '1' else mux_inp_sel;
result <= unsigned(a) + mux_sign;
y <= std_logic_vector(result);
end Behavioral;
The solution you found yourself is fine but it uses a 17-bits adder instead of a 16-bits one. With smart enough synthesizers it should not make any difference. Just for completeness here is another, 16-bits (and slightly simpler), solution:
architecture RTL of Ex_7_1_b is
signal x, y0, y1: unsigned(g_BUS_WIDTH - 1 downto 0);
begin
x <= unsigned(i_a);
y0 <= unsigned(i_b) when i_ctrl(1) = '0' else x"0001";
y1 <= not y0 when i_ctrl(0) = '1' else y0;
o_y <= std_logic_vector(x + y1 + i_ctrl(0));
end architecture RTL;
Note: this works only in VHDL 2008 where the addition of an unsigned
and a std_logic
is defined. If you must use an older version of the VHDL standard use the following, instead:
architecture RTL of Ex_7_1_b is
signal x, y0, y1: unsigned(g_BUS_WIDTH - 1 downto 0);
signal c: natural range 0 to 1;
begin
x <= unsigned(i_a);
y0 <= unsigned(i_b) when i_ctrl(1) = '0' else x"0001";
y1 <= not y0 when i_ctrl(0) = '1' else y0;
c <= 1 when i_ctrl(0) = '1' else 0;
o_y <= std_logic_vector(x + y1 + c);
end architecture RTL;