如何在VHDL设计中减少ALM的数量?

如何在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

我正在尝试用VHDL实现数字时钟的报警模块。我已经为它编写了架构,但是当我运行编译时,我得到了太多的自适应逻辑模块(大约2000个),我认为这太多了。我将在下面发布我的代码

我认为在这行代码中,除法和模运算可能是导致它的原因

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;