问题描述
我一直在尝试编写一个添加单个位的组合电路。当我模拟我的代码时,我从我的临时寄存器中获取了未知值(“U”)。我正在添加我的代码以供参考。如果我遗漏了什么或我的逻辑有问题,请纠正我。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity serial_adder is
Port ( a : in std_logic;
b : in std_logic;
c : in std_logic;
d : in std_logic;
e : in std_logic;
f : in std_logic;
g : in std_logic;
h : in std_logic;
sum : out std_logic_vector (3 downto 0));
end serial_adder;
architecture Behavioral of serial_adder is
signal temp1,temp2,temp3,temp4 : std_logic_vector (1 downto 0);
signal temp5,temp6,temp9 : std_logic_vector (2 downto 0);
signal temp7,temp8 :std_logic_vector (1 downto 0);
begin
process (a,b,c,d,e,f,g,h)
begin
temp1(0) <= a or b;
temp2(0) <= c or d;
temp3(0) <= e or f;
temp4(0) <= g or h;
temp7 <= temp1 or temp2;
temp8 <= temp3 or temp4;
temp9 <= temp5 or temp6;
if (a = b and temp1(0) /= a) then
temp1(1) <= not temp1(0);
else
temp1(1) <= '0';
end if;
if (c = d and temp2(0) /= c) then
temp2(1) <= not temp2(0);
else
temp2(1) <= '0';
end if;
if (e = f and temp3(0) /= e) then
temp3(1) <= not temp3(0);
else
temp3(1) <= '0';
end if;
if (g = h and temp4(0) /= g) then
temp4(1) <= not temp4(0);
else
temp4(1) <='0';
end if;
if (temp1(1) = temp2(1) and temp7(1) /= temp1(1)) then
temp5 <= ('1',temp7(1),temp7(0));
end if;
if (temp3(1) = temp4(1) and temp8 (1) /= temp3(1)) then
temp6 <= ('1',temp8(1),temp8(0));
end if;
if (temp5(2) = temp6(2) and temp9(2) /= temp5(2)) then
sum <= ('1',temp9(2),temp9(1),temp9(0));
end if;
end process;
end Behavioral;
解决方法
信号都是“U”,因为进程永远不会被访问。
根据您的敏感列表,该过程仅对输入信号执行
process (a,b,c,d,e,f,g,h)
考虑到这一点,对于要完成的过程,这些信号中没有一个值发生变化。
在您的测试平台中尝试更改其中一个信号的输入值,并且应该执行该过程以更改您的输出值。
,当您在流程中不使用任何时钟时,不确定您想通过流程实现什么目标。通常(至少根据我的经验)您要么使用带有时钟的进程(如果情况下主要是重置),要么使用组合逻辑,在进程之外进行。
在 FPGA 中,只有当敏感列表中的信号发生变化时,进程中的逻辑才会“执行”/“分析”。另一方面,进程之外的 VHDL 代码是用逻辑门实现的(即没有时钟触发器,而是和/或/...门等等),因此不断地几乎立即更新。 如果您使用进程并忘记敏感列表中的信号,或者在不允许与 FPGA 逻辑正确合成的进程中使用奇怪的 VHDL 代码(即像您的示例中那样没有时钟的进程),它可能在模拟器中工作,但不能在 FPGA 中。
话虽如此,我建议将您的问题转换为计时过程:
architecture Behavioral of serial_adder is
-- define signals...
begin
process (clk)
begin
if rising_edge(clk) then
if reset = '1' then
-- reset signal to their default level:
temp1(0) <= '0';
-- ...
else
-- here goes your main code:
temp1(0) <= a or b
-- ...
if (a = b and temp1(0) /= a) then
temp1(1) <= not temp1(0);
else
temp1(1) <= '0';
end if;
-- ...
end if;
end if;
end process;
end Behavioral;
...或使用纯逻辑,即将 if-else 替换为 when-else (what is the difference)
architecture Behavioral of serial_adder is
-- define signals...
begin
temp1(0) <= a or b;
-- ...
temp1(1) <= not temp1(0) when ((a = b) and (temp1(0) /= a))
else '0';
-- ...
end Behavioral;