Как рассчитать RPM домашнего тренажера с VHDL

у меня проблема; Мне нужно рассчитать/измерить обороты домашнего тренажера с помощью датчика Холла и магнита на колесе, аппаратное обеспечение должно быть описано на VHDL, мой текущий метод таков:

  1. Если датчик Холла обнаруживает импульс, сброс счетчика

  2. Увеличение счетчика каждый такт

  3. При следующем импульсе сохраните предыдущее значение, сбросьте и повторите.

Код:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
entity teller is
    port(
        hallsens        : in std_logic;
        counter     : out std_logic_vector(15 downto 0);
        areset      : in std_logic;
        clk         : in std_logic
        );
end entity teller;
 
architecture rtl of teller is
signal counttemp    : std_logic_vector(15 downto 0);
signal timerval2    : std_logic_vector(15 downto 0);
signal lastcount    : std_logic_vector(15 downto 0);
begin   
    process(clk, areset)
    begin
        if areset = '1' then
        
            counter <= "0000000000000000";
            counttemp <= "0000000000000000";
            timerval2 <= "0000001111101000";            
        elsif hallsens = '1' then
        counter <= lastcount + "1";
        timerval2 <= "0000001111101000";
        counttemp <= "0000000000000000";
        
        elsif rising_edge(clk) then
            
            
            timerval2 <= timerval2 - "1";
 
            if timerval2 = "0000000000000000" then
                
                lastcount <= counttemp;
                counttemp <= counttemp + "1";
                timerval2 <= "0000001111101000";
                
                
            end if;
        end if;
    end process;
    
end rtl;

Но чтобы рассчитать RPM из этого, мне нужно разделить счетчик на тактовую частоту и умножить на 60. Это требует много аппаратного обеспечения на FPGA (Altera Cyclone 2).

Есть ли более эффективный способ сделать это?

ТИА


person Jospuntnl    schedule 19.09.2020    source источник
comment
Почему у вас есть два условия установки/сброса? обычно вы придерживаетесь одного сброса и состояния часов? Я предлагаю переместить детектор Холлсенса внутрь часов. У вас также есть конфликтующие библиотеки std_logic_arith и numeric_std. std_logic_arith — это нестандартный пакет VHDL, поэтому его следует удалить (std_logic_unsngied тоже нестандартен, но ни с чем не конфликтует)   -  person Tricky    schedule 20.09.2020
comment
Известно ли вам, что if timerval2 = X"0000" проверяет значение timerval2, которое присутствовало до фактического назначения сигнала timerval2 <= timerval2 - 1;?   -  person aschipfl    schedule 20.09.2020


Ответы (1)


У меня сейчас нет под рукой компьютера, но я попытаюсь указать разные вещи, которые я вижу:

  • Не смешивайте числовые библиотеки (желательно использовать только numeric_std), как предлагает @tricky.

  • Если вы обрабатываете числовые значения и включаете библиотеки для этого... вы можете использовать числовые типы для сигналов (целые, без знака, со знаком...), это проясняет ситуацию и помогает различать числовые сигналы и сигналы, не имеющие числового значения.

  • Hallsens читается как псевдо-сброс, но не находится в списке чувствительности процесса, это могло вызвать несоответствие между симками и hw. В любом случае, это не очень хороший подход, придерживайтесь простой пары сброса и часов.

  • Я бы обнаружил холлсенсы в тактовой области процесса и увеличил там счетчик событий. Это должно быть проще. Я предполагаю, что время, заявленное вашим холлсенсом, достаточно велико, чтобы его можно было зафиксировать часами.

  • Как только сигнал таймера достигает нуля (я предполагаю, что это дает вам известное время, основанное на вашей частоте клика), вы можете снова перезагрузить таймер (как вы это делаете), вывести значение счетчика и сбросить счетчик, начиная снова.

  • Для математических операций 1/Freq и *60 вы можете использовать некоторые числовые приемы, если это необходимо, на основе значения частоты... но вы можете:

  • умножайте на обратную частоту вместо деления.
  • аппроксимируйте его суммой степени 2. (60 = 64-4)
  • сделайте Freq кратным 60, чтобы упростить расчеты.

Ps: чтобы быть менее подверженным ошибкам, вы можете инициализировать свои векторы (поскольку они кратны 4) в шестнадцатеричном формате, например: signal‹=X0003, избегая больших двоичных чисел.

person domitilo    schedule 24.10.2020