如果elsif vhdl行为

时间:2012-06-13 16:40:16

标签: vhdl xilinx

我正在使用webPack ISE v 13使用以下代码对Nexys 3板进行编程,并通过在if elsif语句中交换语句来注意完全不同的行为。本质上,我在电路板上使用了三个按钮:当按下第一个按钮btn(0)时,8个开关的状态存储在寄存器中。当我按下btn(1)时,开关的状态应显示在8个LED中,LED应该保持这种状态。当我按下btn(2)时,我强制所有LED点亮,如果没有按下btn 1或2,它们应该保持这种状态。通过交换if和elsif下的按钮1和按钮1的操作。 2,行为改变:只有当我按下相应的按钮时才会显示开关的状态,一旦我放开,所有的LED都会亮起。

除了寻找“这就是你需要使它工作的东西”之外,我还在解释为什么vhdl的行为与C ++有如此不同的说法(在这种情况下订单无关紧要)

以下是代码摘录;我指出哪些行要评论/取消注释以获得行为'a'或行为'b'。

行为'a':

  • 当按下btn(0)时,8个开关的状态正确加载到data_reg
  • 当我按下btn(1)时,LED全部亮起(“111 ... 11”)
  • 如果按btn(2),则LED显示data_reg内容
  • 如果没有按下任何按钮,则按下最后一个按钮
  • 指示LED的状态

行为'b':

  • 当按下btn(0)时,8个开关的状态正确加载到data_reg
  • 当我按btn(1)时,LED显示data_reg内容
  • 如果按btn(2),LED全部亮起(“111 ... 11”)
  • 如果没有按下任何按钮,则所有LED均亮起。查看data_reg内容的唯一方法是按住btn(1)。

`

  

处理(CLK)

     
    

开始

         
if (clk'event and clk='1') then
             
   if (db_btn(0)='1') then          --load sw state into data_reg
      data_reg <= sw;
   end if;
                 

结束如果;          结束过程;

      
    
  
   process(btn,data_reg)
   begin
     if btn(1)='1' then 
        data_s2f <= "1111111111111111";   --behvr a; comment this line for behvr b
        -- data_s2f <= "00000000" & data_reg; -- uncomment for behvr b; comment for behvr a
     elsif btn(2)='1' then -- read     
       data_s2f <= "00000000" & data_reg; --behvr a; comment this line for behvr b
       --data_s2f <= "1111111111111111";  -- uncomment for behvr b; comment for behvr a
      end if;
   end process;
   -- output
   led <= data_s2f(7 downto 0);  --display data_s2f in LEDs

模拟测试台

这是我的模拟测试平台。每当我执行所有信号的结果是UUU..UU任何评论将不胜感激:

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 ifstmt_tb IS
END ifstmt_tb;

ARCHITECTURE behavior OF ifstmt_tb IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT ram_ctrl_test
    PORT(
         clk : IN  std_logic;
         reset : IN  std_logic;
        sw : IN  std_logic_vector(7 downto 0);
        btn : IN  std_logic_vector(2 downto 0);
        led : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;


   --Inputs
  signal clk : std_logic := '0';
  signal reset : std_logic := '0';
  signal sw : std_logic_vector(7 downto 0) := (others => '0');
  signal btn : std_logic_vector(2 downto 0) := (others => '0');

    --Outputs
   signal led : std_logic_vector(7 downto 0);

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

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: ram_ctrl_test PORT MAP (
          clk => clk,
          reset => reset,
          sw => sw,
          btn => btn,
          led => led
        );

   -- 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 100 ns.
        reset <= '1';
        sw <= "11001100";
        btn<= (others => '0');
      wait for 100 ns;  
        reset <= '0';
      wait for clk_period*10;
        -- load register
        btn<= (0=>'1', others => '0');
       wait for clk_period*2;   
        btn<= (others => '0');  
       wait for clk_period*10;  
        -- display with btn 1
        btn<= (1=>'1', others => '0');
       wait for clk_period*5;   
        btn<= (others => '0');  
       wait for clk_period*10;  
        -- display with btn 2
        btn<= (2=>'1', others => '0');
       wait for clk_period*5;   
        btn<= (others => '0');  
       wait for clk_period*10;  
        -- change pattern
        sw <= "11100111";
        wait for clk_period;
        -- load register
        btn<= (0=>'1', others => '0');
       wait for clk_period*2;   
        btn<= (others => '0');  
       wait for clk_period*10;  
        -- display with btn 2
        btn<= (2=>'1', others => '0');
       wait for clk_period*5;   
        btn<= (others => '0');  
       wait for clk_period*10;  
        -- display with btn 1
        btn<= (1=>'1', others => '0');
       wait for clk_period*5;   
        btn<= (others => '0');  

      -- insert stimulus here         

      wait;
   end process;  

END;

3 个答案:

答案 0 :(得分:2)

如果使用级联顺序执行语句,VHDL将执行驱动各种条件语句的输出。所有条件都是完全计算的(让我们忽略此点的传播延迟)。硬件“选择”满足您条件的第一个语句(如果elsif分支驱动下级语句的启用,则后续输出,因此如果一个计算结果为false,则启用下一个语句)。

我认为你看到的行为确实显得“奇怪”,但实际上你的期望是什么。如果您未提供默认值,则会根据硬件获得意外结果。你需要以黑白编程。现在你正在编程灰色。 VHDL对程序员意图的宽容程度要低得多。你必须始终是明确的和明确的。

一个可能的答案是,这不是编写此if语句的最佳方法。一种更好的方法是创建一个“滴答”信号,指示“确定”按钮按下,该信号驱动记录按下选项的单独的顺序锁存过程。我想你看到的行为是硬件依赖的,因此难以解释。

这里没有提到的另一点是你应该实现一个开关去抖动器。有效地,当按下并以您不期望的方式操作时,开关可能会切换很多(将其连接到示波器并将其置于边缘模式,您将看到)。您应该在按下开关时计算一段时间(例如1ms),并且仅在该时间段后打开。关闭也一样。这可能会更好地缓冲您可能拥有的任何弹性。这就是你如何让你的“确定”按钮压下“滴答”

答案 1 :(得分:1)

听起来btn(2)的硬件投入的时间比你期望的要高1,或者更频繁地获得高信号。查看映射到其他硬件按钮是否有帮助。确保btn(2)设置为上拉模式而不是下拉。

至于代码部分,请注意结构是嵌套的if,因此当BOTH btn(1)和btn(2)为高时,您将看到行为上的差异。

答案 2 :(得分:0)

除了使用模拟器检查行为......

  • 您确定您的开关映射到了正确的引脚吗? FPGA?
  • 交换机是否接线,按下它们会产生1 - 有时它们会浮动到1并在按下时生成0