我是VHDL,Quartus II和ModelSim的新手。现在,我正在建立一个我们正在构建闪烁LED的实验室。当施工处理相对较长的时间段时,应该如何处理模拟。闪烁LED的频率为1 Hz,开发板I(使用(Terasic DE2-115))上的时钟为50 MHz。在代码中,我计算时钟脉冲并相应地打开LED。但是,当我想用ModelSim验证我的代码时,我遇到了处理时间长达几秒钟的麻烦。所以我只是通过将代码中的周期更改为几个时钟周期来解决它,以确定波的行为符合预期。对于最终编译,我只需更改对应于1秒的计数值。
但应该有更好的方法。我不想在模拟后触摸VHDL代码。在处理接近1 ms或更高的时间段时,我应该使用两个rtl,一个用于合成,一个用于模拟吗?
VHDL代码
library ieee;
use ieee.std_logic_1164.all;
entity lab4 is
port( CLOCK_50 : in std_logic; -- DE2-115 internal clock
KEY : in std_logic_vector(0 downto 0); -- Push-buttons, active 0
-- KEY(0) as reset
LEDG : out std_logic_vector(7 downto 0)); -- Green LEDs
end entity lab4;
architecture lab4_rtl of lab4 is
signal RESET_N : std_logic;
begin
-- Parallel VHDL
constant CLK_FRQ : integer := 50000000;
RESET_N <= KEY(0); -- Here we connect reset to a push-button
-- synch process with asynch reset, i.e. reset as soon as reset is active
p1 : process(CLOCK_50, RESET_N)
variable counter : integer := 0;
variable led_num : integer := 0;
begin
-- reset part
if RESET_N = '0' then --KEY is active 0
counter := 0; --reset counter
LEDG(0) <= '0'; --turn OFF leds
-- synch part, updates depending on clock
elsif rising_edge(CLOCK_50) then
counter := counter + 1;
if counter < 50000000 then;
LEDG(0) <= '1';
elsif counter >= 50000000 AND counter < 100000000 then
LEDG(0) <= '0';
else
counter := 0;
end if;
end if;
end process p1;
end architecture lab4_rtl;
答案 0 :(得分:1)
您声明了一个命名常量,然后忽略它......
constant CLK_FRQ : integer := 50000000;
首先,您可以用CLK_FRQ和CLK_FRQ * 2而不是幻数重写计数器。
然后你可以在sim和synth中为CLK_FRQ设置不同的值。有各种方法可以做到这一点,但我的偏好是一个功能。
function Clock_Frequency return natural is
begin
-- synthesis translate_off
return 50;
-- synthesis translate_on
return 50000000;
end Clock_Frequency;
它使用&#34;魔法&#34; pragmas translate_off(和_on)可能在综合工具之间有所不同,但大多数人都接受。这些直接合成忽略了源的位:在这种情况下,第一个返回只能由模拟器看到。
现在你可以调用这个函数初始化常量
constant CLK_FRQ : integer := Clock_Frequency;
完成工作。
答案 1 :(得分:1)
我不会改变时钟频率,因为这不会改变模拟器必须模拟的事件数(这也是耗时因素)。我认为在更改LED输出之前更改必须通过的周期数会更好。
您可以定义VHDL函数,如果您在模拟环境中,则返回TRUE:
function SIMULATION return boolean is
variable ret : boolean;
begin
ret := false;
--synthesis translate_off
if Is_X('X') then ret := true; end if;
--synthesis translate_on
return ret;
end function;
除此之外,您还可以定义if-then-else函数来简化代码:
function ite(cond : BOOLEAN; value1 : INTEGER; value2 : INTEGER) return INTEGER is
begin
if cond then
return value1;
else
return value2;
end if;
end function;
现在可以在一行中选择计数器的最大值,如下所示:
constant COUNTER_MAX : INTEGER := ite(SIMULATION, 500, 50000);
从上面查看您的代码,有一些错误: