VHDL - iSIM 输出未初始化,不改变状态
VHDL - iSIM output uninitialised, doesn't change states
您好,我是 Xilinx 的新用户,在如何在测试平台中编写 stimulus/simulate 时遇到了问题。我的输出 (Kd) 没有给我任何合理的值,并且在移动之前的前几个时钟周期给出 'u' 并始终保持在“1”。
不确定我是否写了正确的刺激,但希望有人能帮助我!
我的VHDL代码
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity codeFig2b is
Port ( R0 : in STD_LOGIC;
R1 : in STD_LOGIC;
R2 : in STD_LOGIC;
R3 : in STD_LOGIC;
Kd : out STD_LOGIC;
clock : in STD_LOGIC);
end codeFig2b;
architecture Behavioral of codeFig2b is
signal Qa, Qb: STD_LOGIC;
begin
process(clock, R0, R1, R2, R3)
begin
if clock = '1' and clock'event then
Qa <= (R0 or R1 or R2 or R3) or (Qa and Qb);
Qb <= Qa;
end if;
end process;
Kd <= Qa and Qb;
end Behavioral;
我的测试平台##
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY codeFig2b_test IS
END codeFig2b_test;
ARCHITECTURE behavior OF codeFig2b_test IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT codeFig2b
PORT(
R0 : IN std_logic;
R1 : IN std_logic;
R2 : IN std_logic;
R3 : IN std_logic;
Kd : OUT std_logic;
clock : IN std_logic
);
END COMPONENT;
--Inputs
signal R0 : std_logic := '0';
signal R1 : std_logic := '0';
signal R2 : std_logic := '0';
signal R3 : std_logic := '0';
signal clock : std_logic := '0';
--Outputs
signal Kd : std_logic;
-- Clock period definitions
constant clock_period : time := 100 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: codeFig2b PORT MAP (
R0 => R0,
R1 => R1,
R2 => R2,
R3 => R3,
Kd => Kd,
clock => clock
);
-- Clock process definitions
clock_process :process
begin
clock <= '0';
wait for clock_period/2;
clock <= '1';
wait for clock_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '1';
R3 <= '1';
wait for clock_period*10;
-- insert stimulus here
wait;
end process;
END;
这个不用模拟也能回答。 Kd 的输出将变为“1”并保持在那里。
process(clock, R0, R1, R2, R3)
begin
if clock = '1' and clock'event then
Qa <= (R0 or R1 or R2 or R3) or (Qa and Qb);
Qb <= Qa;
end if;
end process;
Kd <= Qa and Qb;
对于 R0、R1、R2 或 R2 或(Qa 和 Qb)中的任何一个,Qa 变高;
所以一旦 Qa 和 Qb 变高,Qa 就会保持高位。
Qb 在第一次出现 Qa 变高后一个时钟变高。
发生这种情况的方式是在 R0、R1、R2 或 R3 中的任何一个上连续输入“1”。
你的时钟周期是 100 ns,你的刺激间隔也是。
在第一个时钟之后没有刺激,其中所有 R0、R1、R2 和 R3 同时都处于低电平以示证明。
不幸的是,您的 Xilinx post (iSIM output Unintialised, doesn't change states.) 上的波形图像没有显示 QA 和 Qb,无法看到它们都变高并保持在那里:
(可点击)
当你添加它们时,这一点就会出现:
可点击)
您构建的是 顺序 逻辑,这意味着输出取决于 inputs/outputs 的 previous hystory。在您的情况下,我们有 Qa 和 Qb,这是 Qa 的最后一个值。
请记住这一点,您在测试台中使用的方法并不是最佳的,因为您正在尝试输入的每个组合,而没有考虑最后一个 Qa 实际上很重要。
事情是这样的:
Start : Qa = U Qb = U => Kb = U
Inputs 1: Qa = 1 Qb = U => Kb = U
Inputs 2: Qa = 1 Qb = 1 => Kb = 1
Inputs 3: Qa = 1 Qb = 1 => Kb = 1
Inputs 4: Qa = 1 Qb = 1 => Kb = 1
....
其中一个Rs变高,Qa就变高。给定输入组合的顺序,Qa 不会再次变低。
这意味着在第二个输入组合之后,Qb 得到一个已知值并且 Kb 变高。
敏感度列表
这不是答案的一部分,但它是对您编写的代码的考虑:您已将敏感度列表 R0、R1、R2、R3 放入,但考虑到您之后编写的内容,这不是必要的。
进程只在
时才做某事
if clock'event and clock = 1 then
这意味着 Rs 上的任何事件都将被忽略。我确信合成器实际上意识到了这一点并忽略了它,但设置适当的敏感度列表是一个很好的做法,并且在可能的情况下,只使用 clocked 顺序逻辑和有限状态的进程机器。
我还建议您使用更具可读性的 rising_edge(clock) 和 falling_edge(clock) 函数:
process(clock)
begin
if rising_edge(clock) then
Qa <= R0 or R1 or R2 or R3 or (Qa and Qb);
Qb <= Qa;
end if;
end process;
信号和过程
您应该知道的另一件事是流程的工作原理:您不是为信号分配新值,而是为它们分配 规划 值。如果您对某个信号进行重新编程,您只是在覆盖之前的计划,并且永远不会分配第一个值。在过程结束时 最终分配值 。
这是一个简单的例子:
-- Let's assume A = 0 and B = 0 at startup
clocked_process : process(clk)
begin
if rising_edge(clk) then
A <= '1';
B <= A;
A <= '0';
end if;
end process;
最后B还是0,这是因为整个过程A=0,只得到一个计划值为1,实际上没有赋值,因为之前被覆盖了过程结束(在这种特定情况下,合成器将忽略 A <= '1' 的实现)。
覆盖计划值可以用来简化逻辑:我通常做的是设置一些默认值,然后只在需要时覆盖它们。
所以,而不是写作
...
case A is
when "00" =>
B <= '0';
when "01" =>
B <= '0';
when "10" =>
B <= '0';
when "11" =>
B <= '1';
end case;
...
我写了这个(如果我需要它用于其他信号,我可能会保留 case 结构,通常在有限状态机中):
...
B <= '0';
if A = "11" then
B <= '1';
end if;
...
对于这个简单的例子,合成器可能能够推断出简化。但是,您应该习惯于在逻辑级端口中思考,因为从行为的角度来看,以两种等效方式编写的同一事物实际上是不同的。
您好,我是 Xilinx 的新用户,在如何在测试平台中编写 stimulus/simulate 时遇到了问题。我的输出 (Kd) 没有给我任何合理的值,并且在移动之前的前几个时钟周期给出 'u' 并始终保持在“1”。
不确定我是否写了正确的刺激,但希望有人能帮助我!
我的VHDL代码
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity codeFig2b is
Port ( R0 : in STD_LOGIC;
R1 : in STD_LOGIC;
R2 : in STD_LOGIC;
R3 : in STD_LOGIC;
Kd : out STD_LOGIC;
clock : in STD_LOGIC);
end codeFig2b;
architecture Behavioral of codeFig2b is
signal Qa, Qb: STD_LOGIC;
begin
process(clock, R0, R1, R2, R3)
begin
if clock = '1' and clock'event then
Qa <= (R0 or R1 or R2 or R3) or (Qa and Qb);
Qb <= Qa;
end if;
end process;
Kd <= Qa and Qb;
end Behavioral;
我的测试平台##
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY codeFig2b_test IS
END codeFig2b_test;
ARCHITECTURE behavior OF codeFig2b_test IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT codeFig2b
PORT(
R0 : IN std_logic;
R1 : IN std_logic;
R2 : IN std_logic;
R3 : IN std_logic;
Kd : OUT std_logic;
clock : IN std_logic
);
END COMPONENT;
--Inputs
signal R0 : std_logic := '0';
signal R1 : std_logic := '0';
signal R2 : std_logic := '0';
signal R3 : std_logic := '0';
signal clock : std_logic := '0';
--Outputs
signal Kd : std_logic;
-- Clock period definitions
constant clock_period : time := 100 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: codeFig2b PORT MAP (
R0 => R0,
R1 => R1,
R2 => R2,
R3 => R3,
Kd => Kd,
clock => clock
);
-- Clock process definitions
clock_process :process
begin
clock <= '0';
wait for clock_period/2;
clock <= '1';
wait for clock_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '1';
R3 <= '1';
wait for clock_period*10;
-- insert stimulus here
wait;
end process;
END;
这个不用模拟也能回答。 Kd 的输出将变为“1”并保持在那里。
process(clock, R0, R1, R2, R3)
begin
if clock = '1' and clock'event then
Qa <= (R0 or R1 or R2 or R3) or (Qa and Qb);
Qb <= Qa;
end if;
end process;
Kd <= Qa and Qb;
对于 R0、R1、R2 或 R2 或(Qa 和 Qb)中的任何一个,Qa 变高;
所以一旦 Qa 和 Qb 变高,Qa 就会保持高位。
Qb 在第一次出现 Qa 变高后一个时钟变高。
发生这种情况的方式是在 R0、R1、R2 或 R3 中的任何一个上连续输入“1”。
你的时钟周期是 100 ns,你的刺激间隔也是。
在第一个时钟之后没有刺激,其中所有 R0、R1、R2 和 R3 同时都处于低电平以示证明。
不幸的是,您的 Xilinx post (iSIM output Unintialised, doesn't change states.) 上的波形图像没有显示 QA 和 Qb,无法看到它们都变高并保持在那里:
当你添加它们时,这一点就会出现:
您构建的是 顺序 逻辑,这意味着输出取决于 inputs/outputs 的 previous hystory。在您的情况下,我们有 Qa 和 Qb,这是 Qa 的最后一个值。
请记住这一点,您在测试台中使用的方法并不是最佳的,因为您正在尝试输入的每个组合,而没有考虑最后一个 Qa 实际上很重要。
事情是这样的:
Start : Qa = U Qb = U => Kb = U
Inputs 1: Qa = 1 Qb = U => Kb = U
Inputs 2: Qa = 1 Qb = 1 => Kb = 1
Inputs 3: Qa = 1 Qb = 1 => Kb = 1
Inputs 4: Qa = 1 Qb = 1 => Kb = 1
....
其中一个Rs变高,Qa就变高。给定输入组合的顺序,Qa 不会再次变低。 这意味着在第二个输入组合之后,Qb 得到一个已知值并且 Kb 变高。
敏感度列表
这不是答案的一部分,但它是对您编写的代码的考虑:您已将敏感度列表 R0、R1、R2、R3 放入,但考虑到您之后编写的内容,这不是必要的。
进程只在
时才做某事if clock'event and clock = 1 then
这意味着 Rs 上的任何事件都将被忽略。我确信合成器实际上意识到了这一点并忽略了它,但设置适当的敏感度列表是一个很好的做法,并且在可能的情况下,只使用 clocked 顺序逻辑和有限状态的进程机器。
我还建议您使用更具可读性的 rising_edge(clock) 和 falling_edge(clock) 函数:
process(clock)
begin
if rising_edge(clock) then
Qa <= R0 or R1 or R2 or R3 or (Qa and Qb);
Qb <= Qa;
end if;
end process;
信号和过程
您应该知道的另一件事是流程的工作原理:您不是为信号分配新值,而是为它们分配 规划 值。如果您对某个信号进行重新编程,您只是在覆盖之前的计划,并且永远不会分配第一个值。在过程结束时 最终分配值 。
这是一个简单的例子:
-- Let's assume A = 0 and B = 0 at startup
clocked_process : process(clk)
begin
if rising_edge(clk) then
A <= '1';
B <= A;
A <= '0';
end if;
end process;
最后B还是0,这是因为整个过程A=0,只得到一个计划值为1,实际上没有赋值,因为之前被覆盖了过程结束(在这种特定情况下,合成器将忽略 A <= '1' 的实现)。
覆盖计划值可以用来简化逻辑:我通常做的是设置一些默认值,然后只在需要时覆盖它们。
所以,而不是写作
...
case A is
when "00" =>
B <= '0';
when "01" =>
B <= '0';
when "10" =>
B <= '0';
when "11" =>
B <= '1';
end case;
...
我写了这个(如果我需要它用于其他信号,我可能会保留 case 结构,通常在有限状态机中):
...
B <= '0';
if A = "11" then
B <= '1';
end if;
...
对于这个简单的例子,合成器可能能够推断出简化。但是,您应该习惯于在逻辑级端口中思考,因为从行为的角度来看,以两种等效方式编写的同一事物实际上是不同的。