funascan 0 17 ноября, 2022 Опубликовано 17 ноября, 2022 (изменено) · Жалоба Доброго времени суток. Уже несколько недель тщетно пытаюсь побороть ULPI. Вроде бы с самим протоколом разобрался и, если я правильно понимаю, моя проблема кроется либо в описании временных ограничений(в этом я не очень силен), либо в колхозности платы(сделано все на макетке, фото приложу ниже). Проблема имеется только с отправкой данных, поэтому далее речь пойдет только о трансмиттере. Кратко опишу, как это работает. В модуле трансмиттера имеется 2 FIFO буфера. Один нужен для непосредственно данных(TXCMD в том числе), второй для количества передаваемых байт. Соответственно 1. Сначала детектируется то, что второй буфер не пуст 2. Считывается количество байт 3. Считывается первый байт 4. По сигналу NXT считываются следующие байты 5. По окончанию считывания генерируется STP 6. Из-за разности размера входной и выходной шины FIFO ненужные данные читаются в пустую FPGA использую EP4CE6E22C8(Intel), трансивер FUSB2805, пишу на SystemVerilog. Код модуля трансмиттера: Спойлер module ULPI_TX( input CLK, input DIR, input NXT, output bit STP, output bit [7:0] DATA, input OUT_FIFO_wrclk, input OUT_FIFO_wren, input [31:0] OUT_FIFO_data, output bit OUT_FIFO_wrempty, output bit [6:0] OUT_FIFO_wrusedw, input BYTES_wrclk, input BYTES_wren, input [31:0] BYTES_data ); logic [7:0] DATA_d; logic rden_trig = 0; logic rden_trig_d; logic rden_trig_edge; always_ff @(posedge CLK) rden_trig_d<=rden_trig; assign rden_trig_edge=rden_trig^rden_trig_d; logic rden; always_ff @(posedge CLK) if (rden) DATA<=DATA_d; assign rden = (NXT|rden_trig_edge); logic rdempty; ULPI_MEM_OUT mem_out ( .data(OUT_FIFO_data), .rdclk(CLK), .rdreq(rden), .wrclk(OUT_FIFO_wrclk), .wrreq(OUT_FIFO_wren), .q(DATA_d), .rdempty(rdempty), .wrempty(OUT_FIFO_wrempty), .wrusedw(OUT_FIFO_wrusedw) ); logic [31:0] BYTES_q; logic BYTES_rden; logic BUFE; //Buffer empty ULPI_MEM_OUT_bytes mem_out_b ( .data(BYTES_data), .rdclk(CLK), .rdreq(BYTES_rden), .wrclk(BYTES_wrclk), .wrreq(BYTES_wren), .q(BYTES_q), .rdempty(BUFE) ); logic [31:0] bytes_cnt; enum bit [2:0] {BUFE_detecting, BUFFER_broadcast, NOT_VALID_BYTES_flush} STAGE = BUFE_detecting; logic [1:0] minor_substages = 0; always_ff @(posedge CLK) begin if (STAGE==BUFE_detecting) begin case (minor_substages) 0: if (!BUFE) begin minor_substages<=minor_substages+1'b1; BYTES_rden<=1; end 1: begin BYTES_rden<=0; minor_substages<=minor_substages+1'b1; end 2: begin if (!DIR) begin minor_substages<=minor_substages+1'b1; rden_trig<=!rden_trig; end end 3: begin bytes_cnt<=BYTES_q-1; minor_substages<=0; STAGE<=BUFFER_broadcast; rden_trig<=!rden_trig; end endcase end if (STAGE==BUFFER_broadcast) begin if (NXT) bytes_cnt<=bytes_cnt-1; if ((bytes_cnt==0)&(NXT)) begin STP<=1; STAGE<=NOT_VALID_BYTES_flush; end end if (STAGE==NOT_VALID_BYTES_flush) begin STP<=0; if (!rdempty) rden_trig<=!rden_trig; else STAGE<=BUFE_detecting; end end endmodule Код временных ограничений: Спойлер derive_clock_uncertainty create_clock -name clk60 -period 60MHz [get_ports {ULPI_CLK}] create_clock -period 60MHz -name {virt_clk_60} set_output_delay -clock [ get_clocks {virt_clk_60} ] -max 7 [get_ports {ULPI_DATA[0] ULPI_DATA[1] ULPI_DATA[2] ULPI_DATA[3] ULPI_DATA[4] ULPI_DATA[5] ULPI_DATA[6] ULPI_DATA[7] ULPI_STP}] set_output_delay -clock [ get_clocks {virt_clk_60} ] -min -1 [get_ports {ULPI_DATA[0] ULPI_DATA[1] ULPI_DATA[2] ULPI_DATA[3] ULPI_DATA[4] ULPI_DATA[5] ULPI_DATA[6] ULPI_DATA[7] ULPI_STP}] Фото платы трансивера: Спойлер P.S. Вроде бы всё описал. Слёзно прошу помощи. Изменено 17 ноября, 2022 пользователем funascan Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 17 ноября, 2022 Опубликовано 17 ноября, 2022 · Жалоба 38 минут назад, funascan сказал: Кратко опишу, как это работает. В модуле трансмиттера имеется 2 FIFO буфера. Один нужен для непосредственно данных(TXCMD в том числе), второй для количества передаваемых байт. Система с двумя несинхронными Фифо никогда хорошо работать не будет... достаточно рассогласовать их на половину кадра и дальше вы никогда не соберёте их вместе. Гораздо проще сделать к Фифо данных дополнительных теги, то есть дополнительное поле памяти на два Бита и туда писать кодировку "начало кадра", "конец кадра ", "данных" и "ошибка данных". На приёмном конце читаете поле тега и ищете начало кадра. дальше вычитывайте данные выбрасываете ошибочные данные и делайте это до момента прихода кодировки "конца кадра". И ещё тут недавно обсуждали стиль написания текста на верилоге.. Посмотрите там даны хорошие ссылки на статьи... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
funascan 0 17 ноября, 2022 Опубликовано 17 ноября, 2022 (изменено) · Жалоба 28 минут назад, iosifk сказал: Система с двумя несинхронными Фифо никогда хорошо работать не будет... достаточно рассогласовать их на половину кадра и дальше вы никогда не соберёте их вместе. Тут я согласен, но я всегда перед записью в фифо проверяю, нет ли там чего. Да, это определенная потеря в производительности, но рассинхрона точно быть не может. 28 минут назад, iosifk сказал: Гораздо проще сделать к Фифо данных дополнительных теги, то есть дополнительное поле памяти на два Бита и туда писать кодировку "начало кадра", "конец кадра ", "данных" и "ошибка данных". На приёмном конце читаете поле тега и ищете начало кадра. дальше вычитывайте данные выбрасываете ошибочные данные и делайте это до момента прихода кодировки "конца кадра". Думал так сделать, но изначально была задумка сразу из памяти кидать данные в ulpi. Как оказалось, при этом задержка данных больше, поэтому вставил триггер после памяти. Ну и к тому же конечные точки уже под такой способ заточены, а их переписывать слишком уж муторно. А учитывая вышенаписанное может и не нужно. Изменено 17 ноября, 2022 пользователем funascan Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба как именно не работает то? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
funascan 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба 5 часов назад, des00 сказал: как именно не работает то? Энумерация то проходит, то не проходит. Если проходит, то данные не всегда передаются и конечная точка рано или поздно отключается по 3м ошибкам. На логическом анализаторе виден отправленный пакет(причем правильно отправленный) а ack пакета после него не следует. Иногда бывает, что при подключении трансивер уходит в Low power Mode. Я так понимаю, что это происходит, когда я пишу в function control, а трансивер что то не правильно принимает и пишет 0 в SuspendM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба 4 minutes ago, funascan said: На логическом анализаторе виден отправленный пакет(причем правильно отправленный) а ack пакета после него не следует. я бы вот с этого начал исследовать, с помощью анализаторов. Почему ломается протокол. Где ваш ack, после этого уже можно двигаться дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
funascan 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба 7 часов назад, des00 сказал: Где ваш ack Происходит вот это, поэтому и ack-а нет. Если я правильно понимаю, то трансивер неправильно захватывает данные, а ошибка хотя бы в одном бите - это сразу же проблема с контрольной суммой. Изменено 18 ноября, 2022 пользователем funascan Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
funascan 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба Как-то так это в signal tap выглядит Изменено 18 ноября, 2022 пользователем funascan Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться