1

下面的 VHDL 代码是一个简单的交换程序。但它不会交换输入ab. 我在评论中给出了成绩单值。

library ieee;
use ieee.std_logic_1164.all;

entity vhdl_swap is
  port(a,b: inout integer);
end vhdl_swap;

architecture ar of vhdl_swap is
  signal s : std_logic;
begin

  process(s)
    variable var : integer:=0;
  begin
    report "var is" & integer'image(var); -- 0
    report "a is " & integer'image(a);    -- 10 - (given value when simulated)
    report "b is " & integer'image(b);  -- 20 - (given value when simulated)

    report "---------------------------";

    var := a;
    report "var is " & integer'image(var);--var = 10 (assigned properly)
    a<=b;
    report "a is " & integer'image(a);-- a=10(same value but not assigned)
    b<=var;
    report "b is " & integer'image(b);-- b=20(same value but not assigned)

    report "-----------------------------------";

    report "a is " & integer'image(a);--a=10
    report "b is " & integer'image(b);--b=20

    --print()  

  end process;
end;

声明中有一些东西起作用a<=b,但我不知道是什么阻止了它自己分配它。

4

2 回答 2

3

在经过增量延迟之前,分配给 VHDL 的新值<=不可用于读取。

这是 VHDL 的基本属性,因为它反映了寄存器更新的工作方式,然后触发更新的信号是时钟。

这也意味着您实际上可以在没有变量的情况下进行交换,只需执行以下操作:

a <= b;
b <= a;

代码还有其他问题,例如s用于什么,输入和输出都使用 a 和 b 会导致驱动冲突,除非添加了解析功能。

于 2016-02-26T18:13:37.527 回答
1

如果您在 VHDL 中为信号分配一个新值,<=而没有给出明确的延迟(使用after <time>),那么新的信号值将在下一个增量周期中可用。当模拟器暂停所有为当前增量周期安排的进程时,一个新的增量周期开始。wait一个进程在一个语句处被暂停。wait on S;您的流程末尾有一个隐式声明,因为您描述了一个包含敏感度列表的流程S。您分配的inout端口ab此处的行为与信号相同。

因为,信号更新直到下一个增量周期才可见,所有报告语句分别打印出相同的值ab。也就是说,它们打印出进程开始/恢复的值a和时间。b

分配信号不同于分配变量,例如var在您的代码中,它会立即更新。

您的进程只执行一次,因为信号S没有改变。每个进程在模拟开始后执行一次,然后在wait语句处暂停(如上所述代码中的隐式语句)。

你说,a初始b值分别为 10 和 20,但我无法用 ModelSim 或 GHDL 重现它。我使用以下测试台进行了尝试,我认为这是唯一可能的方法:

library ieee;
use ieee.std_logic_1164.all;

entity vhdl_swap_tb is
end entity vhdl_swap_tb;

architecture sim of vhdl_swap_tb is
  -- component ports
  signal a : integer := 10;
  signal b : integer := 20;
begin  -- architecture sim

  -- component instantiation
  DUT: entity work.vhdl_swap
    port map (
      a => a,
      b => b);

end architecture sim;

我不得不在这里使用初始值ab因为模式端口inout和未解析类型的端口。因此,我无法通过分配ab在另一个测试平台进程中添加第二个驱动程序。


因为,信号更新(至少)延迟到下一个增量周期,所以您不需要额外的变量。这是一个非常简短的示例代码,演示了两个信号的交换:

library ieee;
use ieee.std_logic_1164.all;

entity swap is
end entity swap;

architecture sim of swap is
  signal a     : integer   := 10;
  signal b     : integer   := 20;
  signal clock : std_logic := '1';
begin

  -- clock generation
  clock <= not clock after 10 ns;

  -- swapping
  process(clock)
  begin
    if rising_edge(clock) then
      a <= b;
      b <= a;
    end if;
  end process;
end sim;

交换在时钟的每个上升沿完成,如下图所示:

模拟输出

于 2016-02-26T20:34:53.667 回答