我有一个奇怪的问题,在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";
答案 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;
它产生:
现在我们看到的第一件事是推断的锁存器Jonathan Drolet关注第一个if语句中的null语句。
将所有开关输入更改为“0”不会影响output
,这在模拟中会再发生四次。
但是你可以看到我们确实得到了四个输出,即
...当我运行此代码或每个if语句有超过3个输出的任何代码时,如果给出正确的组合,其中一个输出不会输出到逻辑'1'
在VHDL代码中不明显。这强烈暗示某个地方出现output
会出现问题,而且在您的代码中并不明显。
(您的代码不会重现您要求帮助的问题,无论您是否想要那些锁存器。)