【发布时间】:2015-04-22 19:14:22
【问题描述】:
我正在尝试实现 PoC.Simulation 帮助程序包的 VHDL-08 版本。
原包使用共享变量跟踪模拟状态:
- 通过:所有断言通过
- 停止:停止所有进程
有几个函数和过程使用该内部状态。例如,tbGenerateClock() 过程用于创建时钟信号。
在我的 VHDL-08 版本中,我将受保护类型用于共享变量。我实现了几个“方法”(正确的终点是什么?),它们正在使用或修改内部状态变量。
GHDL 编译我所有的源代码并在运行时抛出错误:
C:\Tools\GHDL\0.33dev\bin\ghdl.exe:internal error: protected_enter(2)
C:\Tools\GHDL\0.33dev\bin\ghdl.exe:error: simulation failed
这是 GHDL 内部错误还是我以错误的方式使用受保护类型?
我创建了一个(希望是)最小示例 (download from Gist),它只有 2 个过程:generateClock、stopSimulation。
还有tb* 包装程序以确保与我的VHDL-93 实现兼容的接口。
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package simulation is
type tSimStatus is protected
procedure stopSimulation;
procedure generateClock(signal Clock : out STD_LOGIC; constant ClockPeriod : TIME; Enable : BOOLEAN := TRUE);
end protected;
-- stop all simulation processes
procedure tbStopSimulation;
-- Generate clock waveform for simulation
procedure tbGenerateClock(signal Clock : out STD_LOGIC; constant ClockPeriod : TIME; Enable : BOOLEAN := TRUE);
end;
package body simulation is
type tSimStatus is protected body
variable stop : BOOLEAN := FALSE;
procedure stopSimulation is
begin
stop := TRUE;
end procedure;
procedure generateClock(signal Clock : out STD_LOGIC; constant ClockPeriod : TIME; Enable : BOOLEAN := TRUE) is
constant HIGH_TIME : TIME := ClockPeriod / 2;
constant LOW_TIME : TIME := ClockPeriod / 2;
begin
Clock <= '1';
while not stop loop
while Enable and not stop loop
Clock <= '1';
wait for HIGH_TIME;
Clock <= '0';
wait for LOW_TIME;
end loop;
wait until (Enable = TRUE) or (stop = TRUE);
end loop;
end procedure;
end protected body;
shared variable status : tSimStatus;
procedure tbStopSimulation is
begin
status.stopSimulation;
end procedure;
procedure tbGenerateClock(signal Clock : out STD_LOGIC; constant ClockPeriod : TIME; Enable : BOOLEAN := TRUE) is
begin
status.generateClock(Clock, ClockPeriod, Enable);
end procedure;
end package body;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use work.simulation.all;
entity tb is
end entity;
architecture test of tb is
constant CLOCK_PERIOD : TIME := 10 ns;
signal Clock : STD_LOGIC;
signal Reset : STD_LOGIC := '0';
begin
-- clock process
process
begin
tbGenerateClock(Clock, CLOCK_PERIOD, TRUE);
end process;
-- stimuli process
process
begin
wait until rising_edge(Clock);
Reset <= '1';
wait until rising_edge(Clock);
Reset <= '0';
wait until rising_edge(Clock);
tbStopSimulation;
wait;
end process;
end;
解决方案:
- 将时钟生成代码移动到
tbGenerateClock过程中 - 向受保护类型添加函数以获取内部停止状态
- 将此函数标记为
impure
这是修改后的模拟包:
package simulation is
type tSimStatus is protected
procedure stopSimulation;
impure function getState return BOOLEAN;
end protected;
-- stop all simulation processes
procedure tbStopSimulation;
-- Generate clock waveform for simulation
procedure tbGenerateClock(signal Clock : out STD_LOGIC; constant ClockPeriod : TIME; Enable : BOOLEAN := TRUE);
end;
package body simulation is
type tSimStatus is protected body
variable stop : BOOLEAN := FALSE;
procedure stopSimulation is
begin
stop := TRUE;
end procedure;
impure function getState return BOOLEAN is
begin
return stop;
end function;
end protected body;
shared variable status : tSimStatus;
procedure tbStopSimulation is
begin
status.stopSimulation;
end procedure;
procedure tbGenerateClock(signal Clock : out STD_LOGIC; constant ClockPeriod : TIME; Enable : BOOLEAN := TRUE) is
constant HIGH_TIME : TIME := ClockPeriod / 2;
constant LOW_TIME : TIME := ClockPeriod / 2;
begin
Clock <= '1';
while not status.getState loop
while Enable and not status.getState loop
Clock <= '1';
wait for HIGH_TIME;
Clock <= '0';
wait for LOW_TIME;
end loop;
wait until (Enable = TRUE) or (status.getState = TRUE);
end loop;
end procedure;
end package body;
【问题讨论】:
-
这个问题不限于ghdl 0.33。这只是默认的 ghdl :)
标签: vhdl simulation ghdl