Перейти к содержанию
    

Неправильное вычисление среднего значения.

Вычисляю так

 

constant ADC_SAMPLES : std_logic_vector(7 downto 0) := X"03";


when ST_ADC_AVG =>
    if (adc_idx < (ADC_SAMPLES+1)) then
	    if (ADC_READY = '0') then
		    ADC_TRIG <= '1';
		    ChargeState <= ST_ADC_WAIT;
	    end if;	 
    else
        conv_ready  <= '1'; 
		adc_average_res <= std_logic_vector( unsigned(adc_average) / unsigned(ADC_SAMPLES) ); 
		ChargeState <= ST_ADC_RES;
	end if;	
					  
when ST_ADC_WAIT => 
    if (ADC_READY = '1') then
		ADC_TRIG <= '0'; 
		adc_average <= adc_average + ADC_VAL_IN;
		adc_idx := adc_idx + 1;
		ChargeState <= ST_ADC_AVG;
	end if;	
					  
when ST_ADC_RES =>  
	case ms_counter is 
	    when X"03" => 
			ADC_VAL_3MS <= adc_average_res(17 downto 0);
			ADC_SAMP_ST <= X"03";
		
		when others =>
	end case;	
    ChargeState <= ST_SAMPLE; 

 

avg.thumb.png.5f31fe2aec479595ac8a2af81d500773.png

 

Проверяю

adc_average = 0xD80 + 0xD5D + 0xD43 = 0x2820 – все верно

но конечный результат ADC_VAL_3MS = 0x11EB – это значит adc_average деленное на 2 а не на 3.

Это как так выходит?

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

6 minutes ago, jenya7 said:

Это как так выходит?

Вы это синтезируете?  С операцией деления на произвольную величину? :shok: 

А вы уверенны что при синтезе у вас  деление на  переменную не заменяется на деление на ближайшую степень 2ки?

Меня в школе учили что деление на x можно заменить  умножением на 1/x.  Но это давно было - сейчас такому может уже и не учат. :cray2:

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, RobFPGA said:

Приветствую!

Вы это синтезируете?  С операцией деления на произвольную величину? :shok: 

А вы уверенны что при синтезе у вас  деление на  переменную не заменяется на деление на ближайшую степень 2ки?

Меня в школе учили что деление на x можно заменить  умножением на 1/x.  Но это давно было - сейчас такому может уже и не учат. :cray2:

Удачи! Rob.

умножением на 1/x? в VHDL?  мне только флоут не хватало для полного счастья :))

 

adc_average_res <= std_logic_vector( unsigned(adc_average) / 3) );

тот же результат. делиться на два.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую.

9 minutes ago, jenya7 said:

умножением на 1/x? в VHDL?  мне только флоут не хватало для полного счастья :))

Увы - не будет у вас "полного счастья"  :unknw: -  а будет fixed point.  Ведь  умножение на 1/x  можно  преобразовать  как (value * round(2^N/x)) / 2^N.

Выбирая величину числа N  будете регулировать точность приближения к "полному счастью" :biggrin:

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, RobFPGA said:

Приветствую.

Увы - не будет у вас "полного счастья"  :unknw: -  а будет fixed point.  Ведь  умножение на 1/x  можно  преобразовать  как (value * round(2^N/x)) / 2^N.

Выбирая величину числа N  будете регулировать точность приближения к "полному счастью" :biggrin:

Удачи! Rob.

я поставил

constant ADC_SAMPLES : std_logic_vector(7 downto 0) := X"04";

получил ADC_VAL_3MS =  adc_average деленное на 3.

оно делиться на ADC_SAMPLES - 1. тут скорее логическая проблема а не арифметическая.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

58 minutes ago, jenya7 said:

Вычисляю так

Проверяю

adc_average = 0xD80 + 0xD5D + 0xD43 = 0x2820 – все верно

но конечный результат ADC_VAL_3MS = 0x11EB – это значит adc_average деленное на 2 а не на 3.

Это как так выходит?

0x11EB*2=0x23D6, у вас вообще не так выходит)

ЗЫ. возьмите нормальный симулятор, перед тем как выполнять отладку на плис

ЗЗЫ. 99.9% ошибка со времянкой в делителе 32-х битных чисел 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

0x2820 / 0x11EB = 2

 

не знаю почему но так работает

adc_average_res <= std_logic_vector( unsigned(adc_average) / unsigned(ADC_SAMPLES+1) ); 

 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/30/2020 at 8:17 PM, jenya7 said:

0x2820 / 0x11EB = 2 

а ничего что в режиме "программист" калькулятор виндовз целочисленный? 

На остальное я уже ответил. 

ЗЫ. Просидите в состоянии деления тактов 5-6,  должно помочь. На будущее, не используйте вот такую реализацию вычисления среднего. Это не МК

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

1 hour ago, jenya7 said:

оно делиться на ADC_SAMPLES - 1. тут скорее логическая проблема а не арифметическая.

Логические проблемы решаются на нормальном симуляторе, а не по неполному куску кода. В купе с предварительным  анализом  что как можно сделать для оптимальной реализации заданного функционала.   Операция деления очень затратная при реализации в FPGA. Фактически это будет комбинаторный делитель! :wacko:

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, jenya7 сказал:

тут скорее логическая проблема а не арифметическая.

Скорее всего. Возможно, что-то связано с переводом из одного типа в другой.

Нормально целочисленное деление работает.

Спойлер

LIBRARY ieee;
USE ieee.std_logic_1164.all;


--  Entity Declaration

ENTITY Divider IS
	-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
	PORT
	(
		Clk : IN STD_LOGIC;
		IN_Data1 : IN  Integer range 0 to 255;
		IN_Data2 : IN  Integer range 0 to 255;
		IN_Data3 : IN  Integer range 0 to 255;
		OUT_Data : OUT Integer range 0 to 255
	);
	-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!
	
END Divider;


--  Architecture Body

ARCHITECTURE Divider_architecture OF Divider IS

	
BEGIN


Process(Clk, IN_Data1, IN_Data2, IN_Data3)
begin
if rising_edge(Clk)
  then OUT_Data <= (IN_Data1 + IN_Data2 + IN_Data3) / 3;
end if;
end process;


END Divider_architecture;

 

 

Спойлер

Div_by_3-1.thumb.png.58abf483c60242c61ec618a80f9f161c.png

 

Спойлер

Div_by_3-2.thumb.png.8f7b6f1d4985bb2edf8fd0124f69296b.png

 

Изменено пользователем MrGalaxy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Работаете со массивами, кратными степени двойки. Тогда операцию деления можно будет заменить сдвигом. Вернее даже не сдвигом, а отбрасыванием нулей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для деления можете использовать ip ядро cordic , в нем есть функция деления, которая нормально в железе работает. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 hours ago, MrGalaxy said:

Скорее всего. Возможно, что-то связано с переводом из одного типа в другой.

Нормально целочисленное деление работает.

 

 

 

может потому что integer. у меня std_logic_vector.

14 hours ago, Flip-fl0p said:

Работаете со массивами, кратными степени двойки. Тогда операцию деления можно будет заменить сдвигом. Вернее даже не сдвигом, а отбрасыванием нулей.

с шифтом надо попробовать

13 hours ago, Skryppy said:

Для деления можете использовать ip ядро cordic , в нем есть функция деления, которая нормально в железе работает. 

там нет деления. по крайней мере для MAX 10

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 hours ago, MrGalaxy said:

Скорее всего. Возможно, что-то связано с переводом из одного типа в другой.

Отнюдь, при всем уважении, но у ТС проблемы с математикой 5 го класса, а не все что описали выше коллеги)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, des00 сказал:

у ТС проблемы с математикой 5 го класса, а не все что описали выше коллеги)

Я с кодом до конца не разобрался, мозг закипел от бесконечных  STD_LOGIC_VECTOR, :wacko2: и ни одного комментария. :unknw:

6 часов назад, jenya7 сказал:

может потому что integer. у меня std_logic_vector. 

Кто Вам запрещает? Если в итоге непременно нужен std_logic_vector, делаете арифметику в отдельном блоке и передаёте в другой блок. Шина одна и та же. Повысится наглядность кода, а это много стоит.

6 часов назад, jenya7 сказал:

с шифтом надо попробовать

Деление на 2 синтезируется как сдвиг. То, что Вы явно в коде укажете сдвиг, ничего в плане быстродействия или экономии ресурсов не даст. (Про Xilinx не скажу, а Квартус синтезирует именно так).

Изменено пользователем MrGalaxy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...