【问题标题】:ModelSim - Unable To Simulate Button PressesModelSim - 无法模拟按钮按下
【发布时间】:2013-01-27 05:07:38
【问题描述】:

我想使用四个按钮作为输入,三个七段 LED 显示器作为输出。两个按钮应通过 16 个 RAM 位置上下移动;另外两个应该增加和减少当前显示的内存位置的内容。我有以下两个实体:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity DE2_TOP is

  port (
    KEY : in std_logic_vector(3 downto 0);         -- Push button
    CLOCK_50: in std_logic;
    );

end DE2_TOP;

architecture datapath of DE2_TOP is

begin  
  U1: entity work.lab1 port map (
    key => key,
    clock => clock_50,        
  );

end datapath;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity raminfr is                     -STANDARD RAM INFERENCE
    port (
        clock: in std_logic;
        we : in std_logic;
        a : in unsigned(3 downto 0);
        di : in unsigned(7 downto 0);
        do : out unsigned(7 downto 0)
    );
end raminfr;

architecture rtl of raminfr is

type ram_type is array (0 to 15) of unsigned(7 downto 0);
signal RAM : ram_type;
signal read_a : unsigned(3 downto 0);
begin
process (clock)
begin
    if rising_edge(clock) then
        if we = '1' then
            RAM(to_integer(a)) <= di;
        end if;
        read_a <= a;
    end if;
end process;
do <= RAM(to_integer(read_a));
end rtl;

和

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity lab1 is
    port(
        clock : in std_logic;
        key : in std_logic_vector(3 downto 0); 
        );
end lab1;

architecture up_and_down of lab1 is
    signal value_in_ram : unsigned(7 downto 0);
    signal we : std_logic;
    signal value_counter    : unsigned(7 downto 0) ;
    signal register_counter : unsigned(3 downto 0);
        begin
    U1: entity work.raminfr port map (
        a   => register_counter,
        di  => value_counter,
        do  => value_in_ram,
        clock => clock,
        we  => we
    );

    process(clock)
        begin
            if rising_edge(clock) then
                if (key(3)='0' and key(2)='0' and key(1)='1' and key(0)='0') then
                    value_counter <= value_counter + "1";   
                elsif (key(3)='0' and key(2)='0' and key(1)='0' and key(0)='1') then  
                    value_counter <= value_counter - "1";   
                elsif (key(3)='1' and key(2)='0' and key(1)='0' and key(0)='0') then
                    register_counter<= register_counter + "1";
                    value_counter <= value_in_ram;
                elsif (key(3)='0' and key(2)='1' and key(1)='0' and key(0)='0') then
                    register_counter<= register_counter - "1";
                    value_counter <= value_in_ram;
                end if;
            end if;
    end process;
end architecture up_and_down;

我还有以下测试台,我尝试在其中模拟通过 KEY 按下的按钮:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity DE2_TOP_TEST is
end;

architecture BENCH of DE2_TOP_TEST is

    signal KEY :  std_logic_vector(3 downto 0);
    signal CLOCK_50 :  std_logic := '0';
    signal hex4, hex5, hex6 :  std_logic_vector(6 downto 0);           
begin
    clock_50 <= not clock_50 after 50 ns;
    process
        begin
            KEY<="0010";
                    wait for 1 us;
        KEY<="0000";
    end process;

uut:work.DE2_TOP port map (                                                         
    KEY=>key,
    CLOCK_50=>clock_50, 
    hex4=>hex4,
hex5=>hex5,
hex6=>hex6                                 
);
end BENCH;

我的测试台设置如下:

为了模拟,我编译了上面所有的三个文件,然后模拟了DE2_TOP_TEST,但是结果我的“KEY”仍然是未定义的,如下(虽然CLOCK_50确实得到了我设置的默认值):

有人知道这是什么原因吗?

【问题讨论】:

  • 两件小事:在分配给'key'的过程中应该有一个'wait'。第二:这个时钟是从哪里来的('clk'和'clock'。(对不起,没有时间做更多)
  • 所以,你有'UUUU'键。但那是什么时候呢?无论如何,你所有的信号都是'U'。会不会是你还没有开始模拟?在 Modelsim 的 TCL 窗口中尝试“run -all”。一段时间后打破它。
  • 另一个注意事项:您的 VHDL 文件称为“.vho”。好吧,这没什么错,尽管 '.vhdl' 或 '*.vhd' 会更自然。但难道不是你在综合或实现后模拟网表吗?在这些阶段,您可以在 VHDL 网表中写出网表,以模拟设计是否仍在工作。
  • 你能分享错误信息吗?您必须编译所有 vhdl 文件(设计和测试平台),并且必须模拟您的测试平台。模拟器将通过连接所有子模块(=细化)来构建设计。
  • "uut: ENTITY work.DE2_TOP"....

标签: vhdl fpga modelsim


【解决方案1】:

(1) 您在键入要测试的实体上有未连接的端口。这些输入的测试结果与预期一致 - 特别是 clk,未驱动。

(2) 连接clk后,你需要驱动它。

signal clk : std_logic := '0';

和

clk <= not clk after 50 ns;

应该给一个 10MHz 的时钟,在模拟器中检查一下

(3) 使用特定的值序列驱动“KEY”

subtype keys is std_logic_vector(3 downto 0);
constant count_up : keys := "0001";
constant count_dn : keys := "0010";
constant idle     : keys := "0000"; 
-- etc

    process
    begin
        KEY <= count_up;
        wait for 1 us;
        KEY <= idle;
        wait for ...
-- etc
    end process;

(4) 将 OUTPUTS 带回测试台,以便您检查它们的值。如果要将它们连接到显示器,无论如何都需要将它们作为顶级(设计)实体中的端口带出来!

然后(稍后,一旦事情开始按计划进行)您可以在测试平台过程中对其进行测试...

    wait for 100 ns;
    -- after the last press, we should have "07" on the display
    assert digit(1) = "0111111" report "Left digit has wrong value" severity ERROR;
    assert digit(0) = "0000111" report "Left digit has wrong value" severity ERROR;

像这样的自检测试平台可以通过查看波形来节省调试时间。只有在测试失败时才需要波形...

【讨论】:

  • 您能否对第 1 点更具体一点?断开连接的确切位置在哪里?
  • 我已经修改了我的代码来做你认为应该做的事情,但结果是一样的。
  • 您将“时钟”输入lab1 并在进程中使用它,但不是内存。那使用“clk”代替,据我所知,它仍然是未驱动的。但是现在您拥有自己取得进步的工具 - 我相信您可以看到“时钟”切换和“clk”未驱动。
  • 嘿伙计,我已经按照您的要求连接了 lab1 和 RAM 时钟(参见上面的编辑)。另外,我不知道您是否与其他海报一起阅读了上述 cmets,但是当我将它们初始化为信号时,我可以通过默认设置 KEY 和 CLOCK_50 在我的测试台上设置它们 - 但是,我仍然没有能够使用逻辑设置KEY。另外,我不认为以这种方式设置它有效 - 如果您查看我上面的编辑,我将十六进制值移植回我的测试台以检查它们,但它们在输出中都是未定义的。
  • 模拟器中应该有一个控制台窗口。你能把它输出的最后几行贴出来吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 2016-03-26
  • 2014-01-19
相关资源
最近更新 更多