VHDL if语句正在处理每个if语句的多个输出

时间:2015-04-02 02:34:20

标签: if-statement vhdl

我有一个奇怪的问题,在vhdl中听起来不言自明,但即使逻辑看起来没问题,代码也不会输出到示波器。我需要为下面的向量中的每个位驱动0和1,并且我需要使用滑块开关的组合来执行此操作。我正在使用Digilent Nexys 3。

我的问题是,当我运行此代码或每个if语句具有超过3个输出的任何代码时,如果给出正确的组合,则其中一个输出不会输出到逻辑“1”。

我在下面给出了我的代码,这看起来非常简单。有人能告诉我为什么每个if语句只能输出3个东西吗?我需要能够在if语句中输出20个或更多信号。

我已经尝试了所有我能想到的东西,从使用bit_vector到使用不同的语法。任何有关为什么我最多只能得到3个输出的帮助将不胜感激。

Library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all ;


entity pulse_gen_toVGA is port (
clk_50,sw0,sw1,sw2,sw3 : in std_logic ;
rst : in std_logic;
output : out std_logic_vector(3 downto 0));


end pulse_gen_toVGA;

architecture top of pulse_gen_toVGA is


begin



process(sw0,sw1,sw2,sw3)
begin

if (sw0='0' and sw1='0' and sw2='0' and sw3='0') then
null;
end if;

if(sw0='1') then
output<="0001";
elsif(sw1='1') then
output<="0010";
elsif(sw2='1') then
output<="0100";
elsif(sw3='1') then
output<="1000";
end if;


end process;

end top ;

这是我正在使用的输出的ucf文件。

net "clk_50" loc="v10";
net "output<0>" loc="t12";
net "output<1>" loc="n10";
net "output<2>" loc="p11";
net "output<3>" loc="h3";


net "sw0" loc="t10";
net "sw1" loc="t9";
net "sw2" loc="v9";
net "sw3" loc="m8";

2 个答案:

答案 0 :(得分:1)

嗯,你的代码并不完全是O.K ..让我们看看:

if (sw0='0' and sw1='0' and sw2='0' and sw3='0') then
    null;
end if;

这个if什么都不做,除了你的硬盘驱动器上浪费宝贵的字节,每次你合成或模拟时都会有几微秒的CPU时间。拥有这些或者没有任何改变,所以不妨删除它们。

if(sw0='1') then
    output<="0001";
elsif(sw1='1') then
    output<="0010";
elsif(sw2='1') then
    output<="0100";
elsif(sw3='1') then
    output<="1000";
end if;

如果没有任何开关为'1'会怎样?隐含地,如果信号未被分配,则信号不得更改其值,这需要存储器元素,因为当所有开关都为“0”时,output取决于最后一个处于活动状态的开关。

在这种情况下,合成器将推断锁存器。众所周知,锁存器表现不规律,实际上只能由专家使用。每当您忘记在组合过程的一个逻辑路径中分配信号时,它们就会出现。

修复您的代码有两种选择,您可以在if语句中添加else,例如将output设置为0,或者使用正确的内存元素,称为寄存器。在第一种情况下,您将拥有一个组合电路,仅包含没有锁存器/寄存器的逻辑门。在第二种情况下,您将具有与锁存电路相同的行为,但没有锁存器的不规则性。以下是如何实现寄存器:

process(clk_50)
begin
    if rising_edge(clk_50) then
        if(sw0='1') then
            output<="0001";
        elsif(sw1='1') then
            output<="0010";
        elsif(sw2='1') then
            output<="0100";
        elsif(sw3='1') then
            output<="1000";
        end if;
    end if;
end process;

我必须补充一点,寄存器路由并不完全正常,并鼓励您搜索亚稳态,异步输入和重新同步。基本上,使用异步信号(如开关)而不同步它可能会导致问题。

最后,它可能无法解决您的问题,但一旦您拥有“干净”的代码,我们就可以查看。

答案 1 :(得分:0)

在进行更改之前,您可以检查几件事。

Nexys3_Master.ucf中没有标记为output的输出。向我们展示如何(在哪里)output,你发现它不会发生。

我们无法使用您提供的内容复制您的问题,而不是Minimal, Complete, and Verifiable example

接下来,模拟您的设计。

这是一个简单的测试平台:

library ieee;
use ieee.std_logic_1164.all;

entity pgtv_tb is
end entity;

architecture foo of pgtv_tb is
    signal clk_50:  std_logic;
    signal sw0, sw1, sw2, sw3:  std_logic;
    signal rst:     std_logic;
    signal output:  std_logic_vector (3 downto 0);
begin
DUT:
    entity work.pulse_gen_toVGA
        port map (
            clk_50 => clk_50,
            sw0 => sw0,
            sw1 => sw1,
            sw2 => sw2,
            sw3 => sw3,
            rst => rst,
            output => output
        );

STIMULUS:
    process
    begin
        wait for 100 ms;
        sw0 <= '0';
        sw1 <= '0';
        sw2 <= '0';
        sw3 <= '0';
        wait for 100 ms;
        sw0 <= '1';
        wait for 100 ms;
        sw0 <= '0';
        wait for 100 ms;
        sw1 <= '1';
        wait for 100 ms;
        sw1 <= '0';
        wait for 100 ms;
        sw2 <= '1';
        wait for 100 ms;
        sw2 <= '0';
        wait for 100 ms;
        sw3 <= '1';
        wait for 100 ms;
        sw3 <= '0';
        wait for 100 ms;
        wait;       
    end process;
end architecture;

它产生:

pgtv_tb.png (点击)

现在我们看到的第一件事是推断的锁存器Jonathan Drolet关注第一个if语句中的null语句。

将所有开关输入更改为“0”不会影响output,这在模拟中会再发生四次。

但是你可以看到我们确实得到了四个输出,即

  

...当我运行此代码或每个if语句有超过3个输出的任何代码时,如果给出正确的组合,其中一个输出不会输出到逻辑'1'

在VHDL代码中不明显。这强烈暗示某个地方出现output会出现问题,而且在您的代码中并不明显。

(您的代码不会重现您要求帮助的问题,无论您是否想要那些锁存器。)