如何在VHDL设计中减少ALM的数量?
我正在尝试用VHDL实现数字时钟的报警模块。我已经为它编写了架构,但是当我运行编译时,我得到了太多的自适应逻辑模块(大约2000个),我认为这太多了。我将在下面发布我的代码 我认为在这行代码中,除法和模运算可能是导致它的原因如何在VHDL设计中减少ALM的数量?,vhdl,fpga,intel-fpga,Vhdl,Fpga,Intel Fpga,我正在尝试用VHDL实现数字时钟的报警模块。我已经为它编写了架构,但是当我运行编译时,我得到了太多的自适应逻辑模块(大约2000个),我认为这太多了。我将在下面发布我的代码 我认为在这行代码中,除法和模运算可能是导致它的原因 alarm_hour1 <= std_logic_vector(to_unsigned(savedHours/10,alarm_hour1'length)); alarm_hour0 <= std_logic_vector(to_unsigned(sa
alarm_hour1 <= std_logic_vector(to_unsigned(savedHours/10,alarm_hour1'length));
alarm_hour0 <= std_logic_vector(to_unsigned(savedHours mod 10,alarm_hour0'length));
alarm_minute1 <= std_logic_vector(to_unsigned(savedMinutes/10,alarm_minute1'length));
alarm_minute0 <= std_logic_vector(to_unsigned(savedMinutes mod 10,alarm_minute0'length));
alarm_hour1考虑将报警时间保留为二进制格式,这样您可以直接将其与当前时间(以BCD格式提供)进行比较
这是一个很好的例子,说明了使用适当的内部数据格式可以显著减少计算问题,因为只保留一种数据格式(BCD),就可以简单地消除代价高昂的除法和模运算不要混合使用BCD和二进制数据格式。请考虑将报警时间保留为二进制格式,这样您可以直接将其与BCD格式提供的当前时间进行比较
这是一个很好的例子,说明了使用适当的内部数据格式可以显著减少计算问题,因为只保留一种数据格式(BCD),就可以简单地消除代价高昂的除法和模运算而不是混合BCD和二进制数据格式。未指定信号savedHours
和savedMinutes
的范围,因此Quartus假设它们是32位宽。使用一个32位操作数对除法器进行推断,结果生成一个大型条件减法树
将代码更新为类似
——报警时间
信号保存时间:自然范围0至23:=0;
信号保存数量:自然范围0到59:=0;
很可能导致ALM使用量减少
另外,请注意,上升沿
应仅用于时钟信号(在VHDL启动器级别)。您可能需要的不是将逻辑连接到寄存器的时钟输入,而是一些按钮去抖动逻辑。没有指定信号savedHours
和savedMinutes
的范围,因此Quartus假设它们是32位宽。使用一个32位操作数对除法器进行推断,结果生成一个大型条件减法树
将代码更新为类似
——报警时间
信号保存时间:自然范围0至23:=0;
信号保存数量:自然范围0到59:=0;
很可能导致ALM使用量减少
另外,请注意,上升沿
应仅用于时钟信号(在VHDL启动器级别)。您可能需要的不是将逻辑连接到寄存器的时钟输入,而是一些按钮去抖动逻辑。VHDL中的BCD数据类型?我没听说过。我在谷歌上搜索了一下,没有找到任何结果。你能说得更具体些吗?谢谢。我是有意把它概括起来的,以免破坏你的家庭作业和学习经验;-)你在这里做硬件,所有的螺丝和螺栓都用VHDL,但你必须自己组装<可变长度的code>std_logic_vector
可以表示值,因此只需为不同的值部分选取其中的一些值。每个时钟数字可以是一个单独的计数器,其范围为0到2(十小时),0到9(小时和分钟),0到5(十分钟)。出于显示目的,其值可表示为BCD。由于隐含的复杂性原因,不依赖于base 10分区的硬件描述在合成中并不总是受支持,这在这里得到了恰当的演示,而一些供应商可能会鼓励非硬件设计者使用更大的设备。VHDL中的BCD数据类型?我没听说过。我在谷歌上搜索了一下,没有找到任何结果。你能说得更具体些吗?谢谢。我是有意把它概括起来的,以免破坏你的家庭作业和学习经验;-)你在这里做硬件,所有的螺丝和螺栓都用VHDL,但你必须自己组装<可变长度的code>std_logic_vector可以表示值,因此只需为不同的值部分选取其中的一些值。每个时钟数字可以是一个单独的计数器,其范围为0到2(十小时),0到9(小时和分钟),0到5(十分钟)。出于显示目的,其值可表示为BCD。由于隐含的复杂性原因,不依赖于base 10部门的硬件描述在合成中并不总是得到支持,这一点在这里得到了很好的证明,而一些供应商可能会鼓励非硬件设计师使用更大的设备。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity alarm is
port(
--INPUTS
reset : in std_logic;
clock : in std_logic;
alarm_enable : in std_logic;
alarm_set : in std_logic;
alarm_increment : in std_logic;
alarm_decrement : in std_logic;
currentTime_hour1 : in std_logic_vector(3 downto 0);
currentTime_hour0 : in std_logic_vector(3 downto 0);
currentTime_minute1 : in std_logic_vector(3 downto 0);
currentTime_minute0 : in std_logic_vector(3 downto 0);
--OUTPUTS
alarm_buzzer : out std_logic;
alarm_hour1 : buffer std_logic_vector(3 downto 0) := "0000";
alarm_hour0 : buffer std_logic_vector(3 downto 0) := "0000";
alarm_minute1 : buffer std_logic_vector(3 downto 0) := "0000";
alarm_minute0 : buffer std_logic_vector(3 downto 0) := "0000"
);
end alarm;
architecture alarmBehaviour of alarm is
--ALARM TIME
signal savedHours : integer := 0;
signal savedMinutes : integer := 0;
signal incrementDecrementbuttonDetect : std_logic;
signal set_lastButtonState : std_logic := '0';
signal setButtonDetect : std_logic := '0';
--STATE MACHINE
type state_type is (idle, setHour, setMinute);
signal state_reg, state_next : state_type;
begin
incrementDecrementbuttonDetect <= alarm_increment or alarm_decrement;
--STATE REGISTER
process(clock, reset)
begin
if (reset = '1') then
state_reg <= idle;
elsif rising_edge(clock) then
state_reg <= state_next;
end if;
end process;
--SET BUTTON PRESSED
process(clock)
begin
if(rising_edge(clock)) then
if(alarm_set = '1' and set_lastButtonState = '0') then
setButtonDetect <= '1';
else
setButtonDetect <= '0';
end if;
set_lastButtonState <= alarm_set;
end if;
end process;
--NEXT STATE
process(state_reg, setButtonDetect)
begin
case state_reg is
when idle =>
if setButtonDetect = '1' then
state_next <= setHour;
else
state_next <= idle;
end if;
when setHour =>
if setButtonDetect = '1' then
state_next <= setMinute;
else
state_next <= setHour;
end if;
when setMinute =>
if setButtonDetect = '1' then
state_next <= idle;
else
state_next <= setMinute;
end if;
end case;
end process;
process (incrementDecrementbuttonDetect, state_reg)
begin
if rising_edge(incrementDecrementbuttonDetect) then
case state_reg is
when idle =>
when setHour =>
if alarm_increment = '1' then
if savedHours = 23 then
savedHours <= 0;
else
savedHours <= savedHours + 1;
end if;
else null;
end if;
if alarm_decrement = '1' then
if savedHours = 0 then
savedHours <= 23;
else
savedHours <= savedHours - 1;
end if;
else null;
end if;
when setMinute =>
if alarm_increment = '1' then
if savedMinutes = 59 then
savedMinutes <= 0;
else
savedMinutes <= savedMinutes + 1;
end if;
else null;
end if;
if alarm_decrement = '1' then
if savedMinutes = 0 then
savedMinutes <= 59;
else
savedMinutes <= savedMinutes - 1;
end if;
else null;
end if;
end case;
end if;
end process;
alarm_hour1 <= std_logic_vector(to_unsigned(savedHours/10,alarm_hour1'length));
alarm_hour0 <= std_logic_vector(to_unsigned(savedHours mod 10,alarm_hour0'length));
alarm_minute1 <= std_logic_vector(to_unsigned(savedMinutes/10,alarm_minute1'length));
alarm_minute0 <= std_logic_vector(to_unsigned(savedMinutes mod 10,alarm_minute0'length));
--ALARM BUZZER CONDITION
process (currentTime_hour1, currentTime_hour0, currentTime_minute1, currentTime_minute0,
alarm_enable, alarm_hour1, alarm_hour0, alarm_minute1, alarm_minute0)
begin
if((alarm_hour1 = currentTime_hour1) and (alarm_hour0 = currentTime_hour0)
and (alarm_minute1 = currentTime_minute1) and (alarm_minute0 = currentTime_minute0) and alarm_enable = '1') then
alarm_buzzer <= '1';
else
alarm_buzzer <= '0';
end if;
end process;
end alarmBehaviour;