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

Как убрать варнинги

В 28.02.2024 в 19:23, Maverick_ сказал:

сложно что-то сказать не имея описания или понимания как Ваша схема в FPGA работает

 

Код выложить чтоли?? Но он тут большой достаточно. 

Или проект целиком в архиве?

 

Я тут вроде разобрался что некоторые куски кода как то рандомно меняют максимальную частоту. но в чем смысл не до конца ясно.

У меня все процессы построены по типы FSM (Finite State Machine).

Закоментировал один кусок получил Fmax - 1500 мгц.

Потом какой то простейший if добавил и сразу 600. где логика то. Как можно узнать что конкретно тормозит работу и как правильно то делать?

Или надо делать больше простых процессов ?

 

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


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

On 2/28/2024 at 7:41 PM, Worldmaster said:

простейший if добавил и сразу 600. где логика то

логика в том, что для реализации этого if-а пришлось навернуть логическую схему (которая вполне могла не уложиться в один LUT FPGA, что привело к накручиванию путей прохождения сигналов (к ним добавляются коммутаторы этих сигналов) - в результате возросла задержка во всего одном месте цепочки, тактируемой этими клоком - образовалось бутылочное горлышко, которое и нарушило красивую картинку, рисующую полтора гигагерца.

Вам уже рекомендовали:

 

Quote

улучшить код использующий 160МГц, уменьшив уровни логики

т.е. проследите, откуда эта частота передается (генерируется), как она распространяется (что ею тактируется) - вполне может оказаться, что Вы ее используете еще для чего-то, кроме как подать на RAM, либо неоптимально на нее подается (опять же через какой-нибудь if 😄.

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


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

В 29.02.2024 в 09:20, Yuri124 сказал:

т.е. проследите, откуда эта частота передается (генерируется), как она распространяется (что ею тактируется) - вполне может оказаться, что Вы ее используете еще для чего-то, кроме как подать на RAM, либо неоптимально на нее подается (опять же через какой-нибудь if 😄.

А уровни логики откуда берутся?? Простыми словами это количество блоков которое прищлось создать чтоли?? или уровни вложенности if??

Может есть какие нибудь общие правила типа не используй if - используй switch-case. Или допустим локальные переменные выноси на уровень архитектуры.. 

Или все это просто эмпирический подгон?

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

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


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

15 hours ago, Worldmaster said:

Код выложить чтоли?? Но он тут большой достаточно. 

Или проект целиком в архиве?

 

Я тут вроде разобрался что некоторые куски кода как то рандомно меняют максимальную частоту. но в чем смысл не до конца ясно.

У меня все процессы построены по типы FSM (Finite State Machine).

Закоментировал один кусок получил Fmax - 1500 мгц.

Потом какой то простейший if добавил и сразу 600. где логика то. Как можно узнать что конкретно тормозит работу и как правильно то делать?

Или надо делать больше простых процессов ?

 

Вы случайно for не исползуете?

можно посмотреть на реализацию 

У меня все процессы построены по типы FSM (Finite State Machine).

Закоментировал один кусок получил Fmax - 1500 мгц.

Потом какой то простейший if добавил и сразу 600. где логика то. 

расскажите что доавили что убавили...

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


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

21 минуту назад, Worldmaster сказал:

А уровни логики откуда берутся?? Простыми словами это количество блоков которое прищлось создать чтоли?? или уровни вложенности if??

Может есть какие нибудь общие правила типа не используй if - используй switch-case.

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

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


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

В 29.02.2024 в 11:15, Maverick_ сказал:

Вы случайно for не исползуете?

Нет. Он же вроде как тоже не очень синтезируем. 

Вот основной процесс который тормозит.

 

дополнительные функции	

function rMod(value: integer;   maxSize: integer) return integer is
	begin
		if value >= maxSize then
			return value - maxSize;
		else 
			return value;
		end if;    
	end function;
	 
		  -- функция проверки байт в кольцевом буфере
	function CountDataAvailableForRead(buffer_size : integer; read_ptr, write_ptr : integer) return integer is
	variable count : integer;
	begin
		count := rMod(write_ptr - read_ptr + buffer_size, buffer_size);
		return count;
	end function;

	function CountDataAvailableForWrite(buffer_size : integer; read_ptr, write_ptr : integer) return integer is
	variable count : integer;
	begin
		count := rMod(read_ptr - write_ptr + buffer_size, buffer_size);
		if read_ptr = write_ptr then
			return buffer_size;
		end if;
		return count;
	end function;


main_proc: process (USB30_in_clk,SystemReadyFlag,command_request_flag,command_accept_flag,FFT_rx_flag,FFT_tx_flag  ) 
	
	type DATA_MODE_STATE is (idle, frame_data, gyro_data);
	type LOC_FSM_STATE is (idle, wait_tran, get_data, send_data, wait_end_transaction,wait_cycle, prepare_receive, test1, test2 );
	variable loc_state: LOC_FSM_STATE := idle;  
	variable data_mode: DATA_MODE_STATE  := idle;
	variable read_ptr: integer :=0; -- счетчик байт для считывания команд
	variable write_ptr: integer :=0; -- счетчик байт для отправки данных 
	variable bytes_sended: integer :=0; -- счетчик байт для отправки данных 
	variable max_bytes_to_send: integer :=0; -- максимальное количество байт для отправки
	variable fifo_bytes_count: integer :=0;
	variable waiter: integer := 0;
	variable wait_i2c: integer :=0;
	variable led_counter: integer :=0;
	variable mipi_wait: integer :=0;
	-- для устрйоства сделать режимы
	-- редим отправки кадров и при каждом запросе чтения срабатывает алгоритм запроса кадра
	-- командный режим для обработки команд и ответа на них
	
	variable test_i2c: integer :=0;
	variable reset_i2c: integer :=0;
	begin 
	
	if SystemReadyFlag = '0' then 
	
	else   
		if rising_edge(USB30_in_clk) then 
			--debug_led_drive <= not debug_led_drive;

-- 1359 mhz 
		
		--FFT_BE_OUT <= (others => '1');	-- из за этого максимум частоты сильно падает  1300 -> 600
		
		-- отправку производим из одного общего буфера
		fifo_bytes_count := CountDataAvailableForRead(MAX_FIFO_BUF_CNT,fifo_read_ptr,fifo_write_ptr );
	
		-- 	если команда принята то снимаем флаг
		if command_request_flag = '1' and command_accept_flag = '1' then
			command_request_flag <= '0';
		end if;
					

		case loc_state is
			when idle =>
				main_proc_rw_state <= idle;
				 
				-- rx значит ПЛИС получает данные из ФИО
				-- tx значит ПЛИС пишет данные в ФИФО
				if FFT_tx_flag = '0' then
					--waiter := 1;
					loc_state := wait_cycle;	
				elsif FFT_rx_flag = '0' then				
					--waiter := 0;
					loc_state := prepare_receive;	
				end if;	
			when wait_cycle =>
				loc_state := prepare_receive;	
			when prepare_receive =>
				loc_state := wait_tran;	
			 
			when wait_tran =>
				 
					-- прием данных
					if FFT_rx_flag = '0' then
						-- когда мы готовы мы дергаем вниз FFT_WR_N
						-- установили счетчик в 0
						-- установили максимум байт для считывания
						-- FFT_WR_N = 0 - готовы
						-- переходим в блок приема
					
						read_ptr := 0;	
						i2c_command_buffer <= (others => (others => '0'));			
						loc_state := get_data;	
						FFT_OE_N <= '0'; 	
						-- отправка данных
					elsif FFT_tx_flag = '0' then 
						-- после прихода запроса готовимся
						-- сбрасываем FFT_OE_N = 0 и сообщаем что мы почти готовы, FFT_RD_N = 1	
						loc_state := send_data;	
						case device_state is
							when command_mode =>
								-- если была команда на обработку и ответ то отдаем результаты из буфера ответа (можно также использовать кольцевой буфер);
								write_ptr := 0;
								bytes_sended := 0; 
								max_bytes_to_send := MAX_I2C_BUF_CNT; 
								cam_frame_send_complete <= '1';
								data_mode := gyro_data;
								
								case i2c_bus_state is
									when gyroscope_bus =>									
										i2c_command_buffer <= i2c_bus_1_rx_data_buffer; 
									when camera_1_bus =>
										i2c_command_buffer <= i2c_bus_2_rx_data_buffer; 
									when camera_2_bus =>
										i2c_command_buffer <= i2c_bus_3_rx_data_buffer; 
								end case; 
							when camera_mode =>
								-- если была команда для чтения кадра то				
								-- сбрасываем кольцевой буфер
								-- устанавливаем счетчик на количество байт для отправки 	
								if cam_frame_send_complete = '1' then
									cam_frame_send_complete <= '0'; 
									write_ptr := 0;
									bytes_sended := 0;
									fifo_read_ptr <= 0;
									data_mode := frame_data;
									
									-- одновременно инициируем считывание данных с гироскопа								 
									i2c_command_buffer(0) <= x"a1";
									i2c_command_buffer(1) <= x"01";
									i2c_command_buffer(2) <= "01101010";
									i2c_command_buffer(3) <= x"00";
									i2c_command_buffer(4) <= x"20";
									i2c_command_buffer(5) <= x"00";
									i2c_command_buffer(6) <= x"01";
									i2c_command_buffer(7) <= x"0E"; -- считываем TEMP[LH] OUTX[LH]G OUTY[LH]G OUTZ[LH]G OUTX[LH]A OUTY[LH]A OUTZ[LH]A
									command_request_flag <= '1';
									
									
									-- размер указываем дополнительно с буфером результатов гироскопа
									-- вставка происходит в процессе приемки данных с камеры.
									-- буфер должен быть заполнен актуальными данными к моменту подготовки всего кадра
									max_bytes_to_send := (560*560) + MAX_I2C_BUF_CNT; -- максимум байт для отправки. Тут надо полный буфер кадра указать правильный 	
									MAX_FRAME_LEN <= 560*560; -- зададим размер кадра
								else
									-- если мы продолжаем читать данные то дальше по циклу
								end if;
						end case;	
					else 
						loc_state := idle;		
					 end if;
				 
			when get_data =>
				if waiter > 0 then 		
					if FFT_rx_flag = '0' then 				
						-- ТУТ ПРИНИМАЕМ ДАННЫЕ. 				
						if read_ptr < MAX_I2C_BUF_CNT then 	 
							-- принимаем данные в командный буфер					
							i2c_command_buffer(read_ptr) <= FFT_DATA_IN(7 downto 0);
							i2c_command_buffer(read_ptr+1) <= FFT_DATA_IN(15 downto 8);
							i2c_command_buffer(read_ptr+2) <= FFT_DATA_IN(23 downto 16);
							i2c_command_buffer(read_ptr+3) <= FFT_DATA_IN(31 downto 24);
							read_ptr := read_ptr + 4;					
						else
							-- когда закончили 
							main_proc_rw_state <= idle;					
							-- передали управление процессу обработки входной команды
							command_request_flag <= '1';	
							loc_state := wait_end_transaction; 
							cam_frame_send_complete <= '1';	
						end if; 
					else 
						command_request_flag <= '1';	
						loc_state := wait_end_transaction;
						cam_frame_send_complete <= '1';	
						main_proc_rw_state <= idle;
					end if; 
				else 
					FFT_RD_N <= '0';	
					waiter := waiter + 1;				
				end if; 
			when send_data =>
				if FFT_tx_flag = '0' then
					if bytes_sended < max_bytes_to_send then							
						case data_mode is
							when idle =>
								FFT_WR_N <= '1'; -- данные не готовы
							when frame_data =>
								if fifo_bytes_count >= 1 then 
									FFT_WR_N <= '0'; -- готовы 
									FFT_DATA_OUT <= fifo_buffer(fifo_read_ptr);
									fifo_read_ptr <= rMod(fifo_read_ptr + 1, MAX_FIFO_BUF_CNT);
									bytes_sended := bytes_sended + 4; -- отправляем по 4 байта	 									
									if bytes_sended >= MAX_FRAME_LEN then
										data_mode := gyro_data;
										i2c_command_buffer <= i2c_bus_1_rx_data_buffer;									
									end if;
								else 
									FFT_WR_N <= '1'; -- данные не готовы
								end if;
							when gyro_data =>
								FFT_WR_N <= '0'; -- готовы 
								FFT_DATA_OUT <= i2c_command_buffer(write_ptr+3) & i2c_command_buffer(write_ptr + 2) & i2c_command_buffer(write_ptr + 1) & i2c_command_buffer(write_ptr );
								write_ptr := rMod(write_ptr + 4, MAX_I2C_BUF_CNT);
								bytes_sended := bytes_sended + 4; -- отправляем по 4 байта	 
						end case;
					else  
						FFT_WR_N <= '1'; 
						cam_frame_send_complete <= '1';
						loc_state := wait_end_transaction;-- все что надо было отправлено					 					
					end if;
				else 
					FFT_WR_N <= '1'; 
					loc_state := wait_end_transaction; -- все что надо было отправлено
				end if; 
			when wait_end_transaction => 
				main_proc_rw_state <= idle;	
				if FFT_rx_flag = '1' and FFT_tx_flag = '1' then
					loc_state := idle; 
				end if; 
			when others =>		 			
		end case; 
	end if;
	end if;
	end process main_proc;

У говина нашел документ с рекомендациями. Там сказано что лучше делать несколько процессов. Так что начал переделывать потихоньку. Так что в коде могут быть неточности.

 

В 29.02.2024 в 11:30, vladec сказал:

и в нем Вам всегда надо стараться представлять как Ваш код будет имплиментироваться в логику,

А как это представлять то?? Есть где то описание как выглядит каждая конструкция?? На что опираться то при таком представлении??

 

 

В 29.02.2024 в 11:15, Maverick_ сказал:

расскажите что доавили что убавили...

Если весь процесс закоментировать и добавить только мигание светодиодом то 1300. Если затем добавить только FFT_BE_OUT <= (others => '1'); то тут же становится 600. 

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

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


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

1 hour ago, Worldmaster said:

Если весь процесс закоментировать и добавить только мигание светодиодом то 1300. Если затем добавить только FFT_BE_OUT <= (others => '1'); то тут же становится 600. 

Все эти 1300МГц, 600МГц - можно прикинуть самому для сферического GW2AR в вакууме. Берёте документ на GW2AR (DS226), смотрите 3.4.1 CFU Switching Characteris:

  • LUT4 delay - 0.337 nS
  • LUT5 delay - 0.694 nS
  • LUT6 delay - 1.005 nS
  • LUT7 delay - 1.316 nS
  • LUT8 delay - 1.627 nS
  • Reg  delay - 0.380 nS

Получаете:

  1. always @( posedge C ) Q<=X; // R = теоретически 0.380 nS (2632МГц), но скорее всего без LUT4 невозможен поэтому равен следующему варианту
  2. always @( posedge C ) Q<=~Q; //LUT4+R = 0.337+0.380=0,717nS (1395МГц)
  3. always @( posedge C ) if(A[2:0]) Q<=X; //LUT4+R = 0.337+0.380=0,717nS (1395МГц)
  4. always @( posedge C ) if(A[3:0]) Q<=X; //LUT5+R = 0.694+0.380=1.074nS (931МГц)
  5. always @( posedge C ) if(CE&A[3:0]) Q<=X; //LUT6+R = 1.005+0.380=1.385nS (722МГц)
  6. always @( posedge C ) if(CE&A[3:0]|B[1:0]) Q<=X; //LUT8+R = 1.627+0.380=2.007nS (498МГц)
  7. always @( posedge C ) if(CE&A[3:0]|B[1:0]) case(Z[13:0]) Q<=X; //LUT8+LUT8+LUT8+R = 1.627+1.627+1.627+0.380=5.261nS (190МГц) - "3 уровня логики"

 

Это когда Х уже готов, а когда

bytes_sended := bytes_sended + 4; -- отправляем по 4 байта	 									
if bytes_sended >= MAX_FRAME_LEN then

вообще неизвестноо сколько ... это у вас случаем не блокирующее присваивание в VHDL?

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


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

В 29.02.2024 в 13:02, _4afc_ сказал:

вообще неизвестноо сколько ... это у вас случаем не блокирующее присваивание в VHDL?

Не понял. А что тут плохого то?? 

И как надо по другому сделать?

 

В 29.02.2024 в 13:02, _4afc_ сказал:
  • LUT4 delay - 0.337 nS
  • LUT5 delay - 0.694 nS
  • LUT6 delay - 1.005 nS
  • LUT7 delay - 1.316 nS
  • LUT8 delay - 1.627 nS
  • Reg  delay - 0.380 nS

Что значит цифра в конце LUT?? Это количество входов? 

А если у меня больше сигналов для входа то как надо сделать правильно чтобы сохранить простоту и задействовать минимум эитх LUT?

 

В 29.02.2024 в 13:02, _4afc_ сказал:
  • always @( posedge C ) Q<=X; // R = теоретически 0.380 nS (2632МГц), но скорее всего без LUT4 невозможен поэтому равен следующему варианту
  • always @( posedge C ) Q<=~Q; //LUT4+R = 0.337+0.380=0,717nS (1395МГц)
  • always @( posedge C ) if(A[2:0]) Q<=X; //LUT4+R = 0.337+0.380=0,717nS (1395МГц)
  • always @( posedge C ) if(A[3:0]) Q<=X; //LUT5+R = 0.694+0.380=1.074nS (931МГц)
  • always @( posedge C ) if(CE&A[3:0]) Q<=X; //LUT6+R = 1.005+0.380=1.385nS (722МГц)
  • always @( posedge C ) if(CE&A[3:0]|B[1:0]) Q<=X; //LUT8+R = 1.627+0.380=2.007nS (498МГц)
  • always @( posedge C ) if(CE&A[3:0]|B[1:0]) case(Z[13:0]) Q<=X; //LUT8+LUT8+LUT8+R = 1.627+1.627+1.627+0.380=5.261nS (190МГц) - "3 уровня логики"

Это откуда такое?? 

то есть уровень это каждое логическое действие? if, not, or, and. То есть надо минимизировать это количество?

 

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

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


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

используемые variable в процессе "умирают" вне процесса - никуда не подключены

Почему не используете signal вместо variable ?

В симуляции точно все работает?



 

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


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

38 minutes ago, Worldmaster said:

Не понял. А что тут плохого то?? И как надо по другому сделать?

Если в терминах верилог - блокируюшее добавит ещё несколько LUT до использования его результата. Те. увеличит слои логики и ограничит частоту простого проекта до десятков МГц.

Надо присваивать вычисленные на предыдущем такте данные.

 

38 minutes ago, Worldmaster said:

Что значит цифра в конце LUT?? Это количество входов?

Да.

 

38 minutes ago, Worldmaster said:

А если у меня больше сигналов для входа то как надо сделать правильно чтобы сохранить простоту и задействовать минимум эитх LUT?

Вставить регистр между LUT.

т.е. заменить 1 такт LUT10.R на 3 такта LUT4.R->LUT4.R->LUT4.R

 

38 minutes ago, Worldmaster said:

Это откуда такое??

Посмотрите получившийся схематик вашего кода в IDE.

 

38 minutes ago, Worldmaster said:

то есть уровень это каждое логическое действие? if, not, or, and. То есть надо минимизировать это количество?

Упрощённо: уровень - это количество LUT4 друг за другом перед Reg.

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


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

On 2/29/2024 at 11:51 AM, Worldmaster said:

А как это представлять то?? Есть где то описание как выглядит каждая конструкция?? На что опираться то при таком представлении??

Вы должны понимать, что на самом деле весь этот код не описывает программу действий (как программирование микропроцессора), а Вы этими записями  описываете конструкцию какого-то устройства.
Т.е. Вы должны себе четко представить (нарисовать) схему/структуру/блок-схему того устройства, которое должно быть синтезировано (сконструировано, "спаяно") внутри FPGA из имеющихся там базовых кирпичиков.
А только потом - описать эту структуру/эту схему средствами языка синтезирования аппаратуры.
Иначе может получиться, что логически Вы устройство описали правильно, но физически оно будет синтезировано компилятором в очень громоздкую монструозную схему с низким быстродействием (большими задержками при формировании к-л сигналов).
Правда, компиляторы умеют оптимизировать схему, но как это у каждого конкретного получается - думаю, что по-разному. И лучше все же в первую очередь полагаться на себя, а компилятору отдавать на откуп более простые конструкции - где он сам сможет оптимально размести сигналы по имеющимся ресурсам (расстояние, кол-во входов LUT и кол-во используемых сигналов).
Как-то так.

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


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

В 29.02.2024 в 14:06, Maverick_ сказал:

Почему не используете signal вместо variable ?

Ну логика что все под боком. Зачем из архитектуры тащить сигналы которые используются только внутри процесса.

В 29.02.2024 в 14:06, Maverick_ сказал:

используемые variable в процессе "умирают" вне процесса - никуда не подключены

Что значит умирают?

 

В 29.02.2024 в 14:06, Maverick_ сказал:

В симуляции точно все работает?

Да, все отлично. Более того, оно и в железе работает. Но сказали что раз красное то это зависит от фазы луны. Поэтому и стал заморачиваться с тем чтобы поправить все как надо.

 

В 29.02.2024 в 14:25, Yuri124 сказал:

Т.е. Вы должны себе четко представить (нарисовать) схему/структуру/блок-схему того устройства

Так есть эта структура и блоксхема. И устройство есть. Или я должен все эти кирпичики вначале нарисовать чтоли.

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

 

В 29.02.2024 в 14:21, _4afc_ сказал:

Надо присваивать вычисленные на предыдущем такте данные.

А можно на примере?

Ну вот конкретно вот тут:

fifo_read_ptr <= rMod(fifo_read_ptr + 1, MAX_FIFO_BUF_CNT); <- на текущем такте записали данные и изменили указатель
bytes_sended := bytes_sended + 4; -- увеличили счетчик на 4
  
  как в данном слуае будет выглядеть неблокирующее присвоение?
  
  -- Как я понимаю в верхней строке присовение будет сделано но увижу я его тут только на следюущем такте.
if bytes_sended >= MAX_FRAME_LEN then  
	data_mode := gyro_data;
	i2c_command_buffer <= i2c_bus_1_rx_data_buffer;									
end if;

 

В 29.02.2024 в 14:21, _4afc_ сказал:

Вставить регистр между LUT.

т.е. заменить 1 такт LUT10.R на 3 такта LUT4.R->LUT4.R->LUT4.R

А можно какой нибудь пример с if ?? 

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


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

В 29.02.2024 в 14:21, _4afc_ сказал:

Посмотрите получившийся схематик вашего кода в IDE.

Да тут просто дичь какая то. Как тут человеку вообще возможно разобраться?  Тут просто какое то месиво.

image.thumb.png.98fd40cf71b5db16c59c4762b9c5aeb0.png

 

В 29.02.2024 в 14:21, _4afc_ сказал:

 

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


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

19 minutes ago, Worldmaster said:

А можно на примере?

Ну вот конкретно вот тут:

fifo_read_ptr <= rMod(fifo_read_ptr + 1, MAX_FIFO_BUF_CNT); <- на текущем такте записали данные и изменили указатель
bytes_sended := bytes_sended + 4; -- увеличили счетчик на 4
  
  как в данном слуае будет выглядеть неблокирующее присвоение?
  
  -- Как я понимаю в верхней строке присовение будет сделано но увижу я его тут только на следюущем такте.
if bytes_sended >= MAX_FRAME_LEN then  
	data_mode := gyro_data;
	i2c_command_buffer <= i2c_bus_1_rx_data_buffer;									
end if;

 

в верилоге я бы

bytes_sended = bytes_sended + 4; 
if (bytes_sended >= MAX_FRAME_LEN) ...

заменил бы на

if (bytes_sended >= (MAX_FRAME_LEN-4) ...
bytes_sended <= bytes_sended + 4;

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


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

20 minutes ago, Worldmaster said:

А можно какой нибудь пример с if ?? 

 

//исходные LUT8+LUT8+LUT8+R = 1.627+1.627+1.627+0.380=5.261nS - 1 такт 190МГц

always @( posedge C ) if( CE & A[3:0] & B[1:0] & Z[13:0]) Q<=X;

 

// заменить на LUT4.R->LUT4.R->LUT4.R = 0.337+0.380=0,717nS - 3 такта 1395МГц

always @( posedge C ) begin T1<=&A[3-:4];  T2<=&Z[3-:4]; T3<=&Z[7-:4]; T4<=&Z[11-:4]; T5<=B[1]&B[0]&Z[13]&Z[14]; T6<=CE; end  // LUT24 -> LUT6

always @( posedge C ) begin T7<=T1&T2&T3&T4; T8<=T5&T6; end // LUT6 -> LUT2

always @( posedge C ) if (T7&T8) Q<=X;

 

30 minutes ago, Worldmaster said:

Да тут просто дичь какая то. Как тут человеку вообще возможно разобраться?  Тут просто какое то месиво.

Вот так выглядит написанное Вами текстовое описания аппаратуры.

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


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

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

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

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

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

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

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

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

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

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