Reputation: 35
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;
Upvotes: 0
Views: 1327
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:
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