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

Предупреждения синтеза WARNING:Xst:647

Здравствуйте.

Есть приемопередатчик SPI (исходный код взят отсюда: https://www.eewiki.net/display/LOGIC/Serial...+Master+(VHDL)), переписывать его на Verilog я не стал, вроде бы в сочетании VHDL и Verilog в одном проекте ничего страшного нет. От внешнего устройства посредством приемопередатчика я получаю 8-битные пакеты открытых данных, потом формирую из них 64-битные пакеты открытых данных и передаю криптографическому блоку на шифрование. Между приемопередатчиком и криптографическим блоком "расположен" управляющий блок, предназначенный для задания настроек приемопередатчика, управления приемопередатчиком и формирования 64-битных пакетов данных. Код ниже (код с комментариями: http://paste.org/73758).

 

`timescale 1ns / 1ps
module spi_1_control(
input [63:0] rx_plain, 		
output reg [63:0] tx_plain,
output reg enable_1,  
       input result_1,    	

output reg enable_spi_1,			
output reg cpol_spi_1, 				
output reg cpha_spi_1, 				
output reg count_spi_1, 			
output reg [31:0] clk_div_spi_1, 
output reg [31:0] addr_spi_1, 	
output reg [7:0] tx_data_spi_1, 	

input busy_spi_1, 					
input [7:0] rx_data_spi_1	 	
);

parameter count_64 = 57; 		
reg count;

always @ (rx_plain or busy_spi_1) 
	begin
		cpol_spi_1 = 1; 				
		cpha_spi_1 = 1; 				
		count_spi_1 = 0; 				
		clk_div_spi_1 = 32'b 1; 	
		addr_spi_1 = 32'b 0; 		
		enable_spi_1 = 1;

		if (busy_spi_1 == 0)
			begin
				task_transmit (tx_data_spi_1, rx_plain, count_64); 
				enable_1 = 1;
			end
		else tx_data_spi_1 = 8'b 0;
	end

always @ (rx_data_spi_1 or busy_spi_1 or result_1) 
	begin
		cpol_spi_1 = 1; 				
		cpha_spi_1 = 1; 				
		count_spi_1 = 0; 				
		clk_div_spi_1 = 32'b 1;
		addr_spi_1 = 32'b 0; 		
		enable_spi_1 = 1;

		if ((busy_spi_1 == 0) && (result_1 == 1))
			begin
				task_resive (rx_data_spi_1, tx_plain, count_64); 
			end
		else tx_plain = 64'b 0;
	end

task task_resive;

input [7:0] data_rd; 		
output reg [63:0] block_0; 
input [8:0] count_value; 	
integer count;				
begin	
@ (count_value or data_rd)
	for (count = 0; count < count_value; count = count + 8)
		begin
			case (count)
				9'd 0 : block_0 [7:0] <= data_rd; 	
				9'd 8 : block_0 [15:8] <= data_rd;  
				9'd 16 : block_0 [23:16] <= data_rd;
				9'd 24 : block_0 [31:24] <= data_rd;
				9'd 32 : block_0 [39:32] <= data_rd;
				9'd 40 : block_0 [47:40] <= data_rd;
				9'd 48 : block_0 [55:48] <= data_rd;
				9'd 56 : block_0 [63:56] <= data_rd;
				default : block_0 <= 64'b 0;
			endcase
		end

			block_0 <= 64'b 0;
			count = 9'b 0;
end
endtask

task task_transmit;

output reg [7:0] data_wr; 	
input [63:0] block_0; 		
input [8:0] count_value; 	

integer count;				
begin
@ (count_value or block_0)
	for (count = 0; count < count_value; count = count + 8)
		begin
		case (count)
			9'd 0 : data_wr = block_0 [7:0];		
			9'd 8 : data_wr = block_0 [15:8];   
			9'd 16 : data_wr = block_0 [23:16]; 
			9'd 24 : data_wr = block_0 [31:24]; 
			9'd 32 : data_wr = block_0 [39:32]; 
			9'd 40 : data_wr = block_0 [47:40]; 
			9'd 48 : data_wr = block_0 [55:48]; 
			9'd 56 : data_wr = block_0 [63:56]; 
			default : data_wr = block_0 [7:0];
		endcase
		end
			data_wr = 64'b 0;
			count = 9'b 0;
end
endtask
endmodule

 

Суть проблемы в следующем: в процессе синтеза (ISE Design Suite 14.4) получаю следующие предупреждения:

WARNING:Xst:647 - Input <rx_plain> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.

WARNING:Xst:647 - Input <rx_data_spi_1> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.

WARNING:Xst:647 - Input <result_2> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.

При этом структура проекта "разваливается". Организация процесса считывания данных через цикл также выдает ошибку, т.к. count не константа:

 

if ((busy_spi_1 == 0) && (result_1 == 1))
 for (count = 0; count > 57; count = count + 8)
   tx_plain [count + 7: count] = rx_data_spi_1;
else tx_plain = 64'b 0;

 

Это мой первый относительно большой проект на HDL-языках, до этого писал только на C/C++, поэтому некоторые конструкции могут быть C-подобными, за что прошу простить.

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


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

такая запись

 

for (count = 0; count > 57; count = count + 8)

 

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

 

Вы не понимаете самой идеологии происходящего...

 

 

 

вот такой несколько условный анализ вашего кода, немного наивный, но отражающий суть. Если я где не прав поправьте,самому интересно:)

always @ (rx_plain or busy_spi_1) 
        begin
            cpol_spi_1 = 1;                 
            cpha_spi_1 = 1;                 
            count_spi_1 = 0;                 
            clk_div_spi_1 = 32'b 1;     
            addr_spi_1 = 32'b 0;         
            enable_spi_1 = 1;

 

тут написано при любом изменении rx_plain или busy_spi_1 вам надо чтобы произошло следующее

cpol_spi_1 = 1;

cpha_spi_1 = 1;

и так далее... Но все сигналы этого блока не зависят от rx_plain или busy_spi_1, то есть другими словами это должно происходить всегда,

это равносильно как в С написать

 

if(A == 0)

B = 2;

else

B = 2;

 

 

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

 

едем дальше

if (busy_spi_1 == 0)
                begin
                    task_transmit (tx_data_spi_1, rx_plain, count_64); 
                    enable_1 = 1;
                end
            else tx_data_spi_1 = 8'b 0;

если что-то поменялось во входных сигналах и бизи стал 0, зовем приемный таск, в котором

 

первое основное что вам надо знать цикл в HDL это штука которая просто сокращает запись, то есть любой цикл всегда равносилен тому что вы просто запишите друг за другом тело цикла

 

for(i = 0;i<3;i=i+1)

a<=i;

всегда равносильно

 

a[0] <=0;

a[1] <=1;

a[2] <=2;

 

а второе что все что вы написали произойдет одновременное, то есть ваш приемный таск одновременно выполнит все строки кейза

 

9'd 0 : block_0 [7:0] <= data_rd;     
                    9'd 8 : block_0 [15:8] <= data_rd;  
                    9'd 16 : block_0 [23:16] <= data_rd;
                    9'd 24 : block_0 [31:24] <= data_rd;
                    9'd 32 : block_0 [39:32] <= data_rd;
                    9'd 40 : block_0 [47:40] <= data_rd;
                    9'd 48 : block_0 [55:48] <= data_rd;
                    9'd 56 : block_0 [63:56] <= data_rd;
                    default : block_0 <= 64'b 0;

 

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

 

 

В результате ваш сигнал rx_plain нигде не участвует, и оптимизатор его радостно выкинул о чем вам и сказал... Еще раз вся ваша беда в том что вы просто не понимаете идеологии HDL, образ мышления при написании этого кода совсем другой нежели в стандартных языках программирования. И чтобы писать надо либо повернуть сознание приняв правила игры, либо начать мыслить схемами... оба пути представлены на форуме, и второй путь разжеван в кратком курсе iosifik, почитайте.... (надо найти любое сообщение от него, и внизу есть ссылка на его сайт, а там найдете)

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


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

Благодарю за внимание. Цикл статей уважаемого iosifik-а я видел и читал, но, видать, что-то недопонял. Вот с образом мышления пока не очень, но буду разбираться.

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


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

Сам сравнительно недавно сел за Verilog после C++,Assembler'ов. Поначалу голова взрывалась... Тут надо понимать, что ты не пишешь программу, а создаешь цифровую схему, у которой входы, выходы и логика. Советую начать с описания синтеза простейших конструкций, для понимания как вообще код преобразуется в цифровую схему, тогда придет понимание, что можно, а что нельзя.

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


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

Есть 2 пути

1. Это представлять что вы описываете схему, и понимать какая схемная конструкция за какой строчкой кода ляжет

2. Это представлять что вы описываете поведение, и понимать какая строчка кода какую реакцию вызовет

 

Оба имеют право на жизнь, пути похожи, но с нюансами.

 

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

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


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

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

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

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

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

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

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

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

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

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