下面的VHDL代码是一个简单的交换程序。但它没有交换输入a
和b
。我在评论中给出了成绩单值。
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
语句中有一些行为,但我不知道是什么阻止了自己分配它。
答案 0 :(得分:3)
在WriteToStreamAsync
过去之前,VHDL a <= b;
b <= a;
指定的新值无法读取。
这是VHDL的基本属性,因为它反映了寄存器更新的工作方式,然后触发更新的信号就是时钟。
这也意味着你可以在没有变量的情况下实际进行交换,只需执行:
s
代码还有其他问题,例如什么是t1
用于输入和输出的a和b将导致驱动器冲突,除非添加了解析功能。
答案 1 :(得分:1)
如果使用<=
为VHDL中的信号分配新值而未给出明确的延迟(使用after <time>
),则新信号值将在下一个增量循环中可用。当模拟器暂停已为当前增量循环安排的所有进程时,新的增量循环开始。并且在wait
语句处暂停进程。您的流程最后有一个隐式wait on S;
语句,因为您描述了一个包含S
的敏感列表的流程。
您在此处指定了inout
端口a
和b
,其行为与信号相同。
因为,信号更新在下一个增量周期之前才可见,所有报告语句分别打印出a
和b
的相同值。也就是说,当流程开始/恢复时,他们会打印出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;
我必须在这里使用a
和b
的初始值,因为模式inout
的端口和未解析的类型。因此,我无法通过在另一个测试平台进程中分配a
和b
来添加第二个驱动程序。
因为,信号更新会延迟(至少)到下一个增量周期,因此您不需要额外的变量。这是一个非常简短的示例代码,演示了两个信号的交换:
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;
交换在时钟的每个上升沿完成,如下面的波形所示: