olvldrozd 0 22 июля, 2014 Опубликовано 22 июля, 2014 · Жалоба Здравствуйте. Есть приемопередатчик 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-подобными, за что прошу простить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 22 июля, 2014 Опубликовано 22 июля, 2014 · Жалоба такая запись 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, почитайте.... (надо найти любое сообщение от него, и внизу есть ссылка на его сайт, а там найдете) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
olvldrozd 0 23 июля, 2014 Опубликовано 23 июля, 2014 · Жалоба Благодарю за внимание. Цикл статей уважаемого iosifik-а я видел и читал, но, видать, что-то недопонял. Вот с образом мышления пока не очень, но буду разбираться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
likeasm 0 23 июля, 2014 Опубликовано 23 июля, 2014 · Жалоба Сам сравнительно недавно сел за Verilog после C++,Assembler'ов. Поначалу голова взрывалась... Тут надо понимать, что ты не пишешь программу, а создаешь цифровую схему, у которой входы, выходы и логика. Советую начать с описания синтеза простейших конструкций, для понимания как вообще код преобразуется в цифровую схему, тогда придет понимание, что можно, а что нельзя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 23 июля, 2014 Опубликовано 23 июля, 2014 · Жалоба Есть 2 пути 1. Это представлять что вы описываете схему, и понимать какая схемная конструкция за какой строчкой кода ляжет 2. Это представлять что вы описываете поведение, и понимать какая строчка кода какую реакцию вызовет Оба имеют право на жизнь, пути похожи, но с нюансами. Самое главное что вам надо понять что все происходит одновременно, сколько текста вы не напишите все строчки произойдут в один момент. Последовательно строчка за строчкой не выполниться никогда. Единственный способ создать последовательность действий - это конечные автоматы, у которого одновременно выполняются все строчки из текущего состояния, меня состояния можно создать последовательность действий Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться