我编写了一个简单的vhdl代码,在某些条件下通过某些控制信号启用/禁用输出端口。问题是输出信号是U或X而代码看起来很好。
主要实体如下所示。第一个进程对rst
敏感,当它为1时将禁用oe
。第二个进程对clk
敏感,并在时钟转换时启用oe
。输出值也设置为5
。
entity test2 is
port( clk: in std_logic;
rst: in std_logic;
num: out integer range 0 to 7;
oe: out std_logic );
end;
architecture behav of test2 is
begin
process( rst )
begin
if rst = '1' then
oe <= '0';
end if;
end process;
process( clk )
begin
if (clk'event and clk = '1') then
num <= 5;
oe <= '1';
end if;
end process;
end;
现在考虑一下testbench文件。可以看出,在主要过程中,我将r
连接到rst
设置为1,然后设置为0.
entity test2_tb is
end;
architecture behav of test2_tb is
component test2 port( clk: in std_logic;
rst: in std_logic;
num: out integer range 0 to 7;
oe: out std_logic );
end component;
signal c: std_logic := '0';
signal r: std_logic;
signal n: integer range 0 to 7 := 2;
signal o: std_logic;
begin
u1: test2 port map( c, r, n, o );
process( c )
begin
c <= not c after 2ns;
end process;
process
begin
r <= '1';
wait for 4 ns;
r <= '0';
wait for 8 ns;
end process;
end;
r
为1时,连接到o
的{{1}}设置为U.为什么?而且,在时钟的上升沿,oe
的值变为X.为什么?请看下面的波浪
答案 0 :(得分:3)
简而言之:您的oe
端口可能不应该是std_logic
类型,而是std_ulogic
(clk
和rst
相同),它应该是可能是由一个过程驱动而不是两个:
process(clk)
begin
if clk'event and clk = '1' then
if rst = '1' then
oe <= '0';
else
num <= 5;
oe <= '1';
end if;
end if;
end process;
或者,如果您更喜欢异步重置:
process(clk, rst)
begin
if rst = '1' then
oe <= '0';
elsif clk'event and clk = '1' then
num <= 5;
oe <= '1';
end if;
end process;
如果您的工具不能正确支持std_ulogic
(不幸的是,逻辑合成器不支持std_ulogic
,至少在顶层),请使用std_logic
但要非常小心总是在一个单独的过程中驱动输出端口(和内部信号),除非在非常特殊的情况下你真的需要多个硬件来同时驱动相同的硬件线,这是非常罕见的(三态逻辑,高阻抗)。 ..)
答案 1 :(得分:2)
即使你完成了对oe的任务,这些过程仍将继续推动他们的价值观(因为你从未告诉他们做任何事情)。一个驱动0和一个驱动1给出一个X.使用if-elsif语句将两个进程合并为一个。只有一个司机没有冲突。最初都是驾驶U.