一个简单的VHDL电路不会显示初始值

时间:2014-05-22 03:00:28

标签: vhdl

这是我的代码,非常简单。我要在Altera Cyclone II板上循环显示字母表的前8个字母。

entity lettercycle is
    port(
        SW  : in  std_logic; -- toggle switch
        HEX0 : out std_logic_vector(6 downto 0) -- 7-segment display
        );
end lettercycle;

architecture behavioural of lettercycle is
    signal counter : integer range 0 to 7 := 0;
begin
    process
        type SEGMENT_ARRAY is array (0 to 7) of std_logic_vector(6 downto 0);
        variable SEVENSEG : SEGMENT_ARRAY := ("0001000","0000011","1000110","0100001","0000110","0001110","0010000","0001001");
        begin
        HEX0 <= SEVENSEG(counter);
        wait until SW = '0';
        counter <= counter + 1;
        end process;
end behavioural;

这很好用,它循环但最初它在我的七段显示器上不显示“A”。它显示“8”(所以基本上没有)。一旦我按下逻辑0开关SW,它就会变为'A'并正确循环到'B','C'等。它也正确循环。它没做的是最初设置为'A'。如果我强迫

    HEX0 <= SEVENSEG(0);

然后它会显示'A',所以我想出了主意。这可能与弹跳有关吗?

3 个答案:

答案 0 :(得分:1)

综合工具使用下降沿触发器实现该过程 wait until SW = '0';的结果,因此counterHEX0都在里面 该过程在SW的下降沿更新(因此HEX0不是锁存器。)

然而,综合工具不会传播counter的初始0值 基于HEX0的映射,SEVENSEG上的初始值,因此您不会获胜 看到最初的&#39; A&#39;在输出上。

合成输出如下图所示,其中触发器打开 输出也可以看出。

enter image description here

通过更新流程并HEX0分配给:

,可以实现预期的操作
process (SW) is
begin
  if falling_edge(SW) then
    counter <= counter + 1;
  end if;
end process;
HEX0    <= SEVENSEG(counter);

这也将删除HEX0输出中不必要的触发器。

请注意,SEVENSEG将移至架构级别声明为常量。

答案 1 :(得分:1)

Morten对HEX0的下降治疗是对的。

另一种方法是将SEVENSEG声明为架构声明区域中的常量,并将分配从计数器(这是一个信号)移动到进程外的HEX0:

library ieee;
use ieee.std_logic_1164.all;

entity lettercycle is
    port(
        SW  : in  std_logic; -- toggle switch
        HEX0 : out std_logic_vector(6 downto 0) -- 7-segment display
        );
end lettercycle;

architecture behavioural of lettercycle is
    signal counter : integer range 0 to 7 := 0;
    type SEGMENT_ARRAY is array (0 to 7) of std_logic_vector(6 downto 0);
    constant SEVENSEG : SEGMENT_ARRAY := 
              ("0001000","0000011","1000110","0100001",
               "0000110","0001110","0010000","0001001");
begin
    process
        -- type SEGMENT_ARRAY is array (0 to 7) of std_logic_vector(6 downto 0);
        -- variable SEVENSEG : SEGMENT_ARRAY := 
        --           ("0001000","0000011","1000110","0100001",
        --            "0000110","0001110","0010000","0001001");
        begin
        -- HEX0 <= SEVENSEG(counter);
        wait until SW = '0';
        if counter = 7 then
            counter <= 0;
        else
            counter <= counter + 1;
        end if;
    end process;

    HEX0 <= SEVENSEG(counter);

end behavioural;

library ieee;
use ieee.std_logic_1164.all;

entity lettercycle_tb is
end entity;

architecture foo of lettercycle_tb is
    signal SW:      std_logic := '1';
    signal HEX0:    std_logic_vector(6 downto 0);
begin
DUT:
    entity work.lettercycle
        port map (
            SW => SW,
            HEX0 => HEX0
        );
STIMULUS:
    process 
    begin
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        SW <= '0';
        wait for 60 ms;
        SW <= '1';
        wait for 60 ms;
        wait;
    end process;

end architecture;

关于if counter = 7 then...的位是因为整数&#34; +&#34;有它的数学意义,添加的输出可能超出范围,并给你一个讨厌的运行时消息:

  

ghdl -r lettercycle_tb --wave = lettercycle_tb.ghw
  ./lettercycle_tb:error:lettercycle.vhdl:29的绑定检查失败   ./lettercycle_tb:error:模拟失败ghdl:编译错误

这表示模拟可能会失败,并且应该鼓励对计数器和其他正在进行算术运算的值使用基于std_ulogic的数组值,这会有计数器翻转。 0到7的范围恰好适合3位,而在合成产品中,您期望反转。

现已撤销的IEEE Std 1076.6(寄存器传输级综合)中有验证方法的描述:

  

使用模拟验证综合结果的过程包括   将等效输入应用于原始模型和   合成模型然后比较它们的输出以确保它们   是等价的。在此上下文中的等价意味着综合工具   应产生一个在输入,输出和电路中等效的电路   模型的双向端口。由于合成一般不会   识别与模拟器相同的延迟,输出不能   在每个模拟时间进行比较。相反,它们只能进行比较   在所有瞬态延迟已经解决的特定模拟时间   并且已超出所有活动的超时子句。如果输出   在所有可比较的时间都不匹配,合成工具不应该   兼容。任何人都不得有任何匹配的要求   内部节点。

基本上,合成结果应该与VHDL模拟除了忽略元值事务之外的其他方式相匹配。所以你的综合结果尽可能多。

答案 2 :(得分:0)

这不是开关反弹问题(尽管您的设计很容易受到影响)。在你的设计中HEX0是一个闩锁。您从未将其设置为初始值,这就是为什么它在指定初始状态为&#34; 0000000&#34;的工具中启动的原因。请注意,这不是VHDL的固有属性,它可以用&#34; UUUUUUU&#34; (所有未初始化的)在模拟中,但在实际硬件中实现9值逻辑时,综合工具会有一些自由。

SEVENSEG不需要变量,因此您可以将其转换为体系结构级别常量,并将赋值转换为HEX0到流程外的连续赋值,作为一种简单的方法它按照需要启动。