1
votes

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;
2
You need one 16-bits adder with carry input: s=x+y+c where x and y are 16-bits unsigned and c is the one-bit carry input. As you already understood well, you will have to use multiplexers on front of your adder such that, depending on ctrl it computes a+b+0, a+(not b)+1, a+1+0 or a-1+0. So, x is always equal to a, y equals b, not b, x"0001" (hexadecimal notation) or x"ffff" and cequals '0' or '1'. Code it exactly like this, using concurrent signal assignments and you will be done.Renaud Pacalet
Thank you very much, i missed the carry in logic. This problem will be solved.Nominal

2 Answers

2
votes

I designed this circuit with Renaud Pacalet contribute.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Ex_7_1_b is
    generic( g_BUS_WIDTH : integer := 16    );
    port ( 
            i_a : in  std_logic_vector (g_BUS_WIDTH - 1 downto 0);
            i_b : in  std_logic_vector (g_BUS_WIDTH - 1 downto 0);
            i_ctrl : in  std_logic_vector (1 downto 0);
            o_y : out  std_logic_vector (g_BUS_WIDTH - 1 downto 0)
         );
end Ex_7_1_b;

architecture RTL of Ex_7_1_b is
    signal r_A_Ext, r_B_Ext : unsigned(g_BUS_WIDTH downto 0);
    signal r_Carry_In : std_logic;
    signal r_Adder : unsigned(g_BUS_WIDTH - 1 downto 0);
    signal w_Mux_Inv : unsigned(g_BUS_WIDTH - 1 downto 0);
    signal w_Mux_Sel : unsigned(g_BUS_WIDTH - 1 downto 0);
    signal r_Result : unsigned(g_BUS_WIDTH downto 0);
begin
    r_A_Ext <= unsigned(i_a & '1');

    w_Mux_Sel <= to_unsigned(1, w_Mux_Sel'length) when i_ctrl(1) = '1' else unsigned(i_b);
    w_Mux_Inv <= not (w_Mux_Sel) when i_ctrl(0) = '1' else w_Mux_Sel;

    r_Carry_In <= '1' when i_ctrl(0) = '1' else '0';

    r_B_Ext <= w_Mux_Inv & r_Carry_In;

    r_Result <= r_A_Ext + r_B_Ext;
    o_y <= std_logic_vector(r_Result(g_BUS_WIDTH downto 1));
end RTL;
1
votes

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;