您好我是Xilinx的新用户,并且在如何在测试平台上编写激励/模拟方面遇到了麻烦。我的输出(Kd)没有给我任何明智的值,并且在移动前保持'1'前的几个时钟周期并保持在'1'。
不确定我是否写过正确的刺激物,但希望有人能在这里帮助我!
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;
答案 0 :(得分:2)
这可以在不模拟的情况下回答。 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就会保持高位。
Qa在第一次出现高位后的一个时钟点亮。
这种情况的发生方式是在R0,R1,R2或R3中的任何一个连续'1'输入。
您的时钟周期为100 ns,您的刺激间隔也是如此。
在第一个时钟之后没有任何刺激,其中所有R0,R1,R2和R3同时都是低电平以进行演示。
不幸的是,Xilinx帖子(iSIM output Unintialised, doesn't change states.)上的波形图像没有显示QA和Qb,看到它们都变高并留在那里:
当你添加它们时,这一点就会出现:
答案 1 :(得分:0)
您构建的是顺序逻辑,这意味着输出取决于输入/输出的先前的高级。在你的情况下,我们有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
....
一旦R升高,Qa就会很高。根据输入组合的顺序,Qa不会再次变低。 这意味着在第二个输入组合之后,Qb得到一个已知值并且Kb变高。
敏感度列表
这不是答案的一部分,但它是对您编写的代码的考虑因素:您已经设置了敏感度列表R0,R1,R2,R3但是,鉴于您之后所写的内容,这不是必需的。
该过程仅在
时执行if clock'event and clock = 1 then
这意味着忽略R上的任何事件。我确信合成器实际上意识到并忽略了它,但是设置一个合适的灵敏度列表是一个好习惯,并且在可能的情况下,只对顺序逻辑和有限状态机使用时钟进程。 / p>
我还建议您使用更易读的rising_edge(时钟)和falling_edge(时钟)函数:
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&lt; ='1'。
覆盖计划值可用于简化逻辑:我通常做的是设置一些默认值,然后仅在需要时覆盖它们。
所以,而不是写
...
case A is
when "00" =>
B <= '0';
when "01" =>
B <= '0';
when "10" =>
B <= '0';
when "11" =>
B <= '1';
end case;
...
我写这个(如果我需要其他信号,我可能会保留案例结构,通常在有限状态机中):
...
B <= '0';
if A = "11" then
B <= '1';
end if;
...
对于这个简单的例子,合成器可能能够推断出简化。但是,您应该习惯于在逻辑级别端口进行思考,因为从行为的角度来看,以两种等效的方式编写的内容实际上是以不同的方式实现的。