Raviteja
Raviteja

Reputation: 35

how to remove the latch in vhdl and purpose of RTL_ROM?

The code below is a simple 16 bit adder(which uses only one four bit adder). i tried avoiding all the latches. But i am not able to remove the latch that is highlighted(sum_16_temp) in the image. can any one help me in avoiding this latch. And i would appreciate if someone could help me understanding the purpose of RTL_ROM(next_state_i right before the latch)

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;

    entity sixteen_bit_adder is
        Port ( a_16 : in STD_LOGIC_VECTOR (15 downto 0);
               b_16 : in STD_LOGIC_VECTOR (15 downto 0);
               carry_in_16 : in STD_LOGIC;
               clk : in std_logic;
               reset_16 : in std_logic;
               done_addition : out std_logic;
               sum_16 : out STD_LOGIC_VECTOR (15 downto 0);
               carry_out_16 : out STD_LOGIC);

    end sixteen_bit_adder;

    architecture structural of sixteen_bit_adder is

                              ------------------signal declaration------------------
    signal sum_16_temp      : STD_LOGIC_VECTOR (15 downto 0):=x"0000";      -- temporary register for sum
    signal carry_out_temp   : std_logic;                           -- temporary register for carry
    type state_type is (s0,s1,s2,s3,s4);                              -- states;
    signal next_state,state: state_type;
    signal a_4,b_4,sum_4: STD_LOGIC_VECTOR (3 downto 0):=x"0";           -- temp for 4 bit component inputs
    signal carry_in_4,carry_out_4,done_temp: std_logic:='0'; 
                               -------end of signal declaration-------

                               ------component declaration-------------

    component  four_bit_adder is
        Port ( a : in STD_LOGIC_VECTOR (3 downto 0);
               b : in STD_LOGIC_VECTOR (3 downto 0);
               carry_in : in STD_LOGIC;
               sum_4 : out STD_LOGIC_VECTOR (3 downto 0);
               carry_out : out STD_LOGIC);
    end component four_bit_adder;
                                ------end of component declaraton--------

    begin

    four_bit_adder1: four_bit_adder port map(a_4, b_4, carry_in_4, sum_4, carry_out_4);
    flopping_process:  process(reset_16,clk)
                               begin
                                    if reset_16 ='1' then
                                        sum_16          <=   x"0000";
                                        carry_out_16    <=   '0';
                                        state           <=   s0;
                                        done_addition   <=   '0';
                                    elsif rising_edge(clk) then
                                        sum_16          <=   sum_16_temp;
                                        carry_out_16    <=   carry_out_temp;
                                        state           <=   next_state;
                                        done_addition   <=   done_temp;

                                    end if;
                       end process;

    State_machine:     process(state,reset_16)
                                begin
                                if reset_16 ='0' then
                                      case state is
                                            when s0 =>

                                                 a_4             <=   a_16(3 downto 0);
                                                 b_4             <=   b_16(3 downto 0);
                                                 carry_in_4      <=   carry_in_16; 
                                                 next_state      <=   s1;
                                                 sum_16_temp(3 downto 0)     <=   sum_4;
                                                 carry_out_temp    <=   carry_out_4;
                                                 done_temp   <=   '0';

                                            when s1 =>
                                                 a_4             <=   a_16(7 downto 4);
                                                 b_4             <=   b_16(7 downto 4);
                                                 carry_in_4      <=   carry_out_4;
                                                 sum_16_temp(3 downto 0)     <=   sum_4;
                                                 next_state      <=   s2;
                                                 carry_out_temp    <=   carry_out_4;
                                                 done_temp   <=   '0';
                                            when s2 =>
                                                 a_4             <=   a_16(11 downto 8);
                                                 b_4             <=   b_16(11 downto 8);
                                                 carry_in_4      <=   carry_out_4;
                                                 sum_16_temp(7 downto 4)    <=   sum_4;
                                                 next_state      <=   s3;
                                                 carry_out_temp    <=   carry_out_4;
                                                 done_temp   <=   '0';
                                           when s3 =>
                                                 a_4             <=   a_16(15 downto 12);
                                                 b_4             <=   b_16(15 downto 12);
                                                 carry_in_4      <=   carry_out_4;
                                                 sum_16_temp(11 downto 8)    <=   sum_4;
                                                 next_state      <=   s4;
                                                 carry_out_temp    <=   carry_out_4;
                                                 done_temp   <=   '0';
                                           when others =>
                                                 a_4             <=   a_16(15 downto 12);
                                                 b_4             <=   b_16(15 downto 12);
                                                 carry_in_4      <=   carry_out_4;
                                                 sum_16_temp(15 downto 12)    <=   sum_4;
                                                 carry_out_temp    <=   carry_out_4;
                                                 done_temp   <=   '1';
                                                 next_state      <=   s4;

                                            end case;
                                else
                                             a_4             <=   x"0";
                                             b_4             <=   x"0";
                                             carry_in_4      <=   '0';
                                             sum_16_temp     <=   x"0000";
                                             carry_out_temp  <=   '0';
                                             done_temp   <=   '0';
                                             next_state      <=   s0;
                                end if;
                       end process;

    end structural;

enter image description here

Upvotes: 0

Views: 1327

Answers (1)

user1155120
user1155120

Reputation:

I'm loath to provide an answer to a question without an MCVE. There's no way of knowing if there's something else wrong.

library ieee;
use ieee.std_logic_1164.all;

entity sixteen_bit_adder is
    port ( 
        a_16:           in  std_logic_vector (15 downto 0);
        b_16:           in  std_logic_vector (15 downto 0);
        carry_in_16:    in  std_logic;
        clk:            in  std_logic;
        reset_16:       in  std_logic;
        done_addition:  out std_logic;
        sum_16:         out std_logic_vector (15 downto 0);
        carry_out_16:   out std_logic
    );
end entity sixteen_bit_adder;

architecture structural of sixteen_bit_adder is

    -- signal sum_16_temp:       std_logic_vector (15 downto 0) := x"0000";
    signal carry_out_temp:    std_logic;
    type state_type is (s0,s1,s2,s3,s4);
    signal next_state, state: state_type;
    signal a_4, b_4, sum_4:   std_logic_vector (3 downto 0) := x"0";
    signal carry_in_4,
           carry_out_4,
           done_temp:         std_logic := '0'; 


    component  four_bit_adder is
        port ( 
            a:         in  std_logic_vector (3 downto 0);
            b:         in  std_logic_vector (3 downto 0);
            carry_in:  in  std_logic;
            sum_4:     out std_logic_vector (3 downto 0);
            carry_out: out std_logic
        );
    end component four_bit_adder;

begin

four_bit_adder1: 
    four_bit_adder 
        port map (a_4, b_4, carry_in_4, sum_4, carry_out_4);

flopping_process:  
    process (reset_16, clk)
    begin
        if reset_16 = '1' then
            sum_16          <=   x"0000";
            carry_out_16    <=   '0';
            state           <=   s0;
            done_addition   <=   '0';
        elsif rising_edge(clk) then
            case state is
                when s0 =>
                    sum_16(3 downto 0) <= sum_4;
                when s1 =>
                    sum_16(7 downto 4) <= sum_4;
                when s2 =>
                    sum_16(11 downto 8) <= sum_4;
                when s3 =>
                    sum_16(15 downto 12) <= sum_4;
                when others =>
            end case;
            -- sum_16          <=   sum_16_temp;
            carry_out_16    <=   carry_out_temp;
            state           <=   next_state;
            done_addition   <=   done_temp;
        end if;
    end process;

state_machine:
    process (state, reset_16, a_16, b_16, carry_in_16, carry_in_4)
    begin
        if reset_16 = '0' then
            case state is
                when s0 =>
                     a_4             <=   a_16(3 downto 0);
                     b_4             <=   b_16(3 downto 0);
                     carry_in_4      <=   carry_in_16; 
                     next_state      <=   s1;
                     -- sum_16_temp(3 downto 0)     <=   sum_4;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '0';
                when s1 =>
                     a_4             <=   a_16(7 downto 4);
                     b_4             <=   b_16(7 downto 4);
                     carry_in_4      <=   carry_out_4;
                     -- sum_16_temp(3 downto 0)     <=   sum_4;
                     next_state      <=   s2;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '0';
                when s2 =>
                     a_4             <=   a_16(11 downto 8);
                     b_4             <=   b_16(11 downto 8);
                     carry_in_4      <=   carry_out_4;
                     -- sum_16_temp(7 downto 4)    <=   sum_4;
                     next_state      <=   s3;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '0';
               when s3 =>
                     a_4             <=   a_16(15 downto 12);
                     b_4             <=   b_16(15 downto 12);
                     carry_in_4      <=   carry_out_4;
                     -- sum_16_temp(11 downto 8)    <=   sum_4;
                     next_state      <=   s4;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '0';
               when others =>
                     a_4             <=   a_16(15 downto 12);
                     b_4             <=   b_16(15 downto 12);
                     carry_in_4      <=   carry_out_4;
                     -- sum_16_temp(15 downto 12)    <=   sum_4;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '1';
                     next_state      <=   s4;
              end case;
        else
            a_4             <=   x"0";
            b_4             <=   x"0";
            carry_in_4      <=   '0';
            -- sum_16_temp     <=   x"0000";
            carry_out_temp  <=   '0';
            done_temp   <=   '0';
            next_state      <=   s0;
        end if;
    end process;

end architecture structural;

This eliminates sum_16_temp by assigning the output of the adder (sum_4) to the nybbles of sum_16 according to state.

The RTL_ROM input to the latches in your diagram provides the same nybble steering to the present latches you want to eliminate.

Your code modified in this answer analyzes. Without either an entity and architecture pair for four_bit_adder and a method of applied stimuli to insure functionality the answer only addresses the latches you want to remove.

The code in this answer does analyze, but without more can't be elaborated or simulated.

On closer examination there are additional issues with your design specification

Strictly speaking the combinatorial process sensitivity list:

state_machine:
        process (state, reset_16)

Should also contain any and all inputs. This generally doesn't produce synthesis artifacts, while it can affect simulation results (output delays until events and signals that are in the sensitivity list, missing 'glitches').

Most synthesis software ignores sensitivity lists and you're demonstrating a mapped result in the question.

Adding signals found in expressions on the right hand side of signal assignments to the sensitivity list:

    state_machine:
        process (state, reset_16, a_16, b_16, carry_in_16, carry_in_4)

reveals a design issue. In states s1, s2, s3 and s4 you have:

                     carry_in_4      <=   carry_out_4;

without benefit of a register for holding the previous nybble carry out value. This won't simulate and should give you at least a warning during synthesis. Attaching the carry out to the carry in of your 4 bit adder provides a feedback loop with the potential of providing a different result. This can be described as a relaxation oscillator.

The solution to the carry in and carry out feedback is subtle and reveals your design specification is not yet complete.

So I made the changes to support the carry correctly, also fixing the sensitivity list:

architecture structural of sixteen_bit_adder is

    -- signal sum_16_temp:       std_logic_vector (15 downto 0) := x"0000";
    signal carry_out_temp:    std_logic;
    type state_type is (s0,s1,s2,s3,s4);
    signal next_state, state: state_type;
    signal a_4, b_4, sum_4:   std_logic_vector (3 downto 0) := x"0";
    signal carry_in_4,
           carry_out_4,
           done_temp:         std_logic := '0';


    component  four_bit_adder is
        port ( 
            a:         in  std_logic_vector (3 downto 0);
            b:         in  std_logic_vector (3 downto 0);
            carry_in:  in  std_logic;
            sum_4:     out std_logic_vector (3 downto 0);
            carry_out: out std_logic
        );
    end component four_bit_adder;

begin

four_bit_adder1: 
    four_bit_adder 
        port map (a_4, b_4, carry_in_4, sum_4, carry_out_4);

flopping_process:  
    process (reset_16, clk)
    begin
        if reset_16 = '1' then
            sum_16          <=   x"0000";
            carry_out_16    <=   '0';
            state           <=   s0;
            done_addition   <=   '0';
        elsif rising_edge(clk) then
            case state is
                when s0 =>
                    sum_16(3 downto 0) <= sum_4;

                when s1 =>
                    sum_16(7 downto 4) <= sum_4;
                when s2 =>
                    sum_16(11 downto 8) <= sum_4;
                when s3 =>
                    sum_16(15 downto 12) <= sum_4;
                when others =>
            end case;
            -- sum_16          <=   sum_16_temp;
            carry_out_16    <=   carry_out_temp;
            state           <=   next_state;
            done_addition   <=   done_temp;
        end if;
    end process;

state_machine:
    process (state,reset_16, a_16, b_16, carry_in_16)
    begin
        if reset_16 = '0' then
            case state is
                when s0 =>
                     a_4             <=   a_16(3 downto 0);
                     b_4             <=   b_16(3 downto 0);
                     carry_in_4      <=   carry_in_16; 
                     next_state      <=   s1;
                     -- sum_16_temp(3 downto 0)     <=   sum_4;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '0';
                when s1 =>
                     a_4             <=   a_16(7 downto 4);
                     b_4             <=   b_16(7 downto 4);
                     carry_in_4      <=   carry_out_4;
                     -- sum_16_temp(3 downto 0)     <=   sum_4;
                     next_state      <=   s2;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '0';
                when s2 =>
                     a_4             <=   a_16(11 downto 8);
                     b_4             <=   b_16(11 downto 8);
                     carry_in_4      <=   carry_out_4;
                     -- sum_16_temp(7 downto 4)    <=   sum_4;
                     next_state      <=   s3;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '0';
               when s3 =>
                     a_4             <=   a_16(15 downto 12);
                     b_4             <=   b_16(15 downto 12);
                     carry_in_4      <=   carry_out_4;
                     -- sum_16_temp(11 downto 8)    <=   sum_4;
                     next_state      <=   s4;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '0';
               when others =>
                     a_4             <=   a_16(15 downto 12);
                     b_4             <=   b_16(15 downto 12);
                     carry_in_4      <=   carry_out_4;
                     -- sum_16_temp(15 downto 12)    <=   sum_4;
                     carry_out_temp    <=   carry_out_4;
                     done_temp   <=   '1';
                     next_state      <=   s4;
              end case;
        else
            a_4             <=   x"0";
            b_4             <=   x"0";
            carry_in_4      <=   '0';
            -- sum_16_temp     <=   x"0000";
            carry_out_temp  <=   '0';
            done_temp   <=   '0';
            next_state      <=   s0;
        end if;
    end process;

end architecture structural;

Dummied up a four bit adder:

library ieee;

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity  four_bit_adder is
    port ( 
        a:         in  std_logic_vector (3 downto 0);
        b:         in  std_logic_vector (3 downto 0);
        carry_in:  in  std_logic;
        sum_4:     out std_logic_vector (3 downto 0);
        carry_out: out std_logic
    );
end entity four_bit_adder;

architecture foo of four_bit_adder is
    signal sum:   std_logic_vector (5 downto 0);
begin
    sum <= std_logic_vector (
            unsigned ("0" & a & carry_in) + unsigned (b & carry_in)
           );
    carry_out <= sum(5);
    sum_4 <= sum(4 downto 1);
end architecture;

and a testbench:

library ieee;
use ieee.std_logic_1164.all;

entity sixteen_bit_adder_tb is
end entity;

architecture foo of sixteen_bit_adder_tb is
    signal a_16:           std_logic_vector (15 downto 0) := (others => '0');
    signal b_16:           std_logic_vector (15 downto 0) := (others => '0');
    signal carry_in_16:    std_logic := '0';
    signal clk:            std_logic := '0';
    signal reset_16:       std_logic := '1';
    signal done_addition:  std_logic;
    signal sum_16:         std_logic_vector (15 downto 0);
    signal carry_out_16:   std_logic;
begin
DUT:
    entity work.sixteen_bit_adder
        port map (
            a_16 => a_16,
            b_16 => b_16,
            carry_in_16 => carry_in_16,
            clk => clk,
            reset_16 => reset_16,
            done_addition => done_addition,
            sum_16 => sum_16,
            carry_out_16 => carry_out_16
        );
CLOCK:
    process
    begin
        wait for 5 ns;
        clk <= not clk;
        if now > 140 ns then
            wait;
        end if;
    end process;
STIMLI:
    process
    begin
        wait for 20 ns;
        a_16 <= x"0043";
        b_16 <= x"FFFE";  -- one's complement of 1
        carry_in_16 <= '1';  -- plus one is the two's complement
        reset_16 <= '0';
        wait until done_addition = '1';
        wait until rising_edge (clk);
        reset_16 <= '1';
        wait until rising_edge (clk);
        a_16 <= x"1234";
        b_16 <= x"4567";
        carry_in_16 <= '0';
        reset_16 <= '0';
        wait;

    end process;
end architecture;

and got:

sixteen_bit_adder_tb.png

something that looks like it works.

(Note that this doesn't demonstrate an exhaustive test, a set of input value pairs that selectively test carry inputs across nybbles should be constructed).

Upvotes: 2

Related Questions