如何删除 vhdl 中的闩锁和 RTL_ROM 的用途?
how to remove the latch in vhdl and purpose of RTL_ROM?
下面的代码是一个简单的16位加法器(只用了一个四位加法器)。我试着避开所有的闩锁。但是我无法移除图像中突出显示的闩锁(sum_16_temp)。任何人都可以帮助我避免这种闩锁。如果有人能帮助我理解 RTL_ROM(next_state_i 的目的,我将不胜感激。 =13=]
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;
我不愿意回答没有 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 的半字节来消除 sum_16_temp。
图中锁存器的 RTL_ROM 输入为您要消除的当前锁存器提供了相同的 nybble 转向。
您在此答案分析中修改的代码。如果没有 four_bit_adder 的实体和体系结构对,也没有应用刺激的方法来确保功能,答案只会解决您要删除的闩锁。
这个答案中的代码确实进行了分析,但没有更多的内容无法详细说明或模拟。
仔细检查后发现您的设计规范存在其他问题
严格来说组合过程敏感性列表:
state_machine:
process (state, reset_16)
还应包含所有输入。这通常不会产生合成伪影,但会影响模拟结果(输出延迟,直到敏感列表中的事件和信号丢失 'glitches')。
大多数综合软件忽略敏感度列表,而您在问题中展示了映射结果。
将在信号分配右侧的表达式中找到的信号添加到灵敏度列表:
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;
并得到:
看起来有用的东西。
(请注意,这并不是一个详尽的测试,应该构建一组输入值对,用于选择性地测试跨 nybbles 的进位输入)。
下面的代码是一个简单的16位加法器(只用了一个四位加法器)。我试着避开所有的闩锁。但是我无法移除图像中突出显示的闩锁(sum_16_temp)。任何人都可以帮助我避免这种闩锁。如果有人能帮助我理解 RTL_ROM(next_state_i 的目的,我将不胜感激。 =13=]
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;
我不愿意回答没有 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 的半字节来消除 sum_16_temp。
图中锁存器的 RTL_ROM 输入为您要消除的当前锁存器提供了相同的 nybble 转向。
您在此答案分析中修改的代码。如果没有 four_bit_adder 的实体和体系结构对,也没有应用刺激的方法来确保功能,答案只会解决您要删除的闩锁。
这个答案中的代码确实进行了分析,但没有更多的内容无法详细说明或模拟。
仔细检查后发现您的设计规范存在其他问题
严格来说组合过程敏感性列表:
state_machine:
process (state, reset_16)
还应包含所有输入。这通常不会产生合成伪影,但会影响模拟结果(输出延迟,直到敏感列表中的事件和信号丢失 'glitches')。
大多数综合软件忽略敏感度列表,而您在问题中展示了映射结果。
将在信号分配右侧的表达式中找到的信号添加到灵敏度列表:
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;
并得到:
看起来有用的东西。
(请注意,这并不是一个详尽的测试,应该构建一组输入值对,用于选择性地测试跨 nybbles 的进位输入)。