【问题标题】:VHDL if statements in process driving multiple outputs per if statement进程中的 VHDL if 语句驱动每个 if 语句的多个输出
【发布时间】:2015-04-02 02:34:20
【问题描述】:

我有一个奇怪的问题,在 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";

【问题讨论】:

    标签: if-statement vhdl


    【解决方案1】:

    好吧,您的代码并不完全正常。让我们看看:

    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,要么使用 proper em> 称为寄存器的内存元素。在第一种情况下,您将拥有一个组合电路,仅包含没有锁存器/寄存器的逻辑门。在第二种情况下,您将具有与锁存器电路相同的行为,但没有锁存器的异常情况。下面是实现寄存器的方法:

    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;
    

    我要补充一点,寄存器路由不是完全没问题,鼓励大家搜索亚稳态、异步输入和再同步。基本上,使用异步信号(如您的开关)而不同步它可能会导致问题。

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

    【讨论】:

    • 嗨乔纳森。我尝试使用寄存器方法,并将 else 语句设置为逻辑 0,并且也只使用并发语句,但似乎都不起作用。关于什么不允许我在每个 if 语句中输出三个以上的东西的任何想法?我需要让每个 if 语句发送至少 20 个信号。
    • 正如@david-koontz 指出的那样,逻辑很好。你确定你的 UCF 是正确的吗?尝试一些更简单的方法,例如output &lt;= sw0 &amp; sw1 &amp; sw2 &amp; sw3;,以确保您的输入和输出连接正确。
    • 很抱歉。正在使用四通道示波器,示波器上的一个端口坏了。代码运行良好!
    【解决方案2】:

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

    在 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;
    

    它会产生:

    (可点击)

    现在我们首先看到的是 Jonathan Drolet 从第一个 if 语句中的 null 语句中推断出的闩锁。

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

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

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

    在 VHDL 代码中不明显。这强烈表明让 output 出现的地方有问题,并且在您的代码中并不明显。

    (无论您是否需要这些闩锁,您的代码都不会重现您寻求帮助的问题)。

    【讨论】:

    • 嗨,大卫。上面我发布了上面 ucf 文件的代码。我正在输出到 Digilent nexys 3 fpga 上的 pmod 端口。
    • 根据 Master UCF,我不禁注意到 net "output&lt;3&gt;" loc="h3"; 位于 C 连接器上,而其他 3 个位于 A 连接器上。你确定你找对地方了吗?
    • 很抱歉。正在使用四通道示波器,示波器上的一个端口坏了。代码运行良好!
    • 有一个很好的论据来模拟设计,尤其是在出现问题时。
    猜你喜欢
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多