0

下面的代码是一个简单的 16 位加法器(它只使用一个四位加法器)。我试着避开所有的闩锁。但我无法删除图像中突出显示的锁存器(sum_16_temp)。谁能帮我避免这个闩锁。如果有人能帮助我理解RTL_ROM的用途(在闩锁之前的next_state_i ),我将不胜感激

    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;

在此处输入图像描述

4

1 回答 1

2

我不愿意在没有MCVE的情况下提供问题的答案。没有办法知道是否还有其他问题。

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;

这通过根据状态将加法器 (sum_4) 的输出分配给 sum_16 的 nybbles 来消除 sum_16_temp。

图中锁存器的 RTL_ROM 输入为您想要消除的当前锁存器提供相同的 nybble 转向。

您在此答案分析中修改的代码。如果没有用于four_bit_adder 的实体和架构对以及应用刺激的方法来确保功能,答案只能解决您想要移除的锁存器。

此答案中的代码确实进行了分析,但没有更多内容无法详细说明或模拟。

仔细检查后,您的设计规范还有其他问题

严格来说组合过程敏感度列表:

state_machine:
        process (state, reset_16)

还应包含任何和所有输入。这通常不会产生合成伪影,但会影响仿真结果(输出延迟,直到灵敏度列表中的事件和信号,丢失“毛刺”)。

大多数综合软件会忽略敏感度列表,而您正在展示问题中的映射结果。

将信号分配右侧表达式中的信号添加到灵敏度列表中:

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

揭示了一个设计问题。在状态 s1、s2、s3 和 s4 你有:

                     carry_in_4      <=   carry_out_4;

没有使用寄存器来保存前一个 nybble 执行值。这不会模拟,并且应该在综合过程中至少给你一个警告。将进位附加到 4 位加法器的进位提供了一个反馈循环,有可能提供不同的结果。这可以被描述为张弛振荡器。

导入和执行反馈的解决方案很微妙,表明您的设计规范尚未完成。

因此,我进行了更改以正确支持进位,同时修复了敏感度列表:

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;

模拟了一个四位加法器:

图书馆 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;

和一个测试台:

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;

并得到:

十六位加法器 tb.png

看起来有效的东西。

(请注意,这并不是一个详尽的测试,应该构建一组输入值对,选择性地测试跨 nybbles 的进位输入)。

于 2016-06-27T21:42:48.377 回答