0

以下是使用 D 触发器的计数器的 VHDL 代码。在这里,我们假设触发器是上升沿触发的。

在架构内部,我将 Q(当前状态)和 D 声明为 4 位逻辑向量。

我分配了所有输出(Z0 到 Z7)和 D 信号值,以匹配分别由计数器和触发器的最小输入方程确定的逻辑表达式。

在代码结束时,调用一个进程来模拟清除 (ClrN) 和时钟 (CLK) 的行为

我的问题:

代码可以正常工作,但我遇到了模拟测试台的问题。

在模拟中,我们需要显示电路从状态 1000 开始,然后以正确的顺序通过每个状态。

简而言之:我如何在模拟中显示信号 Q 和 D。
这是我不知道该怎么做的部分。

我被告知使用强制命令来设置所需的输入。

例如:

force ClrN 0 0, 1 20  
force CLK 1000 0  
force CLK 0 0, 1 40 -repeat 80  

但我不确定在哪里以及如何使用它。

下面是 VHDL 代码:

library IEEE;  
use IEEE.STD_LOGIC_1164.ALL;

entity counter is
port (CLK, ClrN : in std_logic;  
        Z0 : out std_logic;  
        Z1 : out std_logic;  
        Z2 : out std_logic;  
        Z3 : out std_logic;  
        Z4 : out std_logic;  
        Z5 : out std_logic;  
        Z6 : out std_logic;  
        Z7 : out std_logic);  
end counter;

architecture Behavioral of counter is

signal Q: std_logic_vector(0 to 3);
signal D: std_logic_vector(0 to 3);

begin

u1: process(Q)

begin

Z0 <= Q(0) and not Q(1) and not Q(3);
Z1 <= Q(0) and Q(1);
Z2 <= not Q(0) and Q(1) and not Q(2);
Z3 <= Q(1) and Q(2);
Z4 <= not Q(1) and Q(2) and not Q(3);
Z5 <= Q(2) and Q(3);
Z6 <= not Q(0) and not Q(2) and Q(3);
Z7 <= Q(0) and Q(3);

D(0) <= not Q(1) and not Q(2);
D(1) <= not Q(2) and not Q(3);
D(2) <= not Q(0) and not Q(3);
D(3) <= not Q(0) and not Q(1);
end process u1;


u2: process(CLK,ClrN)  
begin  
if ClrN = '0' then  
Q <= "1000";  
elsif Rising_Edge (CLK) then  
Q <= D;  
end if;  
end process u2;  

end Behavioral; 

以下是我的 VHDL 测试平台:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY tb IS
END tb;

ARCHITECTURE behavior OF tb IS 

    COMPONENT counter
    PORT(
         CLK : IN  std_logic;
         ClrN : IN  std_logic;
         Z0 : OUT  std_logic;
         Z1 : OUT  std_logic;
         Z2 : OUT  std_logic;
         Z3 : OUT  std_logic;
         Z4 : OUT  std_logic;
         Z5 : OUT  std_logic;
         Z6 : OUT  std_logic;
         Z7 : OUT  std_logic
        );
    END COMPONENT;


   --Inputs
   signal CLK : std_logic := '0';
   signal ClrN : std_logic := '0';

    --Outputs
   signal Z0 : std_logic;
   signal Z1 : std_logic;
   signal Z2 : std_logic;
   signal Z3 : std_logic;
   signal Z4 : std_logic;
   signal Z5 : std_logic;
   signal Z6 : std_logic;
   signal Z7 : std_logic;

   -- Clock period definitions
   constant CLK_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: counter PORT MAP (
          CLK => CLK,
          ClrN => ClrN,
          Z0 => Z0,
          Z1 => Z1,
          Z2 => Z2,
          Z3 => Z3,
          Z4 => Z4,
          Z5 => Z5,
          Z6 => Z6,
          Z7 => Z7
        );

   -- Clock process definitions
   CLK_process :process
   begin
        CLK <= '0';
        wait for CLK_period/2;
        CLK <= '1';
        wait for CLK_period/2;
   end process;

   -- Stimulus process
   stim_proc: process
   begin        
--      -- hold reset state for 10 ns.

      wait for 10 ns;   

        ClrN <= '1'; 

     wait;
   end process;

END;

我在哪里以及如何将 Q 和 D 信号添加到我的测试台,以便获得显示电路以状态 1000 开始的模拟,然后它以正确的顺序通过每个状态。我什至使用强制命令吗?

4

1 回答 1

0

记录模拟中发生的情况(除了波形)的一种方法是将所需信号写入输出(如 c 中的 printf)或文件(如 fprintf)。

为此,首先包含 textio 包:

use std.textio.all;
use ieee.std_logic_textio.all;

然后修改你的过程:

u2: process(CLK,ClrN)  
  file f0 : text is out "output.txt";
begin  
  if ClrN = '0' then  
    Q <= "1000";  
  elsif Rising_Edge (CLK) then  
    --pragma translate_off
    write(output, "Q:" & to_string(Q) & " D:" & to_string(D) & lf);
    write(f0, "Q:" & to_string(Q) & " D:" & to_string(D) & lf);
    --pragma translate_on
    Q <= D;  
  end if;  
end process u2;  

编译指示不是绝对必要的,但它们是一个好习惯,可以添加到模块内用于综合的任何不可综合的代码中。

在您的示例中,不应使用武力。

于 2017-04-04T06:12:33.363 回答