Jump to content
    

Правки задержек сигналов

Здравствуйте. Подскажите пожалуйста алгоритм правкеи вот этих проблем?

image.thumb.png.dd89461411c323f0e03f192119dcc157.png

image.thumb.png.17b8173db5adc042138e3cb2581de5a5.png

image.thumb.png.019c23dfd3b306d63faabfcf1ee16b04.png

 

 

Я так понял что нужно добавить констрейнт. 

image.thumb.png.4a0d8adae344b1ccc3d73d2656561610.png

Только мне не понятно какую линию надо брать из какого столбца?.

Тут в некоторых строках указаны вообще внутренние сигналы.

Подскажите пожалуйста как правильно это разрулить?

 

Share this post


Link to post
Share on other sites

3 hours ago, Worldmaster said:

 

Я так понял что нужно добавить констрейнт.

Только мне не понятно какую линию надо брать из какого столбца?.

Тут в некоторых строках указаны вообще внутренние сигналы.

Подскажите пожалуйста как правильно это разрулить?

 

А Ваш существующий SDC файл можете опубликовать?

Share this post


Link to post
Share on other sites

Среда вам подсказывает, что в этих путях есть переход между тактовыми доменами. В тракт сигнала необходимо добавить синхронизаторы. Когда вы, как разработчик, будете уверены, что CDC сделаны корректно, можно будет написать констрейнт set_false_path.

Если просто написать констрейнты, ничего не меняя в коде - вы только замаскируете проблему. Так лучше не делать )

Share this post


Link to post
Share on other sites

применение IP core двухклоковое фифо между SDRAM и логикой - как решение проблеми

IP core само пропишет ограничения для CDC в sdc файл

Share this post


Link to post
Share on other sites

В 03.04.2024 в 15:03, Maverick_ сказал:

применение IP core двухклоковое фифо между SDRAM и логикой - как решение проблеми

Так у меня так и есть. Данные пишутся в FIFO с одним клоком а считываются с другим. И ничего само не прописывается.

 

В 03.04.2024 в 11:28, pavlovconst сказал:

Среда вам подсказывает, что в этих путях есть переход между тактовыми доменами. В тракт сигнала необходимо добавить синхронизаторы. Когда вы, как разработчик, будете уверены, что CDC сделаны корректно, можно будет написать констрейнт set_false_path.

Если просто написать констрейнты, ничего не меняя в коде - вы только замаскируете проблему. Так лучше не делать )

А можно предметно показать что сделать? Что то мне не совсем понятно.

Как вот конкретно вот это утсранить?

2    -5.351    device_state_s0/Q    SDRAM/RAM_ROW_ADDR_req_10_s0/CE    InClock_50_net:[R]    clk_160_clockout:[R]    1.250    2.316    4.216

где device_state это применяется в основом блоке от частоты InClock_50_net и вообще никак не связан с SDRAM. Тем более с линией RAM_ROW_ADDR_req. Это тактируется от clk_160_clockout = 160 мегагерц. 

Что конкретно изменить в коде то надо?

 

 

Share this post


Link to post
Share on other sites

17 часов назад, Worldmaster сказал:

Конечно

А где констрейны input_delay output_delay?

Не знаток говинов, но 600 MHz на вход и 160MHz на выход - это допустимо?

Share this post


Link to post
Share on other sites

В 03.04.2024 в 16:29, Freibier сказал:

А где констрейны input_delay output_delay?

Так я и прошу чтобы показали где и что надо записать то?

 

В 03.04.2024 в 16:29, Freibier сказал:

Не знаток говинов, но 600 MHz на вход и 160MHz на выход - это допустимо?

по мануалу вообще указано до 1200 на MIPI Lane. Мне надо 600. Я так понимаю что при сборке компилятор будет оптимизировать так чтобы добрать до этой частоты?

Share this post


Link to post
Share on other sites

1 час назад, Worldmaster сказал:

от частоты InClock_50_net и вообще никак не связан с SDRAM

а может нужен set_clock_groups?

объявить частоты эксклюзивными, и тогда все обмены данными между клоковыми доменами на совести разработчика.

Share this post


Link to post
Share on other sites

В 03.04.2024 в 17:51, Freibier сказал:

а может нужен set_clock_groups?

А какие последствия?

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

Вот например:

Видим ошибку

image.thumb.png.b245bdfb5960915a5614148ec59cfcfc.png

 

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

 -- в конце цикла приемки проверим что там пришло
cmd_chk_proc: process (InClock_50, FFT_OE_N)   
type cmd_states is (idle, send_data);
variable cmd_state: cmd_states := idle;  
variable cnt: integer := 0; 
variable ptr: integer := 0; 
begin 	
if rising_edge(InClock_50) then  
	case cmd_state is 
		when idle =>
			if i2c_dev_IsEnable = '1' and i2c_IsComplete = '1' then
				i2c_dev_IsEnable <= '0';
			end if;
		
		
			if FFT_OE_N = '1' and FFT_OE_D = '0' then
				case i2c_command_buffer(0) is 		
					when x"a1" => 
						device_state <= command_mode; 
                        -- в каждом устрйостве i2c разместить фифо двухклоковый
                        -- при получении данных фиксируем количество и переливаем их в модуль i2c
                        -- затем запускаем обработку
                        -- таким образом мы можм мередать для обработки любое количество байт подряд
						-- второй байт определяет номер шины i2c для отправки команды. 
						-- гироскоп
						i2c_mode <= i2c_command_buffer(1)(1 downto 0);			 
						i2c_dev_Device_addr <= i2c_command_buffer(I2C_DEV_ADDR_BIT)(6 downto 0);
						i2c_dev_Reg_addr_HI <= i2c_command_buffer(I2C_REG_ADDR_HI);
						i2c_dev_Reg_addr_LOW <= i2c_command_buffer(I2C_REG_ADDR_LOW);
						i2c_dev_Reg_addr_16 <= i2c_command_buffer(I2C_REG_ADDR16_BIT)(0);
						i2c_dev_DataCount <= i2c_command_buffer(I2C_BYTES_COUNT_BIT);
						i2c_dev_Reg_RW <= i2c_command_buffer(I2C_RW_BIT)(0);										
						i2c_dev_WriteEn <= '0';
						i2c_dev_ReadEn <= '0';
						i2c_dev_IsEnable <= '0'; 
						
						i2c_dev_ResetBuffers <= '1';
						
						
						cnt := to_integer(unsigned(i2c_command_buffer(I2C_BYTES_COUNT_BIT)));  
						cmd_state := send_data;
						ptr := 0;
					when x"a2" => 
						device_state <= command_mode;
						-- команда включения или отключения отладочного светодиода
						-- включим когда будет нормальная версия
						debug_led_drive <= i2c_command_buffer(1)(0);					 
					when x"a3" =>
						device_state <= camera_mode;
						icam_index <=  i2c_command_buffer(1)(0);			
						-- команда переводит устройство в режим передачи кадров при каждом запросе на чтение
					when x"a4" =>
						LaserOut_o <= i2c_command_buffer(1)(0);                        
					when others =>		 
				end case;	
			end if;
		when send_data =>	
			if cnt > 0 then 
				i2c_dev_ResetBuffers <= '0';
				if i2c_dev_Reg_RW = WRITE then
					i2c_dev_WriteEn <= '1';
					i2c_dev_WriteData <= i2c_command_buffer(I2C_DATA_PTR_BIT + ptr);					  
				end if;
				ptr := ptr + 1;
				cnt := cnt - 1;
			else
				i2c_dev_ResetBuffers <= '1';
				i2c_dev_IsEnable <= '1';
				i2c_dev_WriteEn <= '0';
				cmd_state := idle;
			end if;
	end case;	
end if;
end process cmd_chk_proc;
 


read_fft_proc: process (USB30_in_clk, FFT_rx_flag)   
variable read_ptr: integer :=0;
variable counter: integer :=0;
variable state: fft_io_states := idle;
begin 	
if rising_edge(USB30_in_clk) then  
	if FFT_rx_flag = '0' then
		case state is 
			when idle => 
				i2c_command_buffer <= (others => (others => '0'));
				if counter >= 4 then
					state := oe_state;
				else 
					counter := counter + 1;
				end if;
			when oe_state =>
				FFT_OE_N <= '0';
				state := rd_state;
			when rd_state =>
				state := work_state;
				FFT_RD_N <= '0';
			when work_state => 
				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 
					state := nop_state;
				end if; 	
			when others =>
				FFT_RD_N <= '1';
				FFT_OE_N <= '1';
		end case;
	else 
		counter := 0;
		state := idle;
		read_ptr := 0;
		FFT_RD_N <= '1';
		FFT_OE_N <= '1';
	end if;
end if;
end process read_fft_proc;

 

Вот как конкретно тут исправить проблему?

 

Share this post


Link to post
Share on other sites

В 03.04.2024 в 18:09, Maverick_ сказал:

посмотрите

У меня не такой богатый опыт в этой штуке. Можете показать как это будет выглядеть на моем примере?? 

По какому принципу надо выставлять set_max_delay  и как определить нужные линии?

 

Вот допустим линия:

image.thumb.png.815b0ab3ce4f4bc79b2b19c9de8e7b40.png

 

Добавляю задержку. 

image.png.c64fbac4d4b93f34f5967f982bf5a925.png

 

Но какое ставить число?

 

В итоге чего бы не ставил то все равно ничего не меняется.

image.thumb.png.807c515530e027d2a8faf1f7ffeae615.png

Edited by Worldmaster

Share this post


Link to post
Share on other sites

смотрели дизайн-пример https://www.gowinsemi.com/en/support/ip_detail/4/   и    https://www.gowinsemi.com/en/support/database/2056/?

пусть даже на другой плис...

к каждой IP core среда должна генерировать файл констрейнов... во всяком случае у Intel, Xilinx так происходит...

сгенерируйте пример и посмотрите что да как

PS я с GOWIN не работал...

 

Share this post


Link to post
Share on other sites

В 03.04.2024 в 18:38, Maverick_ сказал:

смотрели дизайн-пример https://www.gowinsemi.com/en/support/ip_detail/4/       https://www.gowinsemi.com/en/support/database/2056/?

PS я с GOWIN не работал...

Да смотрел конечно. Но тут даже не в МИПИ дело.

Вот пример выше там просто буфер в одном процессе заполняется в другом обрабатывается.

Добавил синхронизирующий процесс.

process (InClock_50) 
begin 	
if rising_edge(InClock_50) then  
	i2c_command_buffer_sync <= i2c_command_buffer; 
end if;
end process;

 
 -- в конце цикла приемки проверим что там пришло
cmd_chk_proc: process (InClock_50, FFT_OE_N, FFT_OE_D, i2c_dev_IsEnable, i2c_IsComplete,  i2c_command_buffer_sync)   
type cmd_states is (idle, send_data);
variable cmd_state: cmd_states := idle;  
variable cnt: integer := 0; 
variable ptr: integer := 0; 
begin 	
if rising_edge(InClock_50) then  
	case cmd_state is 
		when idle =>
			if i2c_dev_IsEnable = '1' and i2c_IsComplete = '1' then
				i2c_dev_IsEnable <= '0';
			end if;
		
		
			if FFT_OE_N = '1' and FFT_OE_D = '0' then
				case i2c_command_buffer_sync(0) is 		
					when x"a1" => 
						device_state <= command_mode; 
                        -- в каждом устрйостве i2c разместить фифо двухклоковый
                        -- при получении данных фиксируем количество и переливаем их в модуль i2c
                        -- затем запускаем обработку
                        -- таким образом мы можм мередать для обработки любое количество байт подряд
						-- второй байт определяет номер шины i2c для отправки команды. 
						-- гироскоп
						i2c_mode <= i2c_command_buffer_sync(1)(1 downto 0);			 
						i2c_dev_Device_addr <= i2c_command_buffer_sync(I2C_DEV_ADDR_BIT)(6 downto 0);
						i2c_dev_Reg_addr_HI <= i2c_command_buffer_sync(I2C_REG_ADDR_HI);
						i2c_dev_Reg_addr_LOW <= i2c_command_buffer_sync(I2C_REG_ADDR_LOW);
						i2c_dev_Reg_addr_16 <= i2c_command_buffer_sync(I2C_REG_ADDR16_BIT)(0);
						i2c_dev_DataCount <= i2c_command_buffer_sync(I2C_BYTES_COUNT_BIT);
						i2c_dev_Reg_RW <= i2c_command_buffer_sync(I2C_RW_BIT)(0);										
						i2c_dev_WriteEn <= '0';
						i2c_dev_ReadEn <= '0';
						i2c_dev_IsEnable <= '0'; 
						
						i2c_dev_ResetBuffers <= '1';
						
						
						cnt := to_integer(unsigned(i2c_command_buffer_sync(I2C_BYTES_COUNT_BIT)));  
						cmd_state := send_data;
						ptr := 0;
					when x"a2" => 
						device_state <= command_mode;
						-- команда включения или отключения отладочного светодиода
						-- включим когда будет нормальная версия
						debug_led_drive <= i2c_command_buffer_sync(1)(0);					 
					when x"a3" =>
						device_state <= camera_mode;
						icam_index <=  i2c_command_buffer_sync(1)(0);			
						-- команда переводит устройство в режим передачи кадров при каждом запросе на чтение
					when x"a4" =>
						LaserOut_o <= i2c_command_buffer_sync(1)(0);                        
					when others =>		 
				end case;	
			end if;
		when send_data =>	
			if cnt > 0 then 
				i2c_dev_ResetBuffers <= '0';
				if i2c_dev_Reg_RW = WRITE then
					i2c_dev_WriteEn <= '1';
					i2c_dev_WriteData <= i2c_command_buffer_sync(I2C_DATA_PTR_BIT + ptr);					  
				end if;
				ptr := ptr + 1;
				cnt := cnt - 1;
			else
				i2c_dev_ResetBuffers <= '1';
				i2c_dev_IsEnable <= '1';
				i2c_dev_WriteEn <= '0';
				cmd_state := idle;
			end if;
	end case;	
end if;
end process cmd_chk_proc;
 

 

Но он все равно ругается на задержку. 

image.thumb.png.dbff57e02120dd36300fbf807f4ad8cc.png

 

 

Share this post


Link to post
Share on other sites

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

по мануалу вообще указано до 1200 на MIPI Lane. Мне надо 600. Я так понимаю что при сборке компилятор будет оптимизировать так чтобы добрать до этой частоты?

И где Вы такие частоты взяли. Что такое 600. pixel clock? Total data rate? mipi bit clock?

Должно быть четкое понятие что и на какой частоте гонит камера. И потянет ли это китайская плис.

Например full hd: 1920x1080p@60Hz, 2-line

total horizontal sample = 2200, total vertical line = 1125;

pixel clock frequency = 2200x1125x60 = 148.5 MHz

total data rate = 148.5MHz * 8bit = 1.188 Gbps

line rate (data rate per line) 1.188 Gbps/2-line = 594 Mbps

MIPI bit clock frequency = 594/2 = 297 MHz (ddr clk)

Это китаец вряд ли потянет. Надо смотреть что его pll может. И можно ли камеру на него сажать.

Получается , системная частота в районе 100МГц, не более. Вроде как.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...